/* =========================================================================
   Novalux Home Services — capa de marca
   -------------------------------------------------------------------------
   Se carga DESPUES de la hoja exportada de Webflow. No reescribe reglas: solo
   reasigna las variables primitivas de las que cuelgan las miles de reglas de
   la plantilla, y anade los componentes que la plantilla original no traia
   (formularios, FAQ, galeria de proyectos, CTA flotantes y modal).
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. Paleta
   La plantilla declara los primitivos cuatro veces repartidas en dos bloques
   :root. Redefinirlos aqui, con la hoja cargada despues, gana en todos los
   casos sin tener que tocar el export.
   ------------------------------------------------------------------------- */
:root {
  --novalux--primary: #0757d8;
  --novalux--secondary: #0874f9;
  --novalux--dark: #031d4c;
  --novalux--background: #f5f8fd;
  --novalux--white: #fff;

  /* Tonos derivados, usados por los componentes nuevos */
  --novalux--dark-soft: #0a2f6b;
  --novalux--line: #d7e3f5;
  --novalux--line-strong: #bfd5f7;
  --novalux--text-muted: #5b6c85;
  --novalux--shadow: 0 1.25rem 3.5rem rgba(3, 29, 76, .1);
  --novalux--shadow-soft: 0 .5rem 1.5rem rgba(3, 29, 76, .07);
  --novalux--whatsapp: #25d366;

  /* --- Primitivos de la plantilla, reasignados --- */
  --_primitives---brand-color--primary-color: #0757d8;
  --_primitives---brand-color--secondary-color: #0874f9;
  --_primitives---brand-color--accent-color: #bfd5f7;

  --_primitives---colors--white: #fff;
  --_primitives---colors--neutral-lightest: #f5f8fd;
  --_primitives---colors--neutral-lighter: #e8effa;
  --_primitives---colors--neutral-light: #f5f8fd;
  --_primitives---colors--neutral: #5b6c85;
  --_primitives---colors--neutral-dark: #33456a;
  --_primitives---colors--neutral-darker: #0a2f6b;

  /* El "negro" de la plantilla pasa a ser el azul oscuro corporativo */
  --_primitives---opacity--neutral-darkest-100: #031d4c;
  --_primitives---opacity--neutral-darkest-88: rgba(3, 29, 76, .88);
  --_primitives---opacity--neutral-darkest-64: rgba(3, 29, 76, .64);
  --_primitives---opacity--neutral-darkest-48: rgba(3, 29, 76, .48);
  --_primitives---opacity--neutral-darkest-32: rgba(3, 29, 76, .32);
  --_primitives---opacity--neutral-darkest-16: rgba(3, 29, 76, .16);
  --_primitives---opacity--neutral-darkest-8: rgba(3, 29, 76, .08);
  --_primitives---opacity--neutral-darkest-4: rgba(3, 29, 76, .04);

  /* El crema de la plantilla pasa a ser el fondo azulado de marca */
  --_primitives---opacity--white-100: #f5f8fd;
  --_primitives---opacity--white-88: rgba(245, 248, 253, .88);
  --_primitives---opacity--white-64: rgba(245, 248, 253, .64);
  --_primitives---opacity--white-48: rgba(245, 248, 253, .48);
  --_primitives---opacity--white-32: rgba(245, 248, 253, .32);
  --_primitives---opacity--white-16: rgba(245, 248, 253, .16);
  --_primitives---opacity--white-8: rgba(245, 248, 253, .08);
  --_primitives---opacity--white-4: rgba(245, 248, 253, .04);
}

/* -------------------------------------------------------------------------
   Velo del hero
   La plantilla declara el oscurecido como background-image del contenedor,
   pero la <img> va dentro en position:absolute e inset:0, asi que lo tapa por
   completo: el velo original nunca llega a verse. Funcionaba porque la foto
   de la plantilla ya era oscura. La nuestra es una piscina a pleno sol, asi
   que el velo tiene que ir por encima de la imagen.
   ------------------------------------------------------------------------- */
.header_background-image-wrapper::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  /* Sin tinte azul: antes el velo era azul marino (rgba(3,29,76)) y tenia la
     foto entera virada a azul. Ahora es negro neutro, que oscurece sin cambiar
     el color: el cielo sigue siendo azul cielo y la piedra sigue siendo calida.

     No se quita del todo porque el titular es blanco y cae justo sobre el
     cielo despejado de la mitad izquierda; sin nada debajo no se leeria. Por
     eso el velo se concentra a la izquierda y abajo (donde hay texto) y se
     abre casi por completo a la derecha, que es donde estan los tecnicos y el
     edificio. Para aclararlo mas, bajar estos valores. */
  background-image:
    linear-gradient(180deg, rgba(0, 0, 0, .52) 0%, rgba(0, 0, 0, .18) 45%, rgba(0, 0, 0, .68) 100%),
    linear-gradient(90deg, rgba(0, 0, 0, .60) 0%, rgba(0, 0, 0, .34) 36%, rgba(0, 0, 0, 0) 72%);
}

/* -------------------------------------------------------------------------
   2. Cabecera fija que se oculta al bajar y reaparece al subir
   ------------------------------------------------------------------------- */
/* IMPORTANTE: el transform de .navbar-container lo controla GSAP/IX3 (la
   animacion de entrada lo mueve de y:-150% a 0). Aqui NO se puede tocar
   transform por dos motivos:

   1. El estilo inline de GSAP gana a cualquier clase nuestra, asi que un
      transform en CSS no llegaria a aplicarse nunca.
   2. Trasladarlo a un envoltorio tampoco sirve: un ancestro con transform pasa
      a ser el bloque contenedor de los descendientes position:fixed, y la
      barra dejaria de quedarse fija al hacer scroll.

   Por eso el ocultar-al-bajar usa margin-top y opacity, propiedades que la
   animacion de Webflow no toca. */
/* .28s y no .45s: la barra vuelve al minimo gesto de subir, y a .45s el gesto
   terminaba antes que la animacion, de modo que parecia que no respondia. */
.navbar-container {
  transition: margin-top .28s cubic-bezier(.4, 0, .2, 1),
              opacity .2s ease,
              background-color .35s ease,
              margin-left .35s ease,
              margin-right .35s ease,
              box-shadow .35s ease;
}

.navbar-container.nav-scrolled {
  margin-top: 0;
  margin-left: 0;
  margin-right: 0;
  background-color: rgba(255, 255, 255, .92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: var(--novalux--shadow-soft);
}

.navbar-container.nav-scrolled .nav_container {
  padding-top: .6rem;
  padding-bottom: .6rem;
}

/* Va despues de .nav-scrolled a proposito: las dos clases coinciden en
   especificidad y conviven (solo se oculta cuando ya hay scroll), asi que el
   orden es lo unico que decide cual gana el margin-top. */
.navbar-container.nav-hidden {
  margin-top: -9rem;
  opacity: 0;
  pointer-events: none;
}

/* .nav_container lleva fondo opaco claro en todos los estados, tambien sobre
   el hero, asi que el logotipo de la cabecera es siempre el de tinta oscura.
   La version clara se reserva para el pie y para las secciones oscuras.

   El logotipo de Novalux es un lockup casi cuadrado (247x220): a la altura
   habitual de barra la palabra "NOVALUX" quedaria ilegible, por eso la barra
   crece un poco. .nav_container ya declara height:auto, de modo que se adapta
   sin tocar el export. */
.navbar_logo {
  height: 3.75rem;
  width: auto;
}

/* .brand-logo de la plantilla solo fija la altura porque alli el logotipo era
   un SVG. El nuestro es un PNG con atributo width, que sin esto se deforma. */
.brand-logo {
  width: auto;
  max-width: 100%;
}

/* El lockup de Novalux es casi cuadrado; en el pie necesita algo mas de aire
   que el logotipo apaisado de la plantilla. */
.card-footer .brand-logo {
  height: 3.25rem;
}

/* -------------------------------------------------------------------------
   3. Botones: una sola llamada a la accion en toda la pagina
   -------------------------------------------------------------------------
   Antes convivian tres botones distintos para la misma accion (pedir
   presupuesto): el azul lleno de la cabecera, el blanco del hero
   (.is-alternate) y el pequeno de las tarjetas de servicio
   (.is-secondary.is-small.is-alternate). Ahora todos usan el mismo marcado que
   el de la cabecera:

       <a class="button is-icon w-inline-block">
         <img src="images/dot.svg" width="8" height="8" alt="">
         <div>Etiqueta</div>
       </a>

   El punto va DELANTE del texto, como en la cabecera. Los antiguos iconos de
   flecha (icon-arrow-flowfline01/02.svg) ya no se usan en estos botones; los
   ficheros se conservan por si vuelven a hacer falta.

   Los botones de WhatsApp se dejan aparte a proposito: llevan el icono de la
   marca, que es lo que dice de que canal se trata. Igualarlos al boton
   generico le quitaria esa senal al usuario. */

/* -------------------------------------------------------------------------
   4. Galeria de proyectos
   ------------------------------------------------------------------------- */
.proyectos_filtros {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .625rem;
  margin-bottom: 3.5rem;
}

.proyectos_filtro {
  padding: .625rem 1.375rem;
  border: 1px solid var(--novalux--line-strong);
  border-radius: 10rem;
  background-color: transparent;
  color: var(--novalux--dark);
  font-family: var(--_typography---font-styles--button-label);
  font-size: .9375rem;
  line-height: 1.2;
  cursor: pointer;
  transition: all .3s cubic-bezier(.445, .05, .55, .95);
}

.proyectos_filtro:hover {
  border-color: var(--novalux--primary);
  color: var(--novalux--primary);
}

.proyectos_filtro.is-activo {
  background-color: var(--novalux--primary);
  border-color: var(--novalux--primary);
  color: var(--novalux--white);
}

/* Paginacion de la galeria (6 casos por pagina). La rellena novalux.js. */
.proyectos_paginacion {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: .5rem;
  margin-top: 3rem;
}

/* display:flex de la regla anterior pisaria el ocultado nativo de [hidden]
   (una sola pagina), asi que se vuelve a ocultar de forma explicita. */
.proyectos_paginacion[hidden] {
  display: none;
}

.proyectos_pagina {
  min-width: 2.75rem;
  height: 2.75rem;
  padding: 0 .75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--novalux--line-strong);
  border-radius: .625rem;
  background-color: transparent;
  color: var(--novalux--dark);
  font-family: var(--_typography---font-styles--button-label);
  font-size: .9375rem;
  line-height: 1;
  cursor: pointer;
  transition: all .25s cubic-bezier(.445, .05, .55, .95);
}

.proyectos_pagina:hover:not(:disabled):not(.is-activo) {
  border-color: var(--novalux--primary);
  color: var(--novalux--primary);
}

.proyectos_pagina.is-activo {
  background-color: var(--novalux--primary);
  border-color: var(--novalux--primary);
  color: var(--novalux--white);
  cursor: default;
}

.proyectos_pagina:disabled {
  opacity: .4;
  cursor: default;
}

.proyectos_grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}

.proyecto_card {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: 1.25rem;
  background-color: var(--novalux--white);
  box-shadow: var(--novalux--shadow-soft);
  text-decoration: none;
  transition: transform .45s cubic-bezier(.445, .05, .55, .95),
              box-shadow .45s cubic-bezier(.445, .05, .55, .95);
}

.proyecto_card:hover {
  transform: translateY(-.375rem);
  box-shadow: var(--novalux--shadow);
}

.proyecto_card.is-oculto {
  display: none;
}

.proyecto_media {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background-color: var(--novalux--line);
}

.proyecto_media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .8s cubic-bezier(.445, .05, .55, .95);
}

.proyecto_card:hover .proyecto_media img {
  transform: scale(1.06);
}

.proyecto_etiqueta {
  position: absolute;
  top: 1rem;
  left: 1rem;
  padding: .4rem .875rem;
  border-radius: 10rem;
  background-color: rgba(3, 29, 76, .78);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: var(--novalux--white);
  font-size: .8125rem;
  letter-spacing: .02em;
  text-transform: uppercase;
}

.proyecto_contenido {
  display: flex;
  flex-direction: column;
  gap: .5rem;
  padding: 1.5rem;
  flex: 1;
}

.proyecto_titulo {
  color: var(--novalux--dark);
  font-size: 1.25rem;
  line-height: 1.25;
  font-weight: 600;
  letter-spacing: -.02em;
  margin: 0;
}

.proyecto_texto {
  color: var(--novalux--text-muted);
  font-size: .9375rem;
  line-height: 1.5;
  margin: 0;
}

/* Antes la tarjeta entera era un <a> y esto era un <span>. Con el comparador
   dentro no puede serlo (arrastrar el tirador navegaria), asi que la tarjeta
   es un <article> y el enlace es este: necesita quitarse el subrayado. */
.proyecto_cta {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  margin-top: auto;
  padding-top: 1rem;
  align-self: flex-start;
  color: var(--novalux--primary);
  font-size: .9375rem;
  font-weight: 600;
  text-decoration: none;
}

.proyecto_cta:hover {
  color: var(--novalux--dark);
}

.proyecto_cta svg {
  transition: transform .35s ease;
}

.proyecto_card:hover .proyecto_cta svg {
  transform: translateX(.25rem);
}

/* -------------------------------------------------------------------------
   5. Formularios (cualificacion y modal)
   ------------------------------------------------------------------------- */
.formulario_shell {
  display: grid;
  grid-template-columns: .85fr 1fr;
  gap: 0;
  border-radius: 1.5rem;
  overflow: hidden;
  background-color: var(--novalux--white);
  box-shadow: var(--novalux--shadow);
}

.formulario_shell {
  border: 1px solid var(--novalux--line);
}

/* La columna oscura era un plano de color liso. Un degradado en diagonal mas
   un halo suave le dan profundidad sin meter ninguna imagen. */
.formulario_aside {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 2.5rem;
  padding: 3.5rem 3rem;
  background-color: var(--novalux--dark);
  background-image:
    radial-gradient(120% 80% at 0% 0%, rgba(8, 116, 249, .38) 0%, rgba(8, 116, 249, 0) 62%),
    linear-gradient(160deg, #062a63 0%, #031d4c 58%);
  color: var(--novalux--white);
  overflow: hidden;
}

/* Aqui habia un aro decorativo (.formulario_aside::after): una circunferencia
   de 20rem asomando por la esquina inferior derecha. Al recortarla el
   overflow:hidden del aside no se leia como un circulo sino como un medio
   arco suelto, y ademas competia con la marca de agua del logotipo, que ocupa
   esa misma zona. Retirado: en la esquina se queda solo el logotipo. */

/* Marca de agua: el mismo lockup, muy grande y casi apagado, asomando por la
   esquina inferior. Va en z-index negativo para quedar por debajo del texto.
   El aside crea su propio contexto de apilado (isolation:isolate), asi que ese
   -1 no puede colarse detras del panel. */
.formulario_marca-agua {
  position: absolute;
  right: -3.5rem;
  bottom: -4.5rem;
  z-index: -1;
  width: 22rem;
  height: auto;
  opacity: .06;
  pointer-events: none;
  user-select: none;
}

/* Cabecera de marca: logotipo y bajada separados por una linea vertical fina,
   que es lo que le da el aire de papeleria corporativa. */
.formulario_marca {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding-bottom: 1.5rem;
  margin-bottom: .25rem;
  border-bottom: 1px solid rgba(245, 248, 253, .14);
  width: 100%;
}

.formulario_logo {
  height: 3.5rem;
  width: auto;
  flex: none;
}

.formulario_marca-texto {
  padding-left: 1rem;
  border-left: 1px solid rgba(245, 248, 253, .18);
  color: rgba(245, 248, 253, .72);
  font-size: .8125rem;
  line-height: 1.45;
  letter-spacing: .02em;
}

.formulario_intro {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .875rem;
}

.formulario_sello {
  display: inline-flex;
  align-items: center;
  padding: .4rem .875rem;
  border: 1px solid rgba(245, 248, 253, .26);
  border-radius: 10rem;
  color: rgba(245, 248, 253, .9);
  font-size: .75rem;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.formulario_titular {
  margin: 0;
  color: var(--novalux--white);
  font-size: 1.875rem;
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -.03em;
}

.formulario_bajada {
  margin: 0;
  color: rgba(245, 248, 253, .7);
  font-size: .9375rem;
  line-height: 1.6;
}

.formulario_ventajas {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.formulario_ventaja {
  display: flex;
  align-items: flex-start;
  gap: .75rem;
  color: rgba(245, 248, 253, .84);
  font-size: 1rem;
  line-height: 1.45;
}

.formulario_ventaja svg {
  flex: none;
  margin-top: .15rem;
}

.formulario_cuerpo {
  padding: 3.5rem 3rem;
}

.formulario_cabecera {
  margin-bottom: 2rem;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--novalux--line);
}

.formulario_cabecera-titulo {
  margin: 0 0 .25rem;
  color: var(--novalux--dark);
  font-size: 1.5rem;
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -.03em;
}

.formulario_cabecera-nota {
  margin: 0;
  color: var(--novalux--text-muted);
  font-size: .9375rem;
}

/* Boton de envio con flecha */
.form_boton--flecha {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .625rem;
  padding-top: 1.125rem;
  padding-bottom: 1.125rem;
}

.form_boton--flecha svg {
  transition: transform .35s cubic-bezier(.4, 0, .2, 1);
}

.form_boton--flecha:hover svg {
  transform: translateX(.25rem);
}

/* Nota de privacidad con candado */
.campo_nota--candado {
  display: flex;
  align-items: flex-start;
  gap: .5rem;
}

.campo_nota--candado svg {
  flex: none;
  margin-top: .1rem;
  opacity: .7;
}

.formulario_grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.25rem;
}

.campo {
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

.campo.is-ancho {
  grid-column: 1 / -1;
}

.campo_label {
  color: var(--novalux--dark);
  font-size: .875rem;
  font-weight: 600;
  letter-spacing: .01em;
}

.campo_control {
  width: 100%;
  padding: .875rem 1rem;
  border: 1px solid var(--novalux--line);
  border-radius: .75rem;
  background-color: var(--novalux--background);
  color: var(--novalux--dark);
  font-family: var(--_typography---font-styles--body);
  font-size: 1rem;
  line-height: 1.4;
  transition: border-color .3s ease, box-shadow .3s ease, background-color .3s ease;
  -webkit-appearance: none;
  appearance: none;
}

.campo_control::placeholder {
  color: #93a3ba;
}

.campo_control:focus {
  outline: none;
  border-color: var(--novalux--secondary);
  background-color: var(--novalux--white);
  box-shadow: 0 0 0 3px rgba(8, 116, 249, .16);
}

.campo_control:user-invalid {
  border-color: #d23c3c;
}

select.campo_control {
  background-image: url("../images/chevron-down.svg");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  background-size: 1rem;
  padding-right: 2.75rem;
  cursor: pointer;
}

textarea.campo_control {
  min-height: 7rem;
  resize: vertical;
}

.campo_nota {
  color: var(--novalux--text-muted);
  font-size: .8125rem;
  line-height: 1.45;
}

.formulario_pie {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin-top: 1.75rem;
}

.form_boton {
  width: 100%;
  padding: 1rem 1.5rem;
  border: 1px solid var(--novalux--primary);
  border-radius: .75rem;
  background-color: var(--novalux--primary);
  color: var(--novalux--white);
  font-family: var(--_typography---font-styles--button-label);
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  transition: all .4s cubic-bezier(.445, .05, .55, .95);
}

.form_boton:hover {
  background-color: var(--novalux--dark);
  border-color: var(--novalux--dark);
}

/* Honeypot antispam: fuera de pantalla pero no display:none, para que los
   bots que ignoran CSS lo rellenen igualmente. */
.campo_trampa {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form_mensaje {
  display: none;
  padding: 1rem 1.25rem;
  border-radius: .75rem;
  font-size: .9375rem;
  line-height: 1.5;
}

.form_mensaje.is-visible {
  display: block;
}

.form_mensaje.is-ok {
  background-color: #e8f6ed;
  border: 1px solid #b7e0c6;
  color: #1c6b3a;
}

.form_mensaje.is-error {
  background-color: #fdeaea;
  border: 1px solid #f3c2c2;
  color: #a52020;
}

/* -------------------------------------------------------------------------
   6. FAQ (acordeon accesible)
   ------------------------------------------------------------------------- */
.faq_lista {
  display: flex;
  flex-direction: column;
  gap: .75rem;
}

.faq_item {
  border: 1px solid var(--novalux--line);
  border-radius: 1rem;
  background-color: var(--novalux--white);
  overflow: hidden;
  transition: border-color .3s ease, box-shadow .3s ease;
}

.faq_item.is-abierto {
  border-color: var(--novalux--line-strong);
  box-shadow: var(--novalux--shadow-soft);
}

.faq_boton {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.5rem 1.75rem;
  border: 0;
  background-color: transparent;
  color: var(--novalux--dark);
  font-family: var(--_typography---font-styles--heading-normal);
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -.01em;
  text-align: left;
  cursor: pointer;
}

.faq_icono {
  position: relative;
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background-color: var(--novalux--background);
  transition: background-color .3s ease, transform .35s ease;
}

.faq_icono::before,
.faq_icono::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: .625rem;
  height: 2px;
  background-color: var(--novalux--primary);
  transform: translate(-50%, -50%);
  transition: transform .35s ease, opacity .25s ease;
}

.faq_icono::after {
  transform: translate(-50%, -50%) rotate(90deg);
}

.faq_item.is-abierto .faq_icono {
  background-color: var(--novalux--primary);
}

.faq_item.is-abierto .faq_icono::before,
.faq_item.is-abierto .faq_icono::after {
  background-color: var(--novalux--white);
}

.faq_item.is-abierto .faq_icono::after {
  transform: translate(-50%, -50%) rotate(0deg);
  opacity: 0;
}

.faq_panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .4s cubic-bezier(.4, 0, .2, 1);
}

.faq_item.is-abierto .faq_panel {
  grid-template-rows: 1fr;
}

.faq_panel > div {
  overflow: hidden;
}

/* El acordeon ocupa el contenedor completo, como el resto de bloques. La
   respuesta si se limita: a 1300 px de ancho la linea de texto seria
   incomoda de leer. */
.faq_respuesta {
  padding: 0 1.75rem 1.5rem;
  max-width: 60rem;
  color: var(--novalux--text-muted);
  font-size: 1rem;
  line-height: 1.6;
  margin: 0;
}

/* -------------------------------------------------------------------------
   8. Acciones flotantes y barra fija movil
   ------------------------------------------------------------------------- */
.acciones-flotantes {
  position: fixed;
  right: 1.5rem;
  bottom: 1.5rem;
  z-index: 900;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: .75rem;
}

/* Los dos botones llevan medidas fijas en vez de ajustarse al texto: con
   ancho automatico "WhatsApp" salia bastante mas corto que "Presupuesto
   gratis" y la pila quedaba escalonada. Con el mismo ancho y la misma altura
   se alinean tambien los iconos en vertical.

   El ancho esta tomado del rotulo mas largo; si algun dia se alarga mas, hay
   que subir este valor o el texto se saldra de la pastilla. */
.flotante {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  width: 14.25rem;
  height: 3.25rem;
  box-sizing: border-box;
  gap: .625rem;
  padding: 0 1.25rem;
  border: 0;
  border-radius: 10rem;
  color: var(--novalux--white);
  font-family: var(--_typography---font-styles--button-label);
  font-size: .9375rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--novalux--shadow);
  transform: translateY(1rem);
  opacity: 0;
  visibility: hidden;
  transition: transform .4s cubic-bezier(.4, 0, .2, 1),
              opacity .4s ease,
              visibility .4s ease,
              background-color .3s ease;
}

.acciones-flotantes.is-visible .flotante {
  transform: translateY(0);
  opacity: 1;
  visibility: visible;
}

.flotante.is-whatsapp {
  background-color: var(--novalux--whatsapp);
}

.flotante.is-whatsapp:hover {
  background-color: #1eb955;
}

.flotante.is-presupuesto {
  background-color: var(--novalux--primary);
}

.flotante.is-presupuesto:hover {
  background-color: var(--novalux--dark);
}

/* Los dos SVG venian a 22 y a 20 px. Igualados aqui para que los iconos
   queden del mismo tamano y en la misma vertical en los dos botones. */
.flotante svg {
  flex: none;
  width: 21px;
  height: 21px;
}

/* Barra fija inferior, solo movil */
.barra-movil {
  display: none;
}

/* -------------------------------------------------------------------------
   Boton de menu (hamburguesa) en azul
   -------------------------------------------------------------------------
   La plantilla pinta la pastilla del boton con el "secondary-color", que en
   movil vuelve a ser el amarillo #ffc228: la plantilla lo reasigna en un
   bloque "body { ... }" dentro de las media queries, y ese valor gana al azul
   que el rebranding fija en ":root" (body esta mas cerca del elemento en la
   herencia). En vez de pelear con la variable, se fija aqui el color directo:
   pastilla azul de marca y trazos blancos para que contrasten. */
.menu-icons {
  background-color: var(--novalux--primary);
}

.menu-icons_line-top,
.menu-icons_line-bottom,
.menu-icons_line-middle,
.menu-icon_line-middle-inner {
  background-color: var(--novalux--white);
}

@media screen and (max-width: 767px) {
  /* Las acciones flotantes se retiran en movil: el CTA de presupuesto y el de
     WhatsApp han pasado a la barra fija inferior, asi que las pastillas
     flotantes solo duplicarian esos mismos botones justo encima de la barra. */
  .acciones-flotantes {
    display: none;
  }

  /* Dos acciones en una sola fila: Presupuesto ocupa el ancho libre (1fr) y
     WhatsApp queda como un boton pequeno cuadrado (auto) solo con el icono. */
  .barra-movil {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 950;
    display: grid;
    grid-template-columns: 1fr auto;
    gap: .5rem;
    padding: .5rem .75rem calc(.5rem + env(safe-area-inset-bottom));
    background-color: rgba(255, 255, 255, .96);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border-top: 1px solid var(--novalux--line);
  }

  .barra-movil_boton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    padding: .75rem .75rem;
    border: 1px solid var(--novalux--primary);
    border-radius: .75rem;
    background-color: var(--novalux--primary);
    color: var(--novalux--white);
    font-family: var(--_typography---font-styles--button-label);
    font-size: .9rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
  }

  /* WhatsApp: boton pequeno cuadrado, solo icono (se oculta su texto). */
  .barra-movil_boton.is-whatsapp {
    width: 3.25rem;
    padding: 0;
    background-color: var(--novalux--whatsapp);
    border-color: var(--novalux--whatsapp);
  }

  .barra-movil_boton.is-whatsapp .barra-movil_texto {
    display: none;
  }

  /* Una sola fila: basta con reservar el alto de un boton al final de la pagina. */
  body {
    padding-bottom: 4.75rem;
  }
}

/* -------------------------------------------------------------------------
   9. Modal de presupuesto
   ------------------------------------------------------------------------- */
.modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background-color: rgba(3, 29, 76, .55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  visibility: hidden;
  transition: opacity .35s ease, visibility .35s ease;
}

.modal.is-abierto {
  opacity: 1;
  visibility: visible;
}

.modal_dialogo {
  position: relative;
  width: 100%;
  max-width: 34rem;
  max-height: calc(100vh - 3rem);
  overflow-y: auto;
  padding: 2.75rem;
  border-radius: 1.5rem;
  background-color: var(--novalux--white);
  box-shadow: var(--novalux--shadow);
  transform: translateY(1.5rem) scale(.98);
  transition: transform .4s cubic-bezier(.4, 0, .2, 1);
}

.modal.is-abierto .modal_dialogo {
  transform: translateY(0) scale(1);
}

.modal_cerrar {
  position: absolute;
  top: 1.25rem;
  right: 1.25rem;
  width: 2.25rem;
  height: 2.25rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background-color: var(--novalux--background);
  color: var(--novalux--dark);
  cursor: pointer;
  transition: background-color .3s ease;
}

.modal_cerrar:hover {
  background-color: var(--novalux--line-strong);
}

.modal_titulo {
  color: var(--novalux--dark);
  font-size: 1.75rem;
  line-height: 1.2;
  letter-spacing: -.03em;
  margin: 0 0 .5rem;
}

.modal_texto {
  color: var(--novalux--text-muted);
  font-size: 1rem;
  line-height: 1.55;
  margin: 0 0 1.75rem;
}

/* -------------------------------------------------------------------------
   10. Detalles de contacto reutilizables
   ------------------------------------------------------------------------- */
.contacto_lista {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.contacto_item {
  display: inline-flex;
  align-items: center;
  gap: .75rem;
  color: inherit;
  text-decoration: none;
  font-size: 1.0625rem;
  transition: opacity .3s ease;
}

.contacto_item:hover {
  opacity: .75;
}

.contacto_item svg {
  flex: none;
}

/* -------------------------------------------------------------------------
   11. Adaptacion a los puntos de ruptura de Webflow
   ------------------------------------------------------------------------- */
@media screen and (max-width: 991px) {
  .proyectos_grid {
    grid-template-columns: repeat(2, 1fr);
  }


  .formulario_shell {
    grid-template-columns: 1fr;
  }

  .formulario_aside,
  .formulario_cuerpo {
    padding: 2.5rem 2rem;
  }

  .navbar_logo {
    height: 2.25rem;
  }
}

@media screen and (max-width: 767px) {
  .proyectos_grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 1rem;
  }

  .proyecto_contenido {
    padding: 1.125rem;
  }

  .proyecto_titulo {
    font-size: 1.0625rem;
  }

  .modal_dialogo {
    padding: 2rem 1.5rem;
  }
}

@media screen and (max-width: 479px) {
  .proyectos_grid {
    grid-template-columns: 1fr;
  }


  .formulario_grid {
    grid-template-columns: 1fr;
  }

  .formulario_aside,
  .formulario_cuerpo {
    padding: 2rem 1.25rem;
  }

  /* A 479 px el logotipo y la bajada uno al lado del otro dejan la bajada en
     dos palabras por linea. Se apilan y se retira la linea vertical, que ahi
     ya no separa nada. */
  .formulario_marca {
    flex-direction: column;
    align-items: flex-start;
    gap: .75rem;
  }

  .formulario_marca-texto {
    padding-left: 0;
    border-left: 0;
  }

  .formulario_marca-agua {
    width: 15rem;
  }

  .proyectos_filtros {
    gap: .5rem;
    margin-bottom: 2.5rem;
  }

  .proyectos_filtro {
    padding: .5rem 1rem;
    font-size: .875rem;
  }
}

/* -------------------------------------------------------------------------
   12. Correccion del desbordamiento horizontal en movil
   -------------------------------------------------------------------------
   .heading-style-h0 esta fijado en 5.375rem sin ninguna media query, asi que
   en un movil de 390 px el titular se sale de la pantalla. Ocurre igual en la
   plantilla original ("Professional" queda cortado), pero aqui el texto es
   mas largo ("Mantenimiento integral de comunidades") y el corte es mayor.

   Se corrige SOLO por debajo de 991 px: en escritorio la composicion sigue
   siendo identica a la plantilla.
   ------------------------------------------------------------------------- */
/* OJO: aqui habia "overflow-x: hidden" sobre html y body. Tapaba el
   desbordamiento lateral, pero rompia la seccion de servicios: un ancestro con
   overflow distinto de visible se convierte en el contenedor de scroll, y
   entonces las tarjetas position:sticky se pegan a EL en vez de al viewport.
   El "top: 10%" pasaba a resolverse contra los 15147 px del documento (1514 px)
   en lugar de contra los 813 px de la ventana (81 px), asi que el umbral caia
   siempre por debajo de la pantalla y las tarjetas no llegaban a apilarse
   nunca.

   Se ha quitado porque ya no hace falta: las causas reales del desbordamiento
   (las tarjetas a 70vw, el ancho fijo de .tag-licenses y el titular
   .heading-style-h0) estan corregidas mas abajo y en sus propios bloques.
   Si vuelve a aparecer scroll horizontal, hay que buscar el elemento culpable,
   NO reponer este overflow. */
html,
body {
  max-width: 100%;
}

/* Ultimo resto de aquel desbordamiento, ya sin taparlo: las columnas del pie
   son tracks "1fr", y un track 1fr no baja de su contenido porque su minimo
   implicito es auto. Enlaces como "WhatsApp +34 643 434 695" o
   "Impermeabilizacion y fachadas" ensanchaban la columna y sacaban el pie
   4 px fuera de la pantalla a 360 px. */
.footer_menu-wrapper > .footer_link-column {
  min-width: 0;
}

.menu-footer {
  overflow-wrap: break-word;
}

/* Mismo motivo en las tarjetas de servicios: el envoltorio de la imagen es un
   item de rejilla y su minimo automatico sale del tamano intrinseco de la
   foto (720 px), asi que a 320 px se salia 25 px. */
.layout_card > * {
  min-width: 0;
}

/* Y la rejilla exterior del pie pedia un track de 385 px como minimo absoluto.
   Por debajo de 479 px la plantilla ya lo pasa a 1fr, pero entre 480 y ~510 px
   no cabia. Se quita el suelo rigido y se conserva la intencion. */
@media screen and (max-width: 991px) {
  .menu-footer_wrapper {
    grid-template-columns: minmax(0, max-content);
  }
}

/* El hero tiene el mismo problema y aparece al subir el margen lateral a 90 px:
   .grid-bottom-hero es "1fr + minmax(385px, min-content)", y entre 992 y
   1200 px la tarjeta destacada (que solo se oculta a partir de 991 px) ya no
   cabe junto al titular. Se deja que ambos tracks puedan encogerse. */
@media screen and (max-width: 1200px) {
  .grid-bottom-hero {
    grid-template-columns: minmax(0, 1fr) minmax(0, 385px);
  }

  .grid-bottom-hero > * {
    min-width: 0;
  }

  .heading-style-h0 {
    font-size: clamp(2.5rem, 6.5vw, 5.375rem);
    overflow-wrap: break-word;
  }
}

@media screen and (max-width: 991px) {
  /* --- Titular del hero -------------------------------------------------
     Los dos titulares ("Mantenimiento" en <h1> y "integral de comunidades" en
     <div>) llevan las clases .heading-style-h0.text-weight-normal (el segundo
     ademas .text-color-soft-white, que en la plantilla solo cambia el color,
     nunca el tamano). El texto real es mas largo que el de la plantilla y la
     palabra mas larga ("Mantenimiento") no cabia en moviles estrechos, asi que
     se partia por la mitad ("Mantenimient / o").

     El tamano lo fija .heading-style-h0.text-weight-normal (especificidad
     0,2,0): base 5.375rem y, solo por debajo de 479 px, 3.5rem. El clamp
     anterior estaba escrito sobre .heading-style-h0 (0,1,0), que PIERDE frente
     a esa regla, por eso no hacia nada en el movil.

     Se replica el mismo selector 0,2,0 (este archivo carga despues => gana por
     orden) con un tamano fluido que ademas suaviza el salto brusco de la
     plantilla (86 px hasta 480 px y de golpe 56 px por debajo). Cada palabra
     cabe entera desde ~320 px en adelante. Afecta a ambos titulares por igual,
     que es como se ven en la plantilla. */
  .heading-style-h0.text-weight-normal {
    font-size: clamp(2.2rem, 11.5vw, 5.375rem);
  }

  /* Red de seguridad: si en algun ancho una palabra aun no cupiera, que parta
     antes de provocar scroll horizontal (mal menor). No deberia activarse. */
  .heading-style-h0 {
    overflow-wrap: break-word;
  }

  /* --- Foto del hero en movil ------------------------------------------
     Con object-fit:cover y object-position por defecto (centro), el recorte
     vertical del movil se comia el lado derecho, que es justo donde estan los
     dos tecnicos con la camiseta de Novalux (solo se veia la espalda de uno en
     el borde). Se desplaza el encuadre a la derecha para que se vean ambos. En
     escritorio la foto entra casi entera, por eso solo se toca aqui. */
  .header_background-image {
    object-position: 80% center;
  }

  /* El lockup ocupa demasiado ancho junto al boton en pantallas estrechas */
  .navbar_logo {
    height: 2.75rem;
  }

  .nav_container {
    max-width: 100%;
  }
}

@media screen and (max-width: 767px) {
  .navbar-container {
    margin-left: 3%;
    margin-right: 3%;
  }

  /* En movil el CTA de presupuesto se retira de la cabecera y pasa a la barra
     fija inferior (.barra-movil). La cabecera queda con el logotipo y el boton
     de menu, sin apreturas. El enlace sigue en el DOM para escritorio/tablet. */
  .nav_button-wrapper .button.is-icon {
    display: none;
  }
}

@media screen and (max-width: 479px) {
  .navbar_logo {
    height: 2.25rem;
  }

  /* En pantallas muy estrechas el boton de la barra se abrevia: la version
     larga sigue disponible para lectores de pantalla. */
  .nav_button-wrapper .button.is-icon .nav-cta-largo {
    display: none;
  }

  .nav_button-wrapper .button.is-icon img {
    display: none;
  }

  .header_content {
    min-height: 100svh;
  }
}

/* -------------------------------------------------------------------------
   13. Rejilla comun: margenes laterales y alineacion de bloques
   -------------------------------------------------------------------------
   La plantilla no tenia una medida unica de margen lateral, y por eso los
   bloques no cuadraban entre si. Convivian tres sistemas distintos:

     a) .padding-global      -> 3% del ancho de ventana
     b) .layout_card (servicios) -> 70vw, sin relacion con el contenedor

   Medido a 1440 px, el borde izquierdo quedaba en 48 px en casi todas las
   secciones y en 216 px en las tarjetas de servicios: 168 px de desvio. Solo
   cuadraba por casualidad a 1920 px exactos, que es donde se diseno la
   plantilla.

   A partir de aqui hay UNA sola medida, --novalux--gutter, de la que dependen
   todas las secciones. Para cambiar los margenes laterales del sitio basta con
   tocar ese valor.
   ------------------------------------------------------------------------- */
:root {
  --novalux--gutter: 90px;
}

/* 90 px en escritorio y tablet. Por debajo se reduce: en un movil de 360 px
   dejaria solo 180 px de contenido. */
@media screen and (max-width: 991px) {
  :root { --novalux--gutter: 2.5rem; }
}

@media screen and (max-width: 767px) {
  :root { --novalux--gutter: 1.5rem; }
}

@media screen and (max-width: 479px) {
  :root { --novalux--gutter: 1.25rem; }
}

.padding-global {
  padding-left: var(--novalux--gutter);
  padding-right: var(--novalux--gutter);
}

/* El margen lateral ya valia 90 px, pero no se veia: .container-large corta el
   contenido en 84rem (1344 px) y lo centra, asi que en cuanto la ventana pasa
   de 1524 px el hueco lateral lo decide el centrado, no el padding. A 1710 px,
   por ejemplo, quedaban 183 px por lado en vez de 90.

   Al quitar el tope, el ancho pasa a depender solo del margen: 90 px por lado
   en cualquier pantalla.

   OJO en monitores muy anchos: a 2560 px el contenido pasa a medir 2380 px y
   las lineas de texto se hacen largas de leer. Si molesta, la solucion es
   devolver aqui un max-width alto (p. ej. 1800px) en vez del 84rem original. */
.container-large {
  max-width: none;
}

/* -------------------------------------------------------------------------
   Separacion vertical entre bloques: 100 px
   -------------------------------------------------------------------------
   Cada seccion aporta la mitad por arriba y la mitad por abajo, de modo que
   entre dos bloques consecutivos se ven 100 px justos (antes eran 224: la
   plantilla ponia 7rem = 112 px a cada lado).

   Si lo que se queria era 100 px POR LADO (y por tanto 200 px de hueco entre
   bloques), basta con poner 100px en esta unica linea. */
.padding-section-large {
  padding-top: 50px;
  padding-bottom: 50px;
}

/* El titular de servicios es el mas largo y caia en tres lineas. Con algo mas
   de ancho entra en dos, y "balance" las reparte parejas en vez de dejar una
   linea larga y otra corta. */
.titular-ancho {
  max-width: 68rem;
}

.titular-ancho h2 {
  text-wrap: balance;
}

/* Tarjetas de servicios al ancho del contenedor
   ---------------------------------------------
   La plantilla las deja en 70vw, que no tiene relacion con .container-large y
   dejaba la seccion mas estrecha que las demas.

   Nota: en su momento se atribuyo esto al "top: 10%" de la tarjeta, pero era
   falso. El culpable de que el apilado se rompiera era el "overflow-x: hidden"
   de html/body (ver el bloque 12): mientras estuvo puesto, el porcentaje se
   resolvia contra la altura del documento. Quitado aquel overflow, "top: 10%"
   se resuelve contra la ventana (81 px) y no depende del ancho de la tarjeta,
   asi que ensancharla no afecta al apilado. */
.layout_card {
  width: 100%;
}

/* Al ensanchar la tarjeta el texto ocupa menos alto, y el space-between de la
   plantilla dejaba un hueco enorme entre el parrafo y el boton (el alto lo
   marca la foto, no el texto). Se agrupa todo junto y se centra en vertical:
   con flex-start quedaria pegado arriba y con un vacio aun mayor debajo. */
.layout_card-content {
  justify-content: center;
  /* Blanco puro. La plantilla usaba opacity--white-100, que en esta paleta es
     #f5f8fd (un blanco con un punto de azul). Sobre el fondo #F5F5F6 de la
     seccion apenas se distinguia; en blanco la tarjeta se separa del fondo. */
  background-color: #ffffff;
}

/* Por debajo de 767 px la plantilla fija el alto del contenido en 20rem. Con
   nuestros textos, mas largos que los suyos, el parrafo no cabia y la tarjeta
   (overflow:hidden) lo recortaba: hasta 71 px perdidos a 320 px de ancho. Ya
   pasaba antes de centrar el contenido, pero centrado se corta por arriba y
   por abajo a la vez, asi que se ve mas. El alto pasa a ser un minimo. */
@media screen and (max-width: 767px) {
  .layout_card-content {
    height: auto;
    min-height: 20rem;
  }

  /* En movil la tarjeta se apila en una sola columna (grid-template-columns:1fr
     de la plantilla), asi que la imagen ya queda arriba y el texto debajo. La
     foto es vertical (720x900) y ocupaba demasiado alto; se recorta a un
     apaisado suave con object-fit para acortarla sin deformarla. */
  .layout_image {
    aspect-ratio: 4 / 3;
    height: auto;
  }

  /* Orden imagen -> texto igual en TODAS las tarjetas.
     La plantilla monta un zigzag en escritorio y, para el apilado movil,
     mandaba la imagen al final ("order: 9999") en las tarjetas 2, 4 y 6
     mediante tres #w-node-... concretos. Al reescribir la seccion con los
     ocho servicios nuevos esos identificadores desaparecieron del HTML, asi
     que la regla de la plantilla ya no encuentra a nadie y sobra el antiguo
     "order: 0" que la anulaba. Se deja este recordatorio: si alguna vez se
     vuelven a pegar nodos de Webflow con esos ids, la foto de esas tarjetas
     saltara al final en movil. */

  /* Boton de la tarjeta a todo el ancho */
  .layout_card .button-group {
    width: 100%;
  }

  .layout_card .button-group .button {
    width: 100%;
    justify-content: center;
  }
}

/* -------------------------------------------------------------------------
   14. Distintivo del hero en una sola linea
   -------------------------------------------------------------------------
   .tag-licenses venia con width:16.5rem fijo. Descontando el relleno y la
   pastilla de "Barcelona" quedaban ~145 px para "Empresa con contrato y
   garantia", que se partia en tres lineas. Con el ancho ajustado al contenido
   la frase entra de una vez.
   ------------------------------------------------------------------------- */
/* fit-content, no auto: .tag-licenses es un contenedor flex a nivel de bloque,
   asi que con width:auto la pastilla blanca se estiraria a todo el ancho de la
   columna (832 px) en lugar de ajustarse a su texto. */
.tag-licenses {
  width: fit-content;
  max-width: 100%;
}

.tag-licenses > .text-style-tagline {
  white-space: nowrap;
}

/* El distintivo va SIEMPRE en una sola linea y centrado en la columna, tambien
   en moviles estrechos. A 1rem no cabe junto a la pastilla "Barcelona", asi que
   por debajo de 767 px se reduce el cuerpo de forma fluida (y se aprieta la
   pastilla) para que "Barcelona / Empresa con contrato y garantia" entre de una
   vez en vez de partirse en tres lineas. */
@media screen and (max-width: 767px) {
  .tag-licenses {
    margin-left: auto;
    margin-right: auto;
    flex-wrap: nowrap;
  }

  .tag-licenses > .text-style-tagline {
    white-space: nowrap;
  }

  /* Especificidad 0,4,0 para ganar a la regla de la plantilla
     .text-style-tagline.text-color-black.text-style-allcaps (0,3,0), que fija
     el cuerpo del rotulo. */
  .tag-licenses .text-style-tagline.text-color-black.text-style-allcaps {
    font-size: clamp(.5rem, 2.6vw, .78rem);
    letter-spacing: .01em;
  }

  .left-liceses {
    padding: 3px 6px;
  }
}

/* -------------------------------------------------------------------------
   15. Comparador antes / despues de la galeria de casos
   -------------------------------------------------------------------------
   Las dos fotos se superponen y la de "antes" se recorta con clip-path segun
   la variable --pos, que mueve el <input type="range">. Se usa un range de
   verdad, y no solo eventos de raton, para que el comparador funcione con
   teclado y con lector de pantalla sin logica extra.

   Sin JavaScript el conjunto sigue siendo utilizable: --pos vale 50% desde el
   atributo style en linea, asi que se ven las dos mitades.
   ------------------------------------------------------------------------- */
.comparador {
  position: relative;
  isolation: isolate;
  touch-action: pan-y;
}

.comparador_img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* La capa "antes" se recorta por la derecha hasta la posicion del tirador */
.comparador_capa {
  position: absolute;
  inset: 0;
  overflow: hidden;
  clip-path: inset(0 calc(100% - var(--pos)) 0 0);
}

.comparador_capa .comparador_img {
  position: absolute;
  inset: 0;
}

.comparador_linea {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--pos);
  width: 2px;
  margin-left: -1px;
  background-color: var(--novalux--white);
  box-shadow: 0 0 0 1px rgba(3, 29, 76, .22);
  pointer-events: none;
  z-index: 2;
}

/* Tirador circular dibujado sobre la propia linea */
.comparador_linea::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 2.5rem;
  height: 2.5rem;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background-color: var(--novalux--white);
  box-shadow: var(--novalux--shadow-soft);
  background-image:
    linear-gradient(90deg, var(--novalux--primary) 0 2px, transparent 2px),
    linear-gradient(90deg, var(--novalux--primary) 0 2px, transparent 2px);
  background-size: 2px .75rem, 2px .75rem;
  background-position: calc(50% - 4px) center, calc(50% + 4px) center;
  background-repeat: no-repeat;
}

/* El range va invisible por encima de todo y es quien recibe el arrastre */
.comparador_rango {
  position: absolute;
  inset: 0;
  z-index: 3;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  opacity: 0;
  cursor: ew-resize;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
}

/* El pulgar ocupa toda la altura para poder agarrarlo en cualquier punto */
.comparador_rango::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 2.5rem;
  height: 20rem;
  cursor: ew-resize;
}

.comparador_rango::-moz-range-thumb {
  width: 2.5rem;
  height: 20rem;
  border: 0;
  border-radius: 0;
  cursor: ew-resize;
}

.comparador_rango:focus-visible {
  outline: none;
}

/* El foco se pinta sobre la linea, que si es visible */
.comparador_rango:focus-visible ~ .comparador_linea::after {
  outline: .1875rem solid var(--novalux--secondary);
  outline-offset: .1875rem;
}

.comparador_marca {
  position: absolute;
  bottom: 1rem;
  z-index: 2;
  padding: .3rem .7rem;
  border-radius: 10rem;
  background-color: rgba(3, 29, 76, .72);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: var(--novalux--white);
  font-size: .75rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  pointer-events: none;
  transition: opacity .25s ease;
}

.comparador_marca.is-antes   { left: 1rem; }
.comparador_marca.is-despues { right: 1rem; }

/* Cada etiqueta se desvanece cuando su mitad casi ha desaparecido.
   Las clases las pone iniciarComparadores() en novalux.js. */
.comparador.is-solo-despues .comparador_marca.is-antes,
.comparador.is-solo-antes .comparador_marca.is-despues {
  opacity: 0;
}

/* La etiqueta de categoria comparte esquina con el tirador: se sube arriba */
.comparador .proyecto_etiqueta {
  z-index: 2;
}

/* El zoom al pasar el raton descuadraria las dos capas del comparador */
.proyecto_card:hover .comparador .comparador_img {
  transform: none;
}

/* -------------------------------------------------------------------------
   19. Bloque de cierre (segunda solicitud)
   -------------------------------------------------------------------------
   Antes era una tarjeta blanca con tres campos en fila: cumplia, pero como
   ultimo empujon antes del pie resultaba plano. Ahora es un panel oscuro con
   una foto de obra terminada de fondo, el argumento a la izquierda y el
   formulario en una tarjeta blanca a la derecha, que es donde cae la vista.

   Reutiliza los componentes que ya existen (.campo, .campo_control,
   .form_boton, .form_mensaje) y el mismo manejador de envio: el <form>
   conserva data-novalux-form y los data-etiqueta.
   ------------------------------------------------------------------------- */
.cierre {
  position: relative;
  isolation: isolate;
  border-radius: 1.5rem;
  overflow: hidden;
  background-color: var(--novalux--dark);
}

.cierre_foto {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* La foto es muy clara: sin este velo el texto blanco no tendria contraste */
.cierre_velo {
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image:
    linear-gradient(105deg, rgba(3, 29, 76, .96) 0%, rgba(3, 29, 76, .88) 42%, rgba(3, 29, 76, .58) 100%);
}

.cierre_grid {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  gap: 3.5rem;
  align-items: center;
  padding: 3.5rem;
}

.cierre_texto {
  min-width: 0;
}

.cierre_titulo {
  margin: 0 0 1rem;
  letter-spacing: -.03em;
}

.cierre_entrada {
  color: rgba(245, 248, 253, .78);
  font-size: 1.0625rem;
  line-height: 1.6;
  margin: 0 0 2rem;
}

.cierre_puntos {
  display: flex;
  flex-direction: column;
  gap: 1.125rem;
  margin: 0 0 2rem;
  padding: 0;
  list-style: none;
}

.cierre_punto {
  display: flex;
  align-items: flex-start;
  gap: .75rem;
}

.cierre_punto svg {
  flex: none;
  margin-top: .15rem;
}

.cierre_punto-titulo {
  display: block;
  color: var(--novalux--white);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.35;
}

.cierre_punto-texto {
  display: block;
  color: rgba(245, 248, 253, .66);
  font-size: .9375rem;
  line-height: 1.5;
  margin-top: .15rem;
}

.cierre_directo {
  display: flex;
  flex-direction: column;
  gap: .75rem;
  padding-top: 1.75rem;
  border-top: 1px solid rgba(245, 248, 253, .16);
}

.cierre_directo-label {
  color: rgba(245, 248, 253, .58);
  font-size: .8125rem;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.cierre_directo-enlaces {
  display: flex;
  flex-wrap: wrap;
  gap: .625rem;
}

.cierre_enlace {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .625rem 1.125rem;
  border: 1px solid rgba(245, 248, 253, .24);
  border-radius: 10rem;
  color: var(--novalux--white);
  font-size: .9375rem;
  font-weight: 600;
  text-decoration: none;
  transition: background-color .3s ease, border-color .3s ease;
}

.cierre_enlace:hover {
  background-color: rgba(245, 248, 253, .1);
  border-color: rgba(245, 248, 253, .42);
}

/* --- Tarjeta del formulario --- */
.cierre_form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 2.25rem;
  border-radius: 1.25rem;
  background-color: var(--novalux--white);
  box-shadow: 0 1.5rem 4rem rgba(0, 0, 0, .28);
}

.cierre_form-cabecera {
  display: flex;
  flex-direction: column;
  gap: .25rem;
  margin-bottom: .25rem;
}

.cierre_form-titulo {
  color: var(--novalux--dark);
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -.02em;
}

.cierre_form-nota {
  color: var(--novalux--text-muted);
  font-size: .9375rem;
}

.cierre_form .form_boton {
  margin-top: .25rem;
}

.cierre_form .campo_nota,
.cierre_form .form_mensaje {
  margin: 0;
}

.enlace-texto {
  color: var(--novalux--primary);
  text-decoration: underline;
  text-underline-offset: .15em;
}

@media screen and (max-width: 991px) {
  .cierre_grid {
    grid-template-columns: 1fr;
    gap: 2.5rem;
    padding: 2.5rem;
  }
}

@media screen and (max-width: 767px) {
  .cierre_grid {
    padding: 2rem 1.5rem;
  }

  .cierre_form {
    padding: 1.75rem 1.25rem;
  }
}

@media screen and (max-width: 479px) {
  .cierre_grid {
    padding: 1.75rem 1.125rem;
  }

  .cierre_enlace {
    width: 100%;
    justify-content: center;
  }
}

/* -------------------------------------------------------------------------
   18. Opiniones: carrusel con flechas y paginacion
   -------------------------------------------------------------------------
   El desplazamiento lo hace el propio navegador con scroll-snap; el JS solo
   mueve el scroll y marca el punto activo. Asi el carrusel sigue siendo
   utilizable con el dedo, con la rueda y con teclado aunque el script falle,
   y no hay ninguna animacion que mantener sincronizada a mano.
   ------------------------------------------------------------------------- */
.resenas {
  position: relative;
}

/* Sin margenes negativos ni padding lateral a proposito: el viewport coincide
   exactamente con el contenedor, igual que el resto de bloques. Ademas, con
   padding el scroll en reposo no vale 0 (el snap lo deja en 22 px), y eso
   descuadraba tanto el calculo del indice como el bloqueo de las flechas. */
.resenas_viewport {
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.resenas_viewport::-webkit-scrollbar {
  display: none;
}

.resenas_pista {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc((100% - 3rem) / 2.5);
  gap: 1.5rem;
  align-items: stretch;
  padding-block: .5rem;
}

.resena {
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  padding: 2.5rem;
  border: 1px solid var(--novalux--line);
  border-radius: 1.25rem;
  background-color: var(--novalux--white);
  box-shadow: var(--novalux--shadow-soft);
}

.resena_comillas {
  fill: var(--novalux--line-strong);
  flex: none;
}

.resena_estrellas {
  display: flex;
  gap: .1875rem;
  color: #f4b400;   /* amarillo de las estrellas de Google */
}

.resena_estrellas svg {
  fill: currentColor;
}

.resena_texto {
  flex: 1;
  color: var(--novalux--dark);
  font-size: 1.125rem;
  line-height: 1.6;
  margin: 0;
}

.resena_cabecera {
  display: flex;
  align-items: center;
  gap: .875rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--novalux--line);
}

.resena_avatar {
  flex: none;
  width: 3rem;
  height: 3rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background-color: var(--novalux--primary);
  color: var(--novalux--white);
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1;
}

.resena_quien {
  display: flex;
  flex-direction: column;
  gap: .125rem;
  min-width: 0;
}

.resena_autor {
  color: var(--novalux--dark);
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.3;
}

.resena_meta {
  color: var(--novalux--text-muted);
  font-size: .875rem;
  line-height: 1.3;
}

/* --- Flechas y paginacion --- */
.resenas_controles {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  margin-top: 2.5rem;
}

.resenas_flecha {
  flex: none;
  width: 3rem;
  height: 3rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--novalux--line-strong);
  border-radius: 50%;
  background-color: var(--novalux--white);
  color: var(--novalux--primary);
  cursor: pointer;
  transition: background-color .3s ease, border-color .3s ease, color .3s ease;
}

.resenas_flecha:hover:not(:disabled) {
  background-color: var(--novalux--primary);
  border-color: var(--novalux--primary);
  color: var(--novalux--white);
}

/* Al llegar a un extremo la flecha se desactiva en vez de desaparecer, para
   que la fila de controles no se mueva. */
.resenas_flecha:disabled {
  opacity: .35;
  cursor: default;
}

/* El contador va en cifras tabulares para que la fila de controles no se
   desplace un pixel cada vez que cambia el numero. */
.resenas_contador {
  margin: 0;
  min-width: 3.25rem;
  text-align: center;
  color: var(--novalux--text-muted);
  font-size: .875rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: .04em;
}

.resenas_puntos {
  display: flex;
  align-items: center;
  gap: .5rem;
}

/* El viewport recibe el foco (tabindex="0"), asi que necesita un anillo
   visible; sin esto el foco entra en la region y no se ve donde esta. */
.resenas_viewport:focus-visible {
  outline: .125rem solid var(--novalux--primary);
  outline-offset: .5rem;
  border-radius: 1.25rem;
}

.resenas_punto {
  width: .5rem;
  height: .5rem;
  padding: 0;
  border: 0;
  border-radius: 10rem;
  background-color: var(--novalux--line-strong);
  cursor: pointer;
  transition: width .35s cubic-bezier(.4, 0, .2, 1), background-color .3s ease;
}

.resenas_punto.is-activo {
  width: 1.75rem;
  background-color: var(--novalux--primary);
}

@media screen and (max-width: 991px) {
  .resenas_pista {
    grid-auto-columns: calc((100% - 1.5rem) / 1.6);
  }

  .resena {
    padding: 2rem;
  }
}

@media screen and (max-width: 600px) {
  .resenas_pista {
    grid-auto-columns: 88%;
  }

  .resena {
    padding: 1.75rem;
  }

  .resena_texto {
    font-size: 1.0625rem;
  }
}

/* -------------------------------------------------------------------------
   17. Bloque de ventajas: de baraja apilada a rejilla
   -------------------------------------------------------------------------
   La plantilla presenta estas tarjetas como una baraja: todas en
   position:sticky, con el "top" escalonado de dos en dos por ciento y una
   rotacion de hasta 6 grados. Con las cuatro tarjetas cortas del original
   funciona. Con nuestras ocho, y con textos de tres o cuatro lineas, no:

     - El escalon entre tarjetas es 2% de la altura de ventana, unos 18 px.
       Como la tarjeta mide 304 px, de cada una solo asomaban 18 px: ni el
       titulo ni el icono llegaban a verse.
     - La rotacion desplaza las esquinas mucho mas que eso: 38 px a 3 grados y
       76 px a 6 grados sobre una tarjeta de 725 px de ancho. O sea que el giro
       movia las cosas entre dos y cuatro veces mas que el escalon que debia
       ordenarlas, y por los bordes asomaban trozos de texto sueltos en
       diagonal.

   El efecto solo se sostiene con tres o cuatro tarjetas breves. Con ocho, lo
   legible es una rejilla: dos columnas, altura segun contenido y las ocho
   ventajas visibles a la vez. Se conserva la columna izquierda pegajosa, que
   es lo que le daba caracter al bloque.

   Si algun dia se vuelve a querer la baraja, hay que bajar a 3-4 tarjetas y
   subir el escalon a la altura de la cabecera de la tarjeta (unos 4rem), no
   dejarlo en 18 px.
   ------------------------------------------------------------------------- */
.layout_content-right {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.5rem;
}

/* Se anulan las cuatro propiedades que montaban la baraja. Van listadas las
   ocho variantes porque content-item-1 repite en su propia regla las mismas
   declaraciones que .layout_content-item, y con solo la clase base no se
   ganaria en especificidad. */
.layout_content-item,
.layout_content-item.content-item-1,
.layout_content-item.content-item-2,
.layout_content-item.content-item-3,
.layout_content-item.content-item-4,
.layout_content-item.content-item-5,
.layout_content-item.content-item-6,
.layout_content-item.content-item-7,
.layout_content-item.content-item-8 {
  position: static;
  top: auto;
  transform: none;
  height: auto;
  min-height: 0;
  margin-bottom: 0;
}

/* Sin align-items en la rejilla, las tarjetas se estiran a la altura de su
   fila, de modo que cada pareja queda pareja aunque los textos sean de
   distinto largo.

   El contenido se alinea arriba: con space-between (lo que traia la plantilla)
   y altura fija el icono y el texto se separaban a los extremos, pero ahora la
   altura la marca la fila y esa separacion abriria huecos distintos en cada
   tarjeta. El aire entre icono, titulo y parrafo lo siguen poniendo las clases
   margin-* que ya lleva el marcado, asi que aqui no se anade gap. */
.layout_content-item {
  justify-content: flex-start;
}

/* Tarjetas con un azulado suave.

   Venian en neutral-light (#f5f8fd), que es exactamente el mismo tono que el
   fondo de la seccion: apiladas y solapadas solo se distinguian por la sombra.
   Este #e4ecfb queda entre ese neutro y el accent (#bfd5f7): se lee como azul
   claro pero sigue siendo un fondo, no una banda de color.

   Se gana ademas contraste con las pastillas blancas de los iconos, que sobre
   el fondo casi blanco de antes se notaban poco. */
#ventajas .layout_content-item {
  background-color: #ffffff;
}

/* Iconos en blanco (solo en este bloque).

   Los SVG de este bloque son los *-blanco.svg: pastilla blanca y trazo azul,
   al reves que los icon-flowline0*.svg originales, que siguen en uso en las
   demas secciones sobre fondos oscuros. Se cambio el fichero en vez de
   recolorearlos por CSS porque son <img>, y a un SVG enlazado asi no le llega
   ni "fill" ni "currentColor" desde fuera.

   La tarjeta es neutral-light, no blanco puro, asi que la pastilla ya se
   distingue; el aro y la sombra solo le dan relieve para que no parezca un
   hueco recortado en la tarjeta. */
#ventajas .layout353_icon-wrapper {
  display: inline-flex;
  border-radius: 1rem;
  box-shadow: 0 0 0 1px rgba(3, 29, 76, .06),
              0 .375rem 1rem rgba(3, 29, 76, .08);
}

#ventajas .layout353_icon-wrapper .icon-1x1-medium {
  display: block;
  border-radius: 1rem;
}

/* Dos columnas de tarjetas dentro de media pagina se quedan demasiado
   estrechas en cuanto baja el ancho: a 991 px la columna derecha ronda los
   300 px, y ahi un titulo como "Especialistas en piscinas" ya parte en tres
   lineas. A partir de ese punto, una sola columna. */
@media screen and (max-width: 991px) {
  .layout_content-right {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* -------------------------------------------------------------------------
   Ventajas: baraja de tarjetas al hacer scroll (solo movil)
   -------------------------------------------------------------------------
   En escritorio y tablet las ocho ventajas van en rejilla plana (mas arriba se
   anulo el position:sticky de la plantilla). En movil se recupera el efecto de
   baraja: cada tarjeta se queda pegajosa a una altura un poco mayor que la
   anterior, de modo que al bajar se apilan y se solapan por el borde superior.
   Es puro CSS (position:sticky), sin JavaScript ni animaciones, asi que no hay
   nada que desactivar bajo prefers-reduced-motion.

   Las ocho variantes .content-item-N se listan porque la plantilla repite en
   cada una las mismas declaraciones que en la clase base; con #ventajas por
   delante se gana la especificidad necesaria para pisar el position:static que
   dejamos puesto en el bloque de escritorio. */
@media screen and (max-width: 767px) {
  #ventajas .layout_content-right {
    /* Sin hueco de rejilla: el desface del apilado ya separa las tarjetas y un
       gap aqui solo alargaria el recorrido del efecto. */
    gap: 0;
  }

  #ventajas .layout_content-item,
  #ventajas .layout_content-item.content-item-1,
  #ventajas .layout_content-item.content-item-2,
  #ventajas .layout_content-item.content-item-3,
  #ventajas .layout_content-item.content-item-4,
  #ventajas .layout_content-item.content-item-5,
  #ventajas .layout_content-item.content-item-6,
  #ventajas .layout_content-item.content-item-7,
  #ventajas .layout_content-item.content-item-8 {
    position: sticky;
    min-height: 12.5rem;
    margin-bottom: 1rem;
    /* Sombra algo mas marcada para que el borde de cada tarjeta se lea sobre la
       que queda debajo. */
    box-shadow: 0 -.25rem 1.25rem rgba(3, 29, 76, .12),
                0 .5rem 1.5rem rgba(3, 29, 76, .10);
  }

  /* Escalon de 0.75rem por tarjeta: deja asomar una franja de la anterior. El
     top base (5rem) reserva sitio para la cabecera fija cuando reaparece al
     subir. */
  #ventajas .layout_content-item.content-item-1 { top: 5rem; }
  #ventajas .layout_content-item.content-item-2 { top: 5.75rem; }
  #ventajas .layout_content-item.content-item-3 { top: 6.5rem; }
  #ventajas .layout_content-item.content-item-4 { top: 7.25rem; }
  #ventajas .layout_content-item.content-item-5 { top: 8rem; }
  #ventajas .layout_content-item.content-item-6 { top: 8.75rem; }
  #ventajas .layout_content-item.content-item-7 { top: 9.5rem; }
  #ventajas .layout_content-item.content-item-8 { top: 10.25rem; }
}

/* Respeta la preferencia del sistema de reducir el movimiento */
@media (prefers-reduced-motion: reduce) {
  .navbar-container,
  .proyecto_card,
  .proyecto_media img,
  .flotante,
  .modal,
  .modal_dialogo,
  .faq_panel {
    transition-duration: .01ms !important;
  }

  /* El carrusel salta a la opinion siguiente en vez de deslizarse */
  .resenas_viewport {
    scroll-behavior: auto;
  }
}

/* -------------------------------------------------------------------------
   19. Pie de pagina a todo el ancho
   -------------------------------------------------------------------------
   La plantilla monta el pie como una tarjeta oscura redondeada, metida hacia
   dentro por los margenes de pagina y flotando sobre una franja del color de
   acento, que asomaba por los cuatro lados. Aqui se quiere el bloque oscuro
   pegado a los bordes de la pantalla.

   Se hace moviendo el hueco de sitio, no quitandolo: se anulan los margenes
   exteriores (.padding-global) y el redondeo, y ese mismo hueco pasa a ser
   padding DENTRO del bloque oscuro. Asi el texto del pie sigue alineado con
   el del resto de la pagina, que es lo que hace que no parezca descolocado.
   ------------------------------------------------------------------------- */
.footer .padding-global {
  padding-left: 0;
  padding-right: 0;
}

/* La franja de acento que quedaba por encima de la tarjeta ya no pinta nada:
   con el bloque a todo el ancho se veria como una linea de color suelta entre
   la ultima seccion y el pie. */
.footer .spacer-xlarge {
  padding-top: 0;
}

.footer_top-wrapper {
  border-radius: 0;
  padding: 4rem var(--novalux--gutter);
}

/* El acento seguia siendo el fondo del <footer>. Ya no se ve por ningun lado
   (el bloque oscuro lo tapa entero), pero se iguala al oscuro para que un
   rebote de scroll al final de la pagina no descubra una franja azul. */
.footer.position-relative {
  background-color: var(--_primitives---colors--neutral-darkest);
}

/* La regla de arriba no lleva media query, asi que pisa tambien los ajustes
   moviles de la plantilla (2rem a 767 px, 1.5rem a 479 px). Se rehacen aqui:
   el hueco lateral lo sigue marcando --novalux--gutter, que ya encoge solo por
   breakpoint, y lo unico que baja es el aire de arriba y abajo. */
@media screen and (max-width: 767px) {
  /* Pie mas compacto en movil: menos aire arriba y abajo del bloque oscuro y
     menos hueco entre las columnas de enlaces y los bloques legales. */
  .footer_top-wrapper {
    padding: 2rem var(--novalux--gutter);
  }

  /* La plantilla reparte los bloques del pie con space-between; en movil, con
     la altura ajustada al contenido, eso deja separaciones irregulares. Con un
     gap fijo y flex-start quedan parejas y mas ajustadas. */
  .right-footer {
    justify-content: flex-start;
    gap: 1.5rem;
  }

  /* El envoltorio exterior valia "minmax(0, max-content)" (regla de los 991 px):
     al ser max-content se estiraba al ancho natural de las tres columnas, y por
     debajo de 480 px, donde la plantilla las quiere en dos columnas, la rejilla
     interior no tenia un ancho definido contra el que repartirse y se salia de
     la pantalla. Con "minmax(0, 1fr)" el envoltorio ocupa el ancho disponible y
     las columnas (3 hasta 480 px, 2 por debajo) se reparten sin desbordar. */
  .menu-footer_wrapper {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Enlaces en dos columnas (Menú | Servicios) y la de Contacto a todo el
     ancho debajo: asi el dato mas largo, "WhatsApp +34 643 434 695", entra en
     una sola linea en vez de partirse el numero en dos. */
  .footer_menu-wrapper {
    grid-template-columns: 1fr 1fr;
    grid-row-gap: 1.25rem;
  }

  .footer_link-column:last-child {
    grid-column: 1 / -1;
  }

  /* Solo la columna de contacto va sin cortes: sus datos (número, correo) no
     deben partirse. Las otras columnas sí pueden envolver títulos largos. */
  .footer_link-column:last-child .menu-footer {
    white-space: nowrap;
  }

  .bottom-wrapper {
    grid-row-gap: 1rem;
  }
}

@media screen and (max-width: 479px) {
  .footer_top-wrapper {
    padding: 1.75rem var(--novalux--gutter);
  }
}

/* La foto del pie es apaisada (1386x1135) dentro de una tarjeta vertical, de
   modo que cover se come cerca del 43% del ancho. Anclada a la derecha entran
   el edificio y el olivo; por defecto (centrada) el recorte se quedaba en
   cielo. El logotipo que la foto trae impreso en su esquina superior izquierda
   cae fuera de ese recorte, asi que no se duplica con el .brand-logo que la
   tarjeta ya superpone encima. */
.card-footer .footer-image {
  object-position: 78% center;
}

/* -------------------------------------------------------------------------
   20. Linea legal del pie en un solo renglon
   -------------------------------------------------------------------------
   La plantilla apila el aviso de copyright y los enlaces legales
   (.footer-legal en flex-direction:column). Van en la misma linea: el
   copyright a la izquierda y los enlaces a la derecha.

   Hacen falta las dos reglas. Con solo cambiar la direccion no basta, porque
   .wrapper-legal lleva width:100% de cuando era una fila apilada: en una fila
   se comeria todo el ancho y empujaria los enlaces al renglon siguiente, que
   es justo lo que se quiere evitar.

   Se conserva flex-wrap:wrap para que en pantallas estrechas vuelvan a
   apilarse en vez de desbordar. */
.footer-legal {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  column-gap: 1.5rem;
  row-gap: .5rem;
}

.footer-legal .wrapper-legal {
  width: auto;
  flex: 0 1 auto;
}

/* -------------------------------------------------------------------------
   21. Un unico fondo plano en todo el sitio
   -------------------------------------------------------------------------
   Aqui vivia toda la maquinaria del degradado azul: .background-liner iba de
   accent (#bfd5f7) a neutral-lightest, y como eso dibujaba una raya dura
   contra la seccion anterior, hacia falta ademas una banda de fundido
   (#proyectos::after) que subiese por detras de las tarjetas para disimular
   el salto.

   Nada de eso hace falta ya: si todas las secciones valen el mismo color, no
   hay limite que disimular. Se retiran el degradado, la banda y el
   position:relative que la sostenia.

   Quedan fuera a proposito dos fondos que no son "fondo de seccion":
     - el hero, que es una fotografia con su velo,
     - el pie y el panel oscuro del formulario, que son bloques de color.
   Sus degradados son funcionales (legibilidad del texto encima), no decorado.

   El grano es el mismo de #presupuesto, ahora en todas las secciones para que
   el papel sea uno solo de arriba abajo. No altera el color: medido, 1.58 de
   desviacion tipica sobre 255. Para dejarlo liso del todo, se borra la linea
   del data URI.
   ------------------------------------------------------------------------- */
.section,
.section.background-liner {
  background-color: #F5F5F6;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)' opacity='0.028'/%3E%3C/svg%3E");
}

/* -------------------------------------------------------------------------
   22. Ultimo resto del amarillo de la plantilla
   -------------------------------------------------------------------------
   .left-liceses es la pastilla "Barcelona" del hero. La plantilla le puso el
   amarillo a pelo (#ffc228) en vez de a traves de
   --_primitives---brand-color--secondary-color, asi que el rebranding, que
   solo reasigno la variable, no llego hasta aqui y la pastilla se quedo
   amarilla dentro de una paleta ya toda azul.

   Se usa el azul PRIMARIO (#0757d8) y no el secundario (#0874f9): el rotulo
   va en 0.65-0.675rem, o sea texto pequeno, que necesita 4.5:1. Sobre el
   secundario el blanco se queda en 4.31:1 y no llega; sobre el primario sube a
   6.24:1.

   El texto hay que forzarlo aparte porque el marcado lleva .text-color-black,
   que sobre el azul quedaria practicamente ilegible. */
.left-liceses {
  background-color: var(--_primitives---brand-color--primary-color);
}

.left-liceses .text-style-tagline.text-color-black {
  color: var(--novalux--white);
}

/* -------------------------------------------------------------------------
   23. La llamada a la accion del hero siempre visible
   -------------------------------------------------------------------------
   Los botones del hero se quedaban invisibles de forma permanente. Medido con
   el navegador: al cargar tenian visibility:visible y estaban dentro de la
   pantalla (top 724 px con ventana de 900), pero con opacity:0; despues de
   hacer scroll por la pagina pasaban a opacity:1.

   O sea que no era ni el velo, ni el z-index, ni el
   visibility:hidden del <head>, sino la animacion de aparicion que el runtime
   de Webflow aplica a [fade-in-animation]: pone opacity:0 y la sube al entrar
   el elemento en pantalla. El hero ya esta en pantalla al cargar, no hay
   scroll, el disparador no llega nunca y el boton no aparece jamas. Los demas
   botones no lo sufren porque para verlos hay que bajar.

   Arreglado quitando el atributo del marcado (ver el comentario en el hero).
   Esta regla es la red de seguridad por si alguien lo vuelve a poner al copiar
   otro boton: el !important gana al style="opacity:0" que escribe el runtime,
   porque una declaracion !important de hoja de estilos vence a una inline
   normal. Solo el hero, que es lo que esta encima del pliegue.
   ------------------------------------------------------------------------- */
#hero .button-group,
#hero .button-group > a {
  opacity: 1 !important;
  visibility: visible !important;
}

/* -------------------------------------------------------------------------
   24. Tarjeta de proyecto destacado del hero: colores invertidos
   -------------------------------------------------------------------------
   Estaban al reves de lo que se queria: la tarjeta llevaba el azul claro
   (accent) y la pastilla "VER PROYECTOS" el casi blanco (neutral-lightest).
   Ahora la tarjeta es blanca y la pastilla azul claro.

   El texto de la pastilla (#1c2623, de la plantilla) sobre el accent da
   10.4:1, de sobra pese a ser de 10 px.

   El borde no es decorativo: el accent sobre blanco solo contrasta 1.49:1, por
   debajo del 3:1 que se pide para distinguir un control de su fondo. Sin el,
   la pastilla se difumina en la tarjeta y deja de leerse como boton.
   ------------------------------------------------------------------------- */
.featured-project {
  background-color: var(--_primitives---colors--white);
}

.featured-project .button-style {
  background-color: var(--_primitives---brand-color--accent-color);
  border: 1px solid rgba(7, 87, 216, .22);
}

/* -------------------------------------------------------------------------
   25. Filete superior del bloque de presupuesto
   -------------------------------------------------------------------------
   El fondo de esta seccion ya no se declara aqui: lo pone la regla 21, que
   pinta el mismo #F5F5F6 en todas. Queda solo el filete que se pidio.

   Sobre esta base clara es matematicamente imperceptible: blanco al 5% sobre
   #F5F5F6 da un contraste de 1.02:1. Se deja porque no molesta; si lo que se
   busca es una linea de separacion visible, tiene que ser oscura, no blanca.

   La banda de fundido que bajaba desde #proyectos se ha retirado con el resto
   de degradados: con todas las secciones del mismo color no hay ningun limite
   que disimular.
   ------------------------------------------------------------------------- */
#presupuesto {
  border-top: 1px solid rgba(255, 255, 255, .05);
}

/* =========================================================================
   26. Ajustes de movil pedidos por el cliente (hero centrado, titulares mas
       pequenos, tarjetas de proyectos apiladas al hacer scroll y nota del
       formulario justificada)
   ========================================================================= */

/* --- 1. Cabecera del hero centrada -------------------------------------- */
@media screen and (max-width: 767px) {
  .grid-bottom-hero .max-width-large {
    text-align: center;
  }

  /* El distintivo es flex a nivel de bloque: se centra con margenes auto
     (ya declarados en la seccion 14); aqui se centran los botones. */
  .grid-bottom-hero .max-width-large .button-group {
    justify-content: center;
  }
}

/* --- 2. Titulares de seccion mas pequenos en movil ---------------------- */
/* Mismos selectores 0,2,0 que la plantilla (este archivo carga despues) para
   poder rebajar el tamano. Se cap­an al valor de la plantilla y encogen de
   forma fluida en pantallas estrechas. */
@media screen and (max-width: 767px) {
  .heading-style-h1.text-weight-normal {
    font-size: clamp(1.6rem, 7vw, 2.5rem);
  }

  .heading-style-h2.text-weight-normal {
    font-size: clamp(1.5rem, 6.2vw, 2.25rem);
  }

  .heading-style-h3.text-weight-normal {
    font-size: clamp(1.3rem, 5.2vw, 2rem);
  }
}

/* --- 3. Galeria "Nuestros proyectos": apilado al hacer scroll ----------- */
/* En movil las tarjetas pasan a una sola columna y se vuelven sticky: cada
   una se queda pegada arriba y la siguiente sube por encima, de modo que se
   superponen una sobre otra al desplazarse. Las ocultas por filtro/paginacion
   siguen con display:none y no estorban. */
@media screen and (max-width: 767px) {
  .proyectos_grid {
    display: block;
  }

  .proyecto_card {
    position: sticky;
    top: 4.5rem;
    margin-bottom: 1.25rem;
  }

  .proyecto_card:last-child {
    margin-bottom: 0;
  }
}

/* --- 4. Nota de privacidad del formulario estirada a lo ancho ----------- */
/* El texto se justifica para que ocupe todo el ancho de la columna (antes
   quedaba en bandera, con el borde derecho irregular). */
.campo_nota--candado span {
  flex: 1;
  text-align: justify;
  text-align-last: left;
  hyphens: auto;
}

/* =========================================================================
   27. Titular del hero a dos ofertas
   -------------------------------------------------------------------------
   El hero pasa de un solo reclamo corto ("Mantenimiento integral de
   comunidades", 3 renglones a 86 px) a las dos lineas de negocio, en
   mayusculas y separadas por un filete azul:

     MANTENIMIENTO INTEGRAL              <- blanco, <h1>
     PARA COMUNIDADES DE PROPIETARIOS
     ---                                 <- filete azul
     REHABILITACIONES Y REFORMAS         <- gris, [heading="strategy"]
     PARA PARTICULARES

   El texto es mucho mas largo, asi que los 5.375 rem de la plantilla ya no
   caben: el renglon mas ancho ("PARA COMUNIDADES DE PROPIETARIOS") mide unos
   18,5 em en Switzer en caja alta y la columna del hero solo da 832 px en
   escritorio (el resto lo ocupa la tarjeta de proyecto destacado). De ahi el
   tope de 2.75rem, que deja el renglon en ~800 px con holgura.

   El tamano se mide contra la COLUMNA (cqw) y no contra la ventana (vw). Con
   vw no hay una sola pendiente que valga: entre 992 y 1300 px la tarjeta
   destacada sigue ocupando sus 385 px, asi que la columna crece mucho mas
   despacio que la ventana y el titular se partia en tres renglones justo en
   esa franja. Al declarar la columna como contenedor, 5.2cqw da ~31 px a
   1200 px y ~44 px a partir de 1440, y el reclamo se mantiene en dos renglones
   en todo el recorrido. Se deja el clamp en vw delante como respaldo para
   navegadores sin unidades de contenedor.

   Los tamanos van en un selector 0,2,0 igual que los de la plantilla y sus
   correcciones de las secciones 12 y 26: la especificidad empata y gana este
   por orden, porque el bloque esta al final del archivo. Si se mueve mas
   arriba, vuelven a mandar los 5.375 rem.
   ========================================================================= */
.grid-bottom-hero .max-width-large {
  container-type: inline-size;
}

.heading-style-h0.hero_titular {
  text-transform: uppercase;
  font-size: clamp(1.55rem, 3.15vw, 2.75rem);
  font-size: clamp(1.55rem, 5.2cqw, 2.75rem);
  /* La plantilla aprieta a -.04em, que en caja baja y a 86 px funciona pero en
     mayusculas cierra demasiado los contraformas. Se afloja y se abre algo el
     interlineado, que a 1 dejaba las dos lineas pegadas. */
  letter-spacing: -.01em;
  line-height: 1.1;
  text-wrap: balance;
}

/* Entre 992 y 1199 px la tarjeta de proyecto destacado seguia reservando sus
   385 px y dejaba la columna del titular en unos 480 px: el reclamo caia al
   minimo legible y aun asi se partia en tres renglones, con un salto brusco
   respecto a los 43 px que recuperaba en cuanto la tarjeta desaparecia a
   991 px. Se adelanta su ocultacion a 1199 px (ya estaba oculta en tablet y
   movil por .hide-tablet, que aqui no se toca porque tambien la usa el pie) y
   se colapsa la rejilla a una columna: un track "minmax(0, 385px)" vacio
   seguiria ocupando sus 385 px, porque el maximo es una longitud definida y no
   depende del contenido. */
@media screen and (max-width: 1199px) {
  .grid-bottom-hero .testimonial-wrapper {
    display: none;
  }

  .grid-bottom-hero {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Filete azul entre las dos ofertas. Va como elemento propio y no como
   border-bottom del <h1> porque el <h1> ocupa todo el ancho de la columna y el
   filete es corto; ademas asi no lo arrastran las animaciones de entrada del
   titular. */
.hero_titular-filete {
  width: 6.5rem;
  height: .3rem;
  margin: 1.5rem 0 2rem;
  background-color: var(--_primitives---brand-color--primary-color);
  border-radius: 2px;
}

/* En movil el bloque del hero esta centrado (seccion 26), y el filete es un
   div a nivel de bloque: se centra con margenes automaticos. */
@media screen and (max-width: 767px) {
  .grid-bottom-hero .max-width-large .hero_titular-filete {
    margin-left: auto;
    margin-right: auto;
  }

  .hero_titular-filete {
    margin-top: 1.25rem;
    margin-bottom: 1.5rem;
  }
}

/* Respaldo para navegadores sin unidades de contenedor: por debajo de 991 px
   desaparece la tarjeta destacada y el titular dispone de todo el ancho, asi
   que ahi el vw si acompana a la columna y puede subir del 3.15vw de
   escritorio. Donde cqw funciona, esta regla queda anulada por la declaracion
   posterior de arriba. El minimo de 1.5rem mantiene los renglones legibles a
   320 px, donde el texto se pliega solo en mas lineas. */
@media screen and (max-width: 991px) {
  .heading-style-h0.hero_titular {
    font-size: clamp(1.5rem, 4.8vw, 2.75rem);
    font-size: clamp(1.5rem, 5.2cqw, 2.75rem);
  }
}

/* =========================================================================
   28. Bloque de servicios: sello de marca y lista de garantias
   -------------------------------------------------------------------------
   Las ocho tarjetas de #servicios llevan el logotipo en la esquina superior
   derecha. Va en position:absolute por dos motivos:

     1. .layout_card es una rejilla de dos pistas (.85fr / 1fr). Un hijo mas
        en flujo normal se colocaria como tercera celda y partiria la tarjeta;
        un hijo absoluto no participa en el reparto de pistas.
     2. La tarjeta ya es position:sticky, asi que sirve de bloque contenedor
        y no hace falta anadirle position:relative.

   El sello se apoya sobre una pastilla blanca porque en escritorio cae encima
   del panel de texto (blanco) pero por debajo de 767 px la tarjeta se apila y
   la esquina pasa a estar sobre la fotografia: sin fondo, el logotipo azul
   marino se perderia contra las fotos oscuras (parking, escalera).
   ========================================================================= */
.servicio_sello {
  position: absolute;
  z-index: 2;
  top: 1rem;
  right: 1rem;
  width: auto;
  height: 2.5rem;
  padding: .4rem .6rem;
  border-radius: .625rem;
  background-color: var(--novalux--white);
  box-shadow: var(--novalux--shadow-soft);
  pointer-events: none;
}

/* .layout_card recorta con overflow:hidden y esquinas redondeadas; 1rem de
   separacion basta para que la pastilla no toque el radio. En movil la tarjeta
   es mas estrecha y el sello baja de tamano para no comerse la foto. */
@media screen and (max-width: 767px) {
  /* IMPRESCINDIBLE: por debajo de 767 px la plantilla apaga el apilado y deja
     la tarjeta en "position: static". Sin posicion, deja de ser bloque
     contenedor y el sello se anclaba al primer ancestro posicionado que
     encontrase, a miles de pixeles de su tarjeta (se veia suelto en mitad de
     otra seccion). "relative" sin desplazamientos no altera nada del apilado
     movil, solo devuelve la referencia. */
  .layout_card {
    position: relative;
  }

  .servicio_sello {
    top: .75rem;
    right: .75rem;
    height: 2.125rem;
  }
}

/* Lista de garantias del mantenimiento de piscinas: es la unica tarjeta que
   trae puntos ademas del parrafo. La marca de verificacion se pinta con un
   ::before y no con un caracter en el HTML para que los lectores de pantalla
   no lean "marca de verificacion" cinco veces. */
.servicio_lista {
  margin: 1rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: .5rem;
}

.servicio_lista li {
  position: relative;
  padding-left: 1.5rem;
  color: var(--novalux--text-muted);
  font-size: 1rem;
  line-height: 1.4;
}

.servicio_lista li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .35em;
  width: .75rem;
  height: .45rem;
  border-left: 2px solid var(--novalux--primary);
  border-bottom: 2px solid var(--novalux--primary);
  transform: rotate(-45deg);
}

/* =========================================================================
   29. Banda de marca de "Reformas y rehabilitaciones"
   -------------------------------------------------------------------------
   Rotulo a sangre que abre la galeria de proyectos: fondo blanco, logotipo y
   titular centrados como un unico grupo, y un filete azul de borde a borde
   que separa la banda del resto de la seccion.

   El titular se escribe en caja baja en el HTML y se pasa a mayusculas por
   CSS: asi los lectores de pantalla lo leen como palabras y no deletreado,
   igual que se hizo con el reclamo del hero (seccion 27).
   ========================================================================= */
.proyectos_marca {
  background-color: var(--novalux--white);
  border-bottom: 2px solid var(--novalux--primary);
  padding: 2.5rem 0;
}

.proyectos_marca-fila {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.75rem;
}

.proyectos_marca-logo {
  flex: none;
  width: auto;
  height: 5.5rem;
}

.proyectos_marca-titulo {
  margin: 0;
  color: var(--novalux--dark);
  font-size: clamp(1.5rem, 4vw, 3.25rem);
  line-height: 1.05;
  font-weight: 700;
  letter-spacing: .01em;
  text-transform: uppercase;
  text-wrap: balance;
}

/* En movil el grupo se apila: el logotipo encima del rotulo. Puesto en fila,
   a 390 px el titular se quedaba con menos de 200 px utiles y caia a cuatro
   renglones de letra minuscula. */
@media screen and (max-width: 767px) {
  .proyectos_marca {
    padding: 1.75rem 0;
  }

  .proyectos_marca-fila {
    flex-direction: column;
    gap: .875rem;
  }

  .proyectos_marca-logo {
    height: 3.5rem;
  }

  .proyectos_marca-titulo {
    text-align: center;
  }
}

/* Titular y entradilla que siguen a la banda. Son mas pequenos que un
   .heading-style-h1 normal (64 px) a proposito: el rotulo de la banda ya hace
   de reclamo grande y dos titulares del mismo cuerpo seguidos competian entre
   si. A 2.125rem la frase entra en un solo renglon en escritorio. */
.proyectos_titulo.heading-style-h1 {
  font-size: clamp(1.375rem, 2.6vw, 2.125rem);
  line-height: 1.15;
}

/* La plantilla separa cabecera y contenido con .margin-xxlarge (6rem). Aqui
   sobra: entre la entradilla y los filtros basta la mitad. */
.proyectos_intro {
  margin-bottom: 3rem;
}

@media screen and (max-width: 767px) {
  .proyectos_intro {
    margin-bottom: 2rem;
  }
}

/* =========================================================================
   30. Miniatura de la tarjeta destacada del hero
   =========================================================================
   .featured-thumbnail lleva ancho y alto fijos de la plantilla (10rem x
   7.5rem) pero ningun object-fit, asi que el valor por defecto es "fill": la
   foto se deformaba para entrar en ese rectangulo. Con la imagen anterior
   (640x800, vertical) el aplastamiento era del 60% del ancho.

   La foto que va ahora ya se sirve recortada a 4:3, de modo que "cover" no
   llega a recortar nada; se deja igualmente para que cualquier foto que se
   ponga en el futuro se recorte en vez de deformarse.
   ========================================================================= */
.featured-thumbnail {
  object-fit: cover;
}

/* =========================================================================
   31. Tarjetas de servicios: menos foto y mas texto
   =========================================================================
   Peticion del cliente: la foto un poco mas pequena y los textos un poco mas
   grandes.

   La foto no se encoge con un ancho propio: la tarjeta es una rejilla de dos
   pistas y la imagen ocupa la suya entera (width/height al 100% con
   object-fit:cover, ver la plantilla). Lo que se cambia es el reparto de la
   rejilla, de .85fr/1fr a .62fr/1fr, y la columna de la imagen pasa de ~46% a
   ~38% del ancho de la tarjeta. Como la altura de la fila la marca el texto,
   la foto tambien baja de alto en la misma proporcion.

   No se toca por debajo de 768 px: alli la tarjeta ya es de una sola columna
   (grid-template-columns:1fr de la plantilla) y la foto va recortada a 4:3 por
   el bloque 13; el reparto de pistas no pinta nada.
   ========================================================================= */
@media screen and (min-width: 768px) {
  .layout_card {
    grid-template-columns: .62fr 1fr;
  }

  /* El titulo esquiva el sello de marca. El sello (bloque 28) ocupa 4.1rem de
     ancho a 1rem del borde derecho de la tarjeta, o sea 5.1rem; el panel de
     texto llega hasta ese mismo borde y solo reserva 2.5rem de relleno. Con el
     titulo mas grande y la columna de texto mas ancha, en tarjetas de dos
     lineas ("Impermeabilizacion de terrazas") la palabra final se metia debajo
     del logotipo. Se reserva la diferencia. Donde el texto es corto no se nota:
     el contenido va centrado en vertical y el titulo ni llega a esa altura. */
  #servicios .layout_card .heading-style-h3 {
    padding-right: 3.25rem;
  }
}

/* El cuerpo de los titulos y parrafos de estas tarjetas, un escalon por
   encima del de la plantilla (2.5rem / 1rem). Se limita a #servicios para no
   arrastrar al resto de la pagina: .heading-style-h3 y .text-size-regular se
   usan tambien en proyectos, ventajas y pie.

   El parrafo sube a 1.125rem, que es justo el valor de .text-size-medium
   (--_ui-styles---size--1-small). La clase ya esta en el HTML pero no llegaba
   a aplicarse: .text-size-regular aparece despues en la hoja de la plantilla
   y, a igual especificidad, gana la ultima. */
#servicios .layout_card .heading-style-h3 {
  font-size: 2.75rem;
}

#servicios .layout_card .text-size-regular {
  font-size: 1.125rem;
}

/* En movil los titulares ya son fluidos (bloque 26) y la tarjeta es estrecha:
   un h3 de 2.75rem se comeria la tarjeta. Se devuelve a la escala fluida y el
   parrafo se queda en un aumento mas contenido. */
@media screen and (max-width: 767px) {
  #servicios .layout_card .heading-style-h3 {
    font-size: clamp(1.3rem, 5.2vw, 2rem);
  }

  #servicios .layout_card .text-size-regular {
    font-size: 1.0625rem;
  }
}

/* =========================================================================
   32. Servicios: la seccion crece con la pantalla por encima de 1440 px
   -------------------------------------------------------------------------
   PROBLEMA
   El bloque 13 le quito el tope de 84rem a .container-large, asi que las
   tarjetas de servicios se estiran hasta 100vw - 180px (los 90 px de
   --novalux--gutter por lado). Pero los tamanos de dentro -- titular, sello,
   parrafo, boton, rellenos -- son medidas fijas en rem, que no dependen de la
   ventana. Resultado: a 1440 px la proporcion es la buena, y a partir de ahi
   la tarjeta se ensancha mientras el contenido se queda igual de grande, de
   modo que a 1920 o 2560 px se ve pequeno y perdido dentro de la tarjeta.

   SOLUCION
   Una sola variable, --nx-px, que vale "un pixel del diseno de 1440 px medido
   en pixeles de la pantalla actual":

     --nx-px: (100vw - 2*gutter) / 1260

   A 1440 px el numerador es 1260 px y --nx-px vale exactamente 1px, asi que la
   consulta puede empezar en 1440 sin ningun salto. A 1920 px vale 1.381px, a
   2560 px 1.889px. Cada medida de la seccion se reescribe como "cuantos
   pixeles medía a 1440" multiplicados por --nx-px, y la seccion entera pasa a
   ser la de 1440 px ampliada, que es justo lo pedido.

   OJO con las unidades: en calc() no se puede dividir una longitud entre otra,
   asi que --nx-px NO es un numero sin unidad sino una longitud, y hay que
   escribir calc(44 * var(--nx-px)) -- numero x longitud -- y nunca
   calc(2.75rem * var(--nx-px)), que seria longitud x longitud y el navegador
   descarta la declaracion entera. De ahi que abajo todo vaya en pixeles del
   diseno (2.75rem = 44, 1.125rem = 18...); el <html> no cambia el tamano base,
   asi que 1rem = 16px y la conversion es exacta.

   Se escala tambien la cabecera (rotulo + titular) porque comparte bloque con
   las tarjetas: si solo creciera el h3 de la tarjeta, a 2560 px pasaria de los
   60 px del h2 de la seccion y la jerarquia quedaria del reves.

   NO se escala .padding-section-large (la separacion vertical entre bloques):
   es comun a todas las secciones y, si solo esta creciera, se rompe el ritmo
   con las de arriba y abajo. Tampoco --novalux--gutter, por el mismo motivo:
   el margen lateral debe seguir alineado con el resto de la pagina.

   Si algun dia se le devuelve un max-width a .container-large, hay que quitar
   este bloque o el 1260 dejara de ser el ancho de referencia.
   ========================================================================= */
@media screen and (min-width: 1440px) {
  #servicios {
    --nx-px: calc((100vw - 2 * var(--novalux--gutter)) / 1260);
  }

  /* --- Cabecera de la seccion --- */
  #servicios .eyebrow {
    grid-column-gap: calc(16 * var(--nx-px));
    grid-row-gap: calc(16 * var(--nx-px));
  }

  #servicios .eyebrow img {
    width: calc(8 * var(--nx-px));
    height: calc(8 * var(--nx-px));
  }

  #servicios .text-style-tagline {
    font-size: calc(10 * var(--nx-px));
    letter-spacing: calc(1 * var(--nx-px));
  }

  #servicios .titular-ancho {
    max-width: calc(1088 * var(--nx-px));
  }

  #servicios .heading-style-h1 {
    font-size: calc(60 * var(--nx-px));
  }

  #servicios .margin-bottom.margin-xxlarge {
    margin-bottom: calc(80 * var(--nx-px));
  }

  #servicios .margin-bottom.margin-xsmall {
    margin-bottom: calc(16 * var(--nx-px));
  }

  /* --- Tarjeta --- */
  #servicios .layout_card {
    grid-column-gap: calc(8 * var(--nx-px));
    grid-row-gap: calc(8 * var(--nx-px));
  }

  #servicios .layout_card-content {
    padding: calc(40 * var(--nx-px));
  }

  #servicios .layout_card .heading-style-h3 {
    font-size: calc(44 * var(--nx-px));
    /* El hueco que el titulo le deja al sello (bloque 31) crece con el. */
    padding-right: calc(52 * var(--nx-px));
  }

  #servicios .layout_card .text-size-regular {
    font-size: calc(18 * var(--nx-px));
  }

  #servicios .layout_card .margin-bottom.margin-small {
    margin-bottom: calc(24 * var(--nx-px));
  }

  #servicios .layout_card .margin-top.margin-medium {
    margin-top: calc(32 * var(--nx-px));
  }

  /* --- Sello de marca (bloque 28) --- */
  #servicios .servicio_sello {
    top: calc(16 * var(--nx-px));
    right: calc(16 * var(--nx-px));
    height: calc(40 * var(--nx-px));
    padding: calc(6.4 * var(--nx-px)) calc(9.6 * var(--nx-px));
    border-radius: calc(10 * var(--nx-px));
  }

  /* --- Boton "Solicitar presupuesto" --- */
  #servicios .layout_card .button.is-icon {
    grid-column-gap: calc(8 * var(--nx-px));
    grid-row-gap: calc(8 * var(--nx-px));
    padding: calc(12 * var(--nx-px)) calc(16 * var(--nx-px));
    border-radius: calc(12 * var(--nx-px));
    font-size: calc(16 * var(--nx-px));
  }

  #servicios .layout_card .button.is-icon img {
    width: calc(8 * var(--nx-px));
    height: calc(8 * var(--nx-px));
  }

  /* --- Lista de garantias de la tarjeta de piscinas (bloque 28) --- */
  #servicios .servicio_lista {
    margin-top: calc(16 * var(--nx-px));
    gap: calc(8 * var(--nx-px));
  }

  #servicios .servicio_lista li {
    padding-left: calc(24 * var(--nx-px));
    font-size: calc(16 * var(--nx-px));
  }

  #servicios .servicio_lista li::before {
    width: calc(12 * var(--nx-px));
    height: calc(7.2 * var(--nx-px));
  }
}

/* =========================================================================
   33. Opiniones reales: circulos de letra y enlace a la ficha de Google
   -------------------------------------------------------------------------
   Al pasar de tres marcadores a nueve resenas reales, todos los avatares en
   el azul de marca daban una fila monotona y, sobre todo, hacian que dos
   tarjetas seguidas se confundieran de un vistazo. Google pinta esos circulos
   de letra en colores distintos por persona; aqui se replican los tres que se
   ven en la ficha (turquesa, purpura y naranja) y el resto se queda en el azul
   de marca.

   Los tres tonos estan elegidos oscuros a proposito: el texto va en blanco
   dentro del circulo y necesita al menos 4.5:1 de contraste. Con el turquesa
   #009688 o el naranja #f57c00 de la paleta de Google no se llega; con estos
   si (4.9:1, 8.2:1 y 5.1:1).

   NOTA: son iniciales, no las fotos de perfil de Google. Esas fotos son de
   sus autores; replicarlas en un sitio comercial no es cosa nuestra.
   ========================================================================= */
.resena_avatar--turquesa { background-color: #00796b; }
.resena_avatar--purpura  { background-color: #7b1fa2; }
.resena_avatar--naranja  { background-color: #d84315; }

/* Salida a la ficha de Google, debajo de las flechas para no competir con el
   titular de la seccion. Reutiliza .button.is-icon de la plantilla; aqui solo
   se centra. Ahora que las resenas son reales el enlace es correcto: antes,
   con textos marcadores, habria dado a entender que Google las verificaba. */
.resenas_cta {
  display: flex;
  justify-content: center;
  margin-top: 2rem;
}

@media screen and (max-width: 479px) {
  /* En el movil mas estrecho el rotulo no cabe en una linea dentro de la
     pastilla y se partia dejando el punto azul descolgado. A ancho completo
     se lee de corrido y ademas iguala a los demas botones de la pagina. */
  .resenas_cta .button {
    width: 100%;
    justify-content: center;
  }
}

.resena_texto {
  text-wrap: pretty;
}

/* -------------------------------------------------------------------------
   Resenas largas: recorte a 7 lineas y boton "Leer mas"
   -------------------------------------------------------------------------
   Las opiniones reales son muy desiguales: la mas corta tiene tres palabras y
   la de Oksana Klymonchuk pasa de doce lineas. Como la pista es
   align-items:stretch, esa sola tarjeta estiraba a las otras ocho y dejaba
   media tarjeta en blanco en las cortas.

   La clave para que la tarjeta NO cambie de alto al desplegar es que el
   parrafo mida exactamente lo mismo en los dos estados: --resena-lineas de
   min-height y de max-height. Plegado recorta con line-clamp; desplegado
   quita el recorte y se lee con scroll propio dentro de ese mismo hueco.

   El min-height va en TODAS las .resena_texto del carrusel, no solo en las
   recortadas: si solo lo llevaran las largas, al desplegar las dos unicas
   tarjetas de siete lineas el alto de la fila caeria al de la siguiente mas
   alta y se moverian las nueve.

   La clase .resenas--recorta la pone el JS. Sin JS no hay boton, asi que
   tampoco se recorta: es preferible una tarjeta larga a un texto cortado sin
   forma de leer el resto.
   ------------------------------------------------------------------------- */
.resenas--recorta {
  --resena-lineas: 7;
}

.resenas--recorta .resena_texto {
  min-height: calc(var(--resena-lineas) * 1.6em);   /* 1.6 = su line-height */
  max-height: calc(var(--resena-lineas) * 1.6em);
  /* El carril de la barra se reserva ya en las nueve tarjetas, plegadas o no.
     Si se reservara solo al desplegar, el texto perderia ancho de golpe, se
     recompondrian las lineas y la tarjeta daria un salto al pulsar. */
  scrollbar-gutter: stable;
}

.resena_texto.is-recortado {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: var(--resena-lineas);
  overflow: hidden;
}

.resena_texto.is-desplegado {
  overflow-y: auto;
  /* Sin esto, al llegar al final del texto la rueda sigue hacia el carrusel y
     se salta de tarjeta sin querer. */
  overscroll-behavior: contain;
  /* La barra se deja siempre a la vista mientras esta desplegado: como el
     hueco no crece, es la unica senal de que el texto continua por debajo.
     Con las barras superpuestas de macOS, que se esconden solas, el parrafo
     desplegado parecia tan cortado como el plegado. */
  scrollbar-width: thin;
  scrollbar-color: var(--novalux--line-strong) transparent;
}

.resena_texto.is-desplegado::-webkit-scrollbar {
  width: .375rem;
}

.resena_texto.is-desplegado::-webkit-scrollbar-track {
  background: transparent;
}

.resena_texto.is-desplegado::-webkit-scrollbar-thumb {
  background-color: var(--novalux--line-strong);
  border-radius: 10rem;
}

/* El boton hereda el gap de 1.25rem de .resena, que para un enlace de texto es
   demasiado: se recupera parte con el margen negativo. */
.resena_mas {
  align-self: flex-start;
  margin-top: -.625rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--novalux--primary);
  font-size: .9375rem;
  font-weight: 600;
  line-height: 1.3;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: .15em;
}

.resena_mas:hover {
  text-decoration-thickness: .125rem;
}

/* El parrafo desplegado recibe el foco (el JS le pone tabindex) por ser una
   region con scroll: sin anillo no se ve donde esta el teclado. */
.resena_texto:focus-visible {
  outline: .125rem solid var(--novalux--primary);
  outline-offset: .25rem;
  border-radius: .375rem;
}
