/* ================================================================
   LECOMAN - PREMIUM LIGHT DESIGN SYSTEM
   Advanced animations, grid hero, glass morphism
   Optimizado para PageSpeed Insights
   ================================================================ */

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

html {
    font-size: 16px;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    scroll-behavior: auto;
    overflow-y: scroll; /* Siempre mostrar espacio para scrollbar */
    scroll-padding-top: 99px; /* Altura de la cabecera fija: 40px logo + 2*24.5px relleno */

    /* text-rendering se queda en `auto` a proposito.
       Estaba en `optimizeSpeed`, que le dice al navegador que desactive el
       kerning y las ligaduras. En una web cuyos titulares van en una grotesca
       de display eso se nota: pares como "AV", "To" o "Ye" quedan con el hueco
       sin corregir. Lo que ahorra son microsegundos en el reflow; lo que
       cuesta es el acabado de cada titular de la web. */
    font-kerning: normal;
    font-variant-ligatures: common-ligatures contextual;
}

/* ========== OPTIMIZACIONES DE RENDIMIENTO ========== */
/* Sin content-visibility en las secciones, a propósito.
   Había `content-visibility: auto` con un alto provisional de 800px. Medido el
   15 de septiembre de 2026: la portada medía 11.351px al cargar y 12.866px al
   llegar abajo, porque cada sección real mide más que el provisional y crece al
   pintarse. ScrollTrigger calcula sus posiciones al cargar, así que todo lo que
   había debajo (proceso, comparador, preguntas, contacto) se disparaba fuera de
   sitio y Lenis recalculaba el recorrido a mitad del scroll: saltos. En una
   página de siete secciones lo que ahorraba al pintar era casi nada. */

/* Movimiento reducido: las animaciones y transiciones se mantienen para todos
   (decisión del 15 de septiembre de 2026, ver la nota de MQ en main.js). Antes
   aquí se anulaban TODAS, hovers incluidos, y quien tenía "menos movimiento"
   activado en Windows veía la web estática. Solo se quita el desplazamiento
   suave de los saltos a un ancla. */
@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto !important;
    }
}

/* Placeholder para imágenes lazy loading */
img[loading="lazy"] {
    background: linear-gradient(135deg, #f0f0f0 0%, #e0e0e0 100%);
}

/* ========== SCROLLBAR PERSONALIZADA ==========
   Lo de abajo es el respaldo: la barra del sistema, repintada. Se ve mientras
   el JavaScript no haya montado la superpuesta, y para siempre si no llega a
   ejecutarse. Nadie se queda sin barra por nuestra culpa.
   La superpuesta, la que pidió el cliente, está más abajo, bajo
   `html.barra-propia`. */
::-webkit-scrollbar {
    width: 6px;
    background: transparent;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    background: var(--color-primary);
    border-radius: var(--radius-md);
    width: 2px;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--color-primary-light);
}

/* Firefox - con detección de soporte */
@supports (scrollbar-width: thin) {
    html {
        scrollbar-width: thin;
        scrollbar-color: var(--color-primary) transparent;
    }
}

/* ========== BARRA DE DESPLAZAMIENTO SUPERPUESTA ==========
   La barra del sistema OCUPA SITIO: reserva sus 6px en el diseño, así que la
   página se queda a 6px del borde de la ventana y el degradado del hero se
   corta contra una franja vacía. No hay forma de hacerla superpuesta en
   escritorio, ni con `::-webkit-scrollbar` ni con `scrollbar-width`.

   Así que se esconde y se dibuja una encima, fija sobre el contenido: sin
   carril, sin fondo, solo el pulgar. La página pasa a ocupar la ventana
   entera. El pulgar lo mueve GSAP desde ScrollTrigger y se puede arrastrar,
   que si no, esconder la del sistema le quitaría al usuario algo que tenía.

   `html.barra-propia` la pone initBarraScroll() en scripts/main.js, y solo
   cuando el pulgar existe de verdad. Mientras no esté, manda el respaldo de
   arriba. Mismo trato que `.has-custom-cursor`. */
html.barra-propia {
    scrollbar-width: none;             /* Firefox */
    -ms-overflow-style: none;          /* Edge antiguo */
}

html.barra-propia::-webkit-scrollbar {
    width: 0;
    height: 0;
}

.barra-scroll {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 14px;
    z-index: var(--z-progress);
    /* El carril no existe como superficie: no pinta nada y no se come los
       clics del contenido que hay debajo. Solo el pulgar los recibe. */
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.35s ease;
}

html.barra-propia .barra-scroll {
    opacity: 1;
}

/* Mientras el preloader tapa la página o el menú está abierto no hay nada que
   recorrer detrás: la barra sobra y encima quedaría flotando sobre el fondo
   oscuro. */
html.barra-propia.is-loading .barra-scroll,
html.barra-propia.nav-open .barra-scroll,
html.barra-propia .barra-scroll--sin-recorrido {
    opacity: 0;
}

/* Sin recorrido no hay pulgar que agarrar: que no se coma los clics. */
.barra-scroll--sin-recorrido .barra-scroll__pulgar {
    pointer-events: none;
}

.barra-scroll__pulgar {
    position: absolute;
    top: 0;
    right: 0;
    width: 14px;
    height: 60px;
    pointer-events: auto;
    cursor: grab;
    /* El pulgar se ve de 6px pero se agarra en 14: el borde transparente
       agranda la zona de clic sin engordar el dibujo. */
    border: 4px solid transparent;
    border-radius: 999px;
    background-color: rgba(var(--color-ink-rgb), 0.28);
    background-clip: padding-box;
    transition: background-color 0.25s ease;
    will-change: transform;
}

.barra-scroll__pulgar:hover,
.barra-scroll__pulgar.esta-arrastrando {
    background-color: var(--color-primary);
}

.barra-scroll__pulgar.esta-arrastrando {
    cursor: grabbing;
}

html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }

body {
    font-family: var(--font-primary);
    background: var(--surface-page);
    color: var(--color-ink);
    overflow-x: hidden;
    line-height: var(--leading-normal);

    /* El castellano tiene palabras largas -"acondicionamiento",
       "impermeabilizacion"- y las direcciones de correo no se parten solas. En
       un movil de 320px eso desbordaba la caja.

       `break-word` y no `anywhere`: los dos parten la palabra que no cabe, pero
       `anywhere` ademas cuenta ese corte al calcular la anchura minima del
       elemento, y eso cambia como se reparten los flex y los grid de toda la
       web. `break-word` solo actua al pintar, sin tocar el reparto. */
    overflow-wrap: break-word;
}

body.is-loading { overflow: hidden !important; }
body.nav-open { overflow: hidden !important; }

/* Scrollbar adaptada al preloader (fondo oscuro) */
html.is-loading::-webkit-scrollbar-track {
    background: var(--color-ink) !important;
}
html.is-loading::-webkit-scrollbar-thumb {
    background: var(--color-primary) !important;
}

/* Scrollbar adaptada al menú (fondo muy oscuro) */
html.nav-open::-webkit-scrollbar-track {
    background: var(--color-ink-deepest) !important;
}
html.nav-open::-webkit-scrollbar-thumb {
    background: var(--color-primary) !important;
}

a { text-decoration: none; color: inherit; transition: color 0.3s ease; }
a:visited { color: inherit; }
button { border: none; background: none; cursor: pointer; font-family: inherit; }
img { max-width: 100%; height: auto; display: block; }
ul, ol { list-style: none; }

.container {
    width: 100%;
    max-width: var(--container-max);
    margin: 0 auto;
    padding: 0 var(--container-pad);
}

/* ========== NOISE OVERLAY ========== */
/* Capa de grano sobre toda la pagina. Va promovida a capa de GPU: al ser fija
   y cubrirlo todo, sin promover obliga a recomponer la textura entera en cada
   fotograma de scroll. */
.noise-overlay {
    will-change: transform;
    transform: translateZ(0);
    position: fixed;
    inset: 0;
    z-index: var(--z-grain);
    pointer-events: none;
    opacity: 0.015;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
}

/* ========== TYPOGRAPHY ========== */
.section-label {
    display: inline-block;
    font-family: var(--font-accent);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--color-primary);
    margin-bottom: 1.5rem;
    position: relative;
    padding-left: 3rem;
}

.section-label::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    /* Sin el translateY la raya se apoya con su borde SUPERIOR en el centro,
       asi que quedaba un pixel por debajo del eje del texto. Se ve poco por
       separado y se ve mucho cuando hay siete etiquetas iguales bajando por
       la pagina. */
    transform: translateY(-50%);
    width: 2rem;
    height: 2px;
    background: var(--color-primary);
    border-radius: var(--radius-xs);
}

.section-title {
    font-family: var(--font-heading);
    font-size: var(--text-title);
    font-weight: 700;
    line-height: var(--leading-tight);
    letter-spacing: var(--tracking-tight);
    color: var(--color-ink);
    padding-right: 0.05em;
}

.section-title em {
    font-style: normal;
    background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-light) 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

/* ========== SCROLL PROGRESS ========== */
.scroll-progress {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 3px;
    z-index: var(--z-progress);
    background: rgba(var(--color-ink-rgb), 0.05);
    will-change: transform;
    transform: translateZ(0);
}

.scroll-progress__bar {
    height: 100%;
    /* Ancho completo y se recorta con scaleX. Antes ponia `width: 0%` mientras
       el JS animaba scaleX: escalar cero es cero, asi que esta barra no se ha
       visto nunca, en ninguna pagina. El scaleX(0) inicial evita ademas que
       asome entera durante el instante entre pintar el CSS y arrancar el JS. */
    width: 100%;
    background: linear-gradient(90deg, var(--color-primary), var(--color-primary-light));
    transform: scaleX(0);
    transform-origin: left center;
    will-change: transform;
}


/* ========== PRELOADER ========== */
.preloader {
    position: fixed;
    inset: 0;
    z-index: var(--z-preloader);
    background: var(--color-ink);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.5rem;
    clip-path: inset(0 0 0 0);
}

.preloader__logo {
    font-family: var(--font-heading);
    font-size: clamp(2rem, 4vw, 3rem);
    font-weight: 700;
    letter-spacing: var(--tracking-snug);
    color: var(--text-inverse);
    text-transform: uppercase;
    text-align: center;
}

.preloader__progress {
    width: min(280px, 60vw);
    height: 2px;
    background: rgba(255,255,255,0.12);
    overflow: hidden;
    border-radius: var(--radius-md);
}

/* Misma historia que el titulo del hero: el barrido repintaba en cada fotograma,
   y ademas justo durante la carga, que es cuando el hilo principal esta mas
   ocupado. El degradado se queda quieto. */
.preloader__bar {
    height: 100%;
    width: 100%;
    background: linear-gradient(90deg, var(--color-primary), var(--color-primary-light), var(--color-primary));
    border-radius: var(--radius-md);
    transform: scaleX(0);
    transform-origin: center;
}

.preloader__counter {
    font-family: var(--font-heading);
    font-size: clamp(1rem, 2vw, 1.25rem);
    font-weight: 500;
    letter-spacing: var(--tracking-wide);
    color: var(--text-on-dark-muted);
    text-align: center;
    margin-top: 0.5rem;
}

/* ========== CURSOR PERSONALIZADO ==========
   Se oculta el cursor del sistema SOLO cuando el JS ha confirmado que procede
   dibujar el falso: puntero fino. La clase
   .has-custom-cursor la pone initCursor(), y solo ahi.

   Antes esto era `html, body { cursor: none !important }` incondicional, y
   dejaba la web sin ningun cursor visible en tres situaciones reales:

     - Con `prefers-reduced-motion: reduce`: el JS si escondia los dos puntos,
       pero el `cursor: none` seguia aplicandose.
     - Con la ventana por debajo de 992px en un ordenador con raton: el CSS
       escondia los puntos por media query y pasaba exactamente lo mismo.
     - Si el JS o GSAP no llegaban a cargar (CDN caido, bloqueador de scripts).

   Atando el `cursor: none` a la misma decision que dibuja el cursor falso, los
   dos ya no se pueden desincronizar: o estan los dos, o no esta ninguno.

   El selector universal hace falta de verdad. `cursor` se hereda, pero
   cualquier elemento con su propia regla -y hay una docena de
   `cursor: pointer` y dos `cursor: ew-resize`- ganaba a la heredada. El
   resultado era la mano del sistema Y el punto rojo a la vez encima de cada
   tarjeta de servicio. */
html.has-custom-cursor,
html.has-custom-cursor * {
    cursor: none !important;
}

/* Los dos puntos se dibujan SOLO con .has-custom-cursor, la misma clase que
   esconde el cursor del sistema. Antes no tenian display: none de base y la
   visibilidad la llevaba el JS con style.display: si el JS no llegaba, o hasta
   que llegaba, asomaban cortados en la esquina superior izquierda. */
.cursor,
.cursor-follower {
    display: none;
}

html.has-custom-cursor .cursor,
html.has-custom-cursor .cursor-follower {
    display: block;
    opacity: 0;
}

/* Visibles solo con el raton dentro de la ventana (la clase la pone y la
   quita initCursor). Hasta el primer movimiento no se sabe donde esta el
   raton, y los puntos esperaban en la esquina superior izquierda.
   Sobre un campo de texto el aro no aparece: distrae y tapa lo que se esta
   escribiendo. Antes eso lo hacia una regla .is-text que nunca llego a
   funcionar, porque GSAP escribia opacity: 1 en linea y el estilo en linea
   gana a la hoja. Ahora la opacidad es solo cosa del CSS. */
html.has-custom-cursor.cursor-dentro .cursor,
html.has-custom-cursor.cursor-dentro .cursor-follower:not(.is-text) {
    opacity: 1;
}

/* Sobre un elemento interactivo el aro crece (lo escala GSAP) y se atenua. */
html.has-custom-cursor.cursor-dentro .cursor-follower.is-active:not(.is-text) {
    opacity: 0.5;
}

.cursor {
    position: fixed;
    width: 12px;
    height: 12px;
    background: var(--color-ink);
    border-radius: var(--radius-circle);
    pointer-events: none;
    z-index: var(--z-cursor);
    mix-blend-mode: difference;
    transform: translate(-50%, -50%);
    will-change: transform;
    /* Solo el color se anima en CSS. El tamano lo lleva GSAP con scale.
       Antes lo llevaban los dos a la vez -CSS animaba width/height de 12 a
       28px mientras GSAP escalaba a 1.5-, asi que el tamano real era el
       producto de las dos cosas y cada fotograma obligaba a recalcular el
       layout. Un transform no toca el layout. */
    transition: background-color 0.3s var(--ease-out-expo),
                opacity 0.3s ease;
}

.cursor.is-active {
    background: var(--color-primary);
    mix-blend-mode: normal;
}

/* Sobre un campo de texto el punto se estira hasta parecer un cursor de
   escritura. Sin esto, al ocultar el cursor del sistema no quedaba ninguna
   pista de donde ibas a escribir, justo en el formulario de contacto. */
.cursor.is-text {
    width: 2px;
    height: 26px;
    border-radius: 1px;
    background: var(--color-primary);
    mix-blend-mode: normal;
}

.cursor-follower {
    position: fixed;
    width: 40px;
    height: 40px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-circle);
    pointer-events: none;
    z-index: calc(var(--z-cursor) - 1);
    transform: translate(-50%, -50%);
    will-change: transform;
    transition: border-color 0.3s ease, opacity 0.3s ease;
}

.cursor-follower.is-active {
    border-color: var(--color-primary);
}

/* ========== HEADER MINIMALISTA ========== */
/* Aqui habia un mix-blend-mode: difference. La idea era que el logotipo se
   invirtiera solo segun el fondo, pero midiendo la franja real de 90px bajo el
   header a lo largo de las 59 posiciones de scroll, 50 son claras (luminancia
   251). O sea que el 85% del recorrido el logo salia EN NEGATIVO: el isotipo
   rojo se pintaba cian y el punto de marca, turquesa (230,57,70 restado de
   250,251,254 da 20,194,184). Se ve en e2e/punto/logo.png.
   Ahora la cabecera se pinta para fondo claro, que es el caso normal, y
   .header--sobre-oscuro la cambia donde de verdad hay fondo oscuro. */
.header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    z-index: var(--z-header);
    padding: 1.5rem 0;
    will-change: transform;
    transform: translateZ(0);
    transition: padding 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Velo: las fotos del carrusel de servicios pasan por debajo del header y
   algunas son oscuras (luminancia 93 a la izquierda en y=4800). Este degradado
   garantiza que el logotipo oscuro se lea siempre. Sobre las secciones claras
   es del mismo color que el fondo, asi que no se ve. */
.header::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 190%;
    background: linear-gradient(to bottom,
                rgba(var(--surface-page-rgb), 0.92) 0%,
                rgba(var(--surface-page-rgb), 0.7) 45%,
                rgba(var(--surface-page-rgb), 0) 100%);
    pointer-events: none;
    z-index: -1;
    transition: background 0.35s ease;
}

.header.is-scrolled {
    padding: 1rem 0;
}

.header__container {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

/* Logo tipográfico */
.header__logo {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    text-decoration: none;
}

.header__logo-img {
    width: 40px;
    height: 40px;
    object-fit: contain;
}

.header__logo-text {
    font-family: var(--font-heading);
    font-size: var(--text-md);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    color: var(--color-ink);
    text-transform: uppercase;
    transition: color 0.35s ease;
}

.header__logo-dot {
    width: 8px;
    height: 8px;
    background: var(--color-primary);
    border-radius: var(--radius-circle);
}


/* Botón de menú */
.header__menu-btn {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.75rem 1.25rem;
    background: transparent;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: background 0.25s ease,
                border-color 0.25s ease,
                transform 0.2s ease;
    will-change: transform;
}

.header__menu-btn:hover {
    background: rgba(var(--color-ink-rgb), 0.06);
    border-color: rgba(var(--color-ink-rgb), 0.4);
    transform: scale(1.02);
}

.header__menu-btn:active {
    transform: scale(0.98);
}

.header__menu-label {
    font-family: var(--font-primary);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--color-ink);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    transition: color 0.35s ease;
}

.header__menu-icon {
    position: relative;
    width: 24px;
    height: 12px;
}

.header__menu-icon span {
    position: absolute;
    left: 0;
    width: 100%;
    height: 2px;
    background: var(--color-ink);
    border-radius: var(--radius-xs);
    will-change: transform;
    transition: background 0.35s ease;
}

.header__menu-icon span:first-child { top: 0; }
.header__menu-icon span:last-child { bottom: 0; width: 60%; }

/* Hamburger → X animation handled by GSAP in initHeader() */

/* Cabecera sobre fondo oscuro. Dos sitios, y solo dos, medidos con pixeles
   reales: el pie de pagina (luminancia 17) y el menu a pantalla completa.
   La clase del pie la pone initHeaderSobreOscuro(); la del menu es nav-open,
   que ya existia. */
.header--sobre-oscuro .header__logo-text,
.header--sobre-oscuro .header__menu-label,
html.nav-open .header__logo-text,
html.nav-open .header__menu-label {
    color: var(--text-inverse);
}

.header--sobre-oscuro .header__menu-icon span,
html.nav-open .header__menu-icon span {
    background: var(--surface-raised);
}

.header--sobre-oscuro .header__menu-btn,
html.nav-open .header__menu-btn {
    border-color: rgba(255, 255, 255, 0.3);
}

.header--sobre-oscuro .header__menu-btn:hover,
html.nav-open .header__menu-btn:hover {
    background: rgba(255, 255, 255, 0.1);
    border-color: var(--text-on-dark-muted);
}

/* El velo tambien se da la vuelta: uno claro sobre el pie dejaria una neblina
   blanca en su borde superior. Con el menu abierto sobra del todo, porque el
   panel ya es opaco. */
.header--sobre-oscuro::before {
    background: linear-gradient(to bottom,
                rgba(10, 10, 15, 0.85) 0%,
                rgba(10, 10, 15, 0.55) 45%,
                rgba(10, 10, 15, 0) 100%);
}

html.nav-open .header::before {
    background: none;
}

/* ========== FULLSCREEN NAVIGATION ========== */
.nav-fullscreen {
    position: fixed;
    inset: 0;
    z-index: var(--z-nav);
    pointer-events: none;
    visibility: hidden;
}

.nav-fullscreen.is-open {
    pointer-events: all;
}

.nav-fullscreen__bg {
    position: absolute;
    inset: 0;
    background: var(--color-ink-deepest);
    transform-origin: top center;
}

.nav-fullscreen__content {
    position: relative;
    width: 100%;
    display: flex;
    flex-direction: column;
    padding: clamp(6rem, 10vh, 8rem) clamp(2rem, 5vw, 5rem) clamp(2rem, 4vh, 3rem);

    /* El respaldo en vh va primero: un navegador que no entienda dvh se queda
       con el, y uno que si lo entienda sobrescribe con la linea siguiente.
       Hace falta porque en movil vh mide la ventana con la barra de direcciones
       retraida, y sin esto el ultimo enlace del menu queda debajo de ella.

       Y si aun asi no cabe -movil apaisado, tipografia grande del sistema-, que
       se pueda llegar abajo desplazando. El scroll es nativo y no Lenis: dentro
       de un overlay tactil el suavizado estorba. overscroll-behavior evita que
       al llegar al final del menu el gesto siga y arrastre la pagina de debajo. */
    height: 100vh;
    height: 100dvh;
    max-height: 100vh;
    max-height: 100dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.nav-fullscreen__main {
    flex: 1;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(2rem, 5vw, 6rem);
    align-items: center;
}

/* Menu Links */
.nav-fullscreen__menu {
    display: flex;
    flex-direction: column;
}

.nav-fullscreen__list {
    display: flex;
    flex-direction: column;
    gap: 0;
}

.nav-fullscreen__item {
    overflow: hidden;
}

.nav-fullscreen__link {
    display: flex;
    align-items: baseline;
    gap: 2rem;
    padding: 1.25rem 0;
    text-decoration: none;
    border-bottom: 1px solid rgba(255,255,255,0.08);
}

.nav-fullscreen__link::before {
    content: attr(data-index);
    font-family: var(--font-primary);
    font-size: var(--text-xs);
    font-weight: 500;
    color: rgba(255,255,255,0.3);
    letter-spacing: var(--tracking-wide);
    min-width: 2rem;
}

.nav-fullscreen__link-text {
    font-family: var(--font-heading);
    font-size: clamp(2.5rem, 6vw, 5rem);
    font-weight: 600;
    color: var(--text-inverse);
    letter-spacing: var(--tracking-tight);
    line-height: var(--leading-tight);
    transition: color 0.4s var(--ease-out-expo),
                transform 0.4s var(--ease-out-expo),
                width 0.4s var(--ease-out-expo);
    display: inline-block;
    position: relative;
}

.nav-fullscreen__link-text::after {
    content: '';
    position: absolute;
    bottom: 0.1em;
    left: 0;
    width: 0;
    height: 3px;
    background: var(--color-primary);
    transition: width 0.4s var(--ease-out-expo);
}

.nav-fullscreen__link:hover .nav-fullscreen__link-text {
    color: var(--color-primary);
    transform: translateX(1.5rem);
}

.nav-fullscreen__link:hover .nav-fullscreen__link-text::after {
    width: 100%;
}

.nav-fullscreen__link-label {
    font-family: var(--font-primary);
    font-size: var(--text-xs);
    color: var(--text-on-dark-muted);
    margin-left: auto;
    opacity: 0;
    transform: translateX(-30px);
    transition: color 0.5s var(--ease-out-expo),
                opacity 0.5s var(--ease-out-expo),
                transform 0.5s var(--ease-out-expo);
}

.nav-fullscreen__link:hover .nav-fullscreen__link-label {
    opacity: 1;
    transform: translateX(0);
    color: var(--text-on-dark-soft);
}

/* Visual/Image Section */
.nav-fullscreen__visual {
    position: relative;
    height: 70%;
    border-radius: var(--radius-xl);
    overflow: hidden;
}

.nav-fullscreen__image-wrapper {
    position: absolute;
    inset: 0;
}

.nav-fullscreen__image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.8s ease;
}

.nav-fullscreen__visual:hover .nav-fullscreen__image {
    transform: scale(1.08);
}

.nav-fullscreen__image-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, rgba(var(--color-primary-rgb), 0.3) 0%, rgba(10,10,15,0.5) 100%);
}

/* Footer del nav */
.nav-fullscreen__footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-top: 2rem;
    border-top: 1px solid rgba(255,255,255,0.08);
}

.nav-fullscreen__contact {
    display: flex;
    gap: 2rem;
}

.nav-fullscreen__contact a,
.nav-fullscreen__social a {
    font-family: var(--font-primary);
    font-size: 0.875rem;
    color: var(--text-on-dark-muted);
    text-decoration: none;
    transition: color 0.3s ease;
}

.nav-fullscreen__contact a:hover,
.nav-fullscreen__social a:hover {
    color: var(--text-inverse);
}

.nav-fullscreen__social {
    display: flex;
    gap: 1.5rem;
}

.nav-fullscreen__social a {
    font-weight: 600;
    letter-spacing: var(--tracking-wide);
}

/* Responsive Navigation */
@media (max-width: 1023px) {
    .nav-fullscreen__main {
        grid-template-columns: 1fr;
    }
    
    .nav-fullscreen__visual {
        display: none;
    }
    
    .nav-fullscreen__link-text {
        font-size: clamp(2rem, 8vw, 3.5rem);
    }
}

@media (max-width: 600px) {
    .header__menu-label {
        display: none;
    }
    
    .header__menu-btn {
        padding: 0.75rem;
        border-radius: var(--radius-circle);
        width: 48px;
        height: 48px;
        justify-content: center;
    }
    
    .nav-fullscreen__contact {
        flex-direction: column;
        gap: 0.75rem;
    }
    
    .nav-fullscreen__footer {
        flex-direction: column;
        gap: 1.5rem;
        align-items: flex-start;
    }
}

/* ========== HERO ========== */
.hero {
    position: relative;
    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: clamp(6rem, 12vh, 10rem) 0;
    overflow: hidden;
    background: var(--surface-page);
    contain: layout style;
}

.hero::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 120px;
    background: linear-gradient(to top, #fff 0%, transparent 100%);
    pointer-events: none;
    z-index: 5;
}

/* Grid Background */
.hero__grid-bg {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
}

.hero__canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}

.hero__grid-overlay {
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse 90% 70% at 50% 40%, transparent 30%, var(--surface-page) 90%);
    pointer-events: none;
    will-change: transform;
    transform: translateZ(0);
}

/* Floating Shapes */
.hero__shapes {
    position: absolute;
    inset: 0;
    pointer-events: none;
    overflow: hidden;
}

.hero__shape {
    position: absolute;
    border-radius: var(--radius-circle);
    filter: blur(60px);
    opacity: 0.4;
    will-change: transform;
    transform: translateZ(0);
}

.hero__shape--1 {
    width: 500px;
    height: 500px;
    background: linear-gradient(135deg, rgba(var(--color-primary-rgb), 0.3) 0%, rgba(255,107,107,0.2) 100%);
    top: -10%;
    right: -5%;
}

.hero__shape--2 {
    width: 400px;
    height: 400px;
    background: linear-gradient(135deg, rgba(78,205,196,0.2) 0%, rgba(132,94,247,0.15) 100%);
    bottom: -10%;
    left: -5%;
}

.hero__shape--3 {
    width: 300px;
    height: 300px;
    background: linear-gradient(135deg, rgba(132,94,247,0.2) 0%, rgba(var(--color-primary-rgb), 0.15) 100%);
    top: 40%;
    left: 30%;
}

.hero__content {
    position: relative;
    z-index: 2;
    width: 100%;
    text-align: center;
    max-width: 1000px;
    margin: 0 auto;
}

.hero__eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 2.5rem;
    overflow: hidden;
    background: rgba(255,255,255,0.7);
    padding: 0.75rem 1.5rem;
    border-radius: var(--radius-pill);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(var(--color-ink-rgb), 0.05);
    opacity: 0;
    transform: translateY(40px);
}

.hero__eyebrow-line {
    width: 2rem;
    height: 2px;
    background: var(--color-primary);
    transform-origin: left;
    border-radius: var(--radius-xs);
}

.hero__eyebrow-text {
    font-family: var(--font-accent);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--text-secondary);
}

.hero__title {
    font-family: var(--font-heading);
    font-size: var(--text-hero);
    font-weight: 700;
    line-height: var(--leading-none);
    letter-spacing: var(--tracking-tight);
    margin-bottom: 2rem;
    color: var(--color-ink);
    padding-right: 0.1em;
}

.hero__title-line {
    display: block;
    overflow: hidden;
}

.hero__title-text {
    display: block;
    transform: translateY(100%);
    opacity: 0;
}

/* Aqui habia un `animation: shimmer 3s infinite` que movia el background-position
   del degradado. Medido con una traza de Chrome, quieto en el hero 5 segundos
   sin tocar nada:
       con shimmer -> 1486 pintados, 132 ms de pintado y 27 ms de rasterizado,
                      con 723 repintados del documento ENTERO
       sin shimmer -> 0 pintados, 0 ms, 0 repintados
   O sea que era la unica razon por la que la portada no se quedaba nunca quieta.
   background-position no se puede componer en la GPU: cada fotograma obliga a
   repintar el texto, y al ir sobre background-clip: text arrastra el documento.
   El degradado se queda; lo que se va es el barrido. */
.hero__title em {
    font-style: normal;
    background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-soft) 50%, var(--color-primary) 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.hero__subtitle {
    font-family: var(--font-primary);
    font-size: clamp(1rem, 2vw, 1.25rem);
    font-weight: 400;
    line-height: var(--leading-relaxed);
    color: rgba(var(--color-ink-rgb), 0.6);
    max-width: 550px;
    margin: 0 auto 3rem;
    opacity: 0;
    transform: translateY(20px);
}

.hero__bottom {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4rem;
    flex-wrap: wrap;
}

.hero__cta {
    display: inline-flex;
    align-items: center;
    gap: 1rem;
    padding: 1.25rem 2.5rem;
    background: var(--color-ink);
    color: var(--text-inverse);
    font-family: var(--font-accent);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    border-radius: var(--radius-pill);
    transition: box-shadow 0.5s var(--ease-out-expo),
                transform 0.5s var(--ease-out-expo);
    position: relative;
    overflow: hidden;
    box-shadow: 0 4px 30px rgba(var(--color-ink-rgb), 0.2);
    opacity: 0;
    transform: translateY(40px);
}

.hero__cta::before {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--color-primary);
    transform: translateX(-101%);
    transition: transform 0.5s var(--ease-out-expo);
    z-index: var(--z-below);
    border-radius: var(--radius-pill);
}

.hero__cta:hover::before {
    transform: translateX(0);
}

.hero__cta:hover {
    transform: translateY(-3px);
    box-shadow: var(--glow-primary);
}

.hero__cta-arrow {
    width: 20px;
    height: 20px;
    stroke: currentColor;
    fill: none;
    transition: transform 0.3s ease;
}

.hero__cta:hover .hero__cta-arrow {
    transform: translateX(5px);
}

.hero__scroll-hint {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    opacity: 0;
    transform: translateY(40px);
}

.hero__scroll-text {
    font-family: var(--font-accent);
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: rgba(var(--color-ink-rgb), 0.4);
    writing-mode: vertical-rl;
}

.hero__scroll-line {
    width: 2px;
    height: 80px;
    background: rgba(var(--color-ink-rgb), 0.1);
    position: relative;
    overflow: hidden;
    border-radius: var(--radius-xs);
}

.hero__scroll-dot {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 4px;
    height: 4px;
    background: var(--color-primary);
    border-radius: var(--radius-circle);
}

/* Con transform y no con top: animar top obligaba a recalcular el layout en cada
   fotograma, 144 veces por segundo con la pagina quieta segun la auditoria.
   El recorrido es el alto de .hero__scroll-line (80px), no un porcentaje: en un
   transform el % es del propio punto (4px). Y cada fotograma repite el
   translateX(-50%) del centrado, porque el transform de la animacion sustituye
   entero al de la regla. */

.hero__counter {
    text-align: center;
    opacity: 0;
    transform: translateY(40px);
}

.hero__counter-number {
    font-family: var(--font-heading);
    font-size: clamp(3rem, 6vw, 5rem);
    font-weight: 700;
    letter-spacing: var(--tracking-tight);
    line-height: var(--leading-none);
    display: block;
    background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-ink) 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.hero__counter-label {
    font-family: var(--font-accent);
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--text-muted);
}

/* ========== INTRO ========== */
.intro {
    padding: var(--section-gap-lg) 0;
    background: var(--surface-raised);
    position: relative;
}

.intro::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 120px;
    background: linear-gradient(to bottom, #fff 0%, transparent 100%);
    pointer-events: none;
    z-index: 2;
}

.intro::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 120px;
    background: linear-gradient(to top, var(--surface-sunken) 0%, transparent 100%);
    pointer-events: none;
    z-index: 2;
}

.intro__text {
    font-family: var(--font-heading);
    font-size: clamp(1.5rem, 4vw, 3.5rem);
    font-weight: 500;
    line-height: var(--leading-snug);
    letter-spacing: var(--tracking-snug);
    color: rgba(var(--color-ink-rgb), 0.12);
    max-width: 1100px;
}

.intro__text .word {
    display: inline-block;
    overflow: hidden;
    vertical-align: top;
    margin-right: 0.3em;
    line-height: var(--leading-snug);
}

.intro__text .char {
    display: inline-block;
}

/* En reposo esto era #c0c0c0 al 40 % de opacidad. Compuesto sobre el blanco de
   la seccion da #e6e6e6: 1,25:1 de contraste, o sea ilegible. El efecto revela
   el parrafo conforme bajas, asi que quien se parase a media seccion -o quien
   simplemente leyera despacio- se quedaba el final del texto en blanco.
   Ahora el reposo es el mismo tinte de la marca al 62 %, que da 4,8:1 y pasa el
   minimo, y lo que hace el efecto es acabar de encenderlo. De paso solo anima
   opacidad, que no obliga a repintar. */
.intro__text .char-inner {
    display: inline-block;
    color: var(--color-ink);
    opacity: 0.62;
    transition: opacity 0.15s ease-out;
}

.intro__text .char-inner.is-visible {
    opacity: 1;
}

.intro__text .space {
    display: inline;
}

.intro__text .word-inner {
    display: inline-block;
    /* 0,4 s y no 0,15: el texto se ilumina palabra a palabra con el scroll y a
       0,15 s el cambio se percibe como un parpadeo en vez de como un barrido. */
    transition: color 0.4s var(--ease-out-expo);
}

.intro__text .word-inner.is-visible {
    color: var(--color-ink);
}

/* ========== SERVICES HORIZONTAL ========== */
.services-horizontal {
    background: var(--surface-sunken);
    overflow: hidden;
    position: relative;
    contain: layout style;
    /* La altura de pantalla completa la necesita el pin de ScrollTrigger.
       dvh detras de vh: en movil, vh mide la ventana con la barra de
       direcciones retraida, asi que la seccion sobresale justo lo que mide esa
       barra y el pin se descuadra al aparecer. */
    min-height: 100vh;
    min-height: 100dvh;
}

.services-horizontal__wrapper {
    padding: var(--section-gap) 0;
    position: relative;
    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.services-horizontal__header {
    margin-bottom: 4rem;
    text-align: left;
    padding-left: clamp(2rem, 5vw, 5rem);
    position: relative;
}

.services-horizontal__header .section-label {
    color: var(--color-primary);
}

.services-horizontal__header .section-title {
    color: var(--color-ink);
}

.services-horizontal__header .section-title em {
    color: var(--color-ink);
}

.services-horizontal__track {
    display: flex;
    gap: clamp(1.5rem, 3vw, 3rem);
    padding: 2rem clamp(2rem, 5vw, 5rem);
    width: max-content;
    align-items: stretch;
    will-change: transform;
    transform: translateZ(0);
}

/* Service Card - Diseño más limpio */
.service-card {
    position: relative;
    width: clamp(320px, 28vw, 420px);
    height: clamp(450px, 60vh, 550px);
    height: clamp(450px, 60svh, 550px);
    background: var(--color-ink);
    overflow: hidden;
    flex-shrink: 0;
    border-radius: var(--radius-xl);
    cursor: pointer;
    transition: transform 0.4s var(--ease-out-expo),
                box-shadow 0.4s var(--ease-out-expo);
    box-shadow: 0 10px 40px rgba(var(--color-ink-rgb), 0.15);
    contain: layout style paint;
    transform: translateZ(0);
}

.service-card:hover {
    transform: translateY(-12px) scale(1.02) translateZ(0);
    box-shadow: 0 25px 60px rgba(var(--color-ink-rgb), 0.25),
                0 0 0 1px rgba(var(--color-primary-rgb), 0.1);
}

.service-card__number {
    position: absolute;
    top: 1.5rem;
    left: 1.5rem;
    font-family: var(--font-heading);
    font-size: var(--text-2xs);
    font-weight: 700;
    color: var(--text-inverse);
    z-index: 5;
    letter-spacing: var(--tracking-wider);
    background: rgba(var(--color-ink-rgb), 0.6);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    padding: 0.6rem 1rem;
    border-radius: var(--radius-pill);
    border: 1px solid var(--border-on-dark);
    transform: translateZ(0);
    transition: background 0.4s ease, border-color 0.4s ease, transform 0.4s ease;
}

.service-card:hover .service-card__number {
    background: var(--color-primary);
    border-color: transparent;
    transform: scale(1.05);
}

.service-card__image {
    position: absolute;
    inset: 0;
    z-index: var(--z-base);
    contain: strict;
}

/* El velo oscuro que hace legible el texto blanco sobre la foto.

   No se veia en NINGUNA tarjeta. Mas abajo, el zoom de las tarjetas
   ampliables pintaba su tinte rojo en este mismo ::after con un selector mas
   especifico, y como las ocho tarjetas son ampliables, el velo quedaba
   sustituido por un tinte a opacidad 0. En tactil, donde la descripcion esta
   siempre a la vista, eso era texto blanco directamente sobre la foto. El
   tinte vive ahora en ::before.

   Tampoco hay variante en hover: antes la habia, pero un degradado no se
   interpola, asi que su transition no hacia nada y el cambio pegaba un salto.
   La respuesta al hover la da el tinte rojo, que se anima por opacidad. */
.service-card__image::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg,
        rgba(var(--color-ink-rgb), 0.1) 0%,
        rgba(var(--color-ink-rgb), 0.2) 30%,
        rgba(var(--color-ink-rgb), 0.5) 60%,
        rgba(var(--color-ink-rgb), 0.95) 100%);
    z-index: var(--z-base);
}

.service-card__image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    transition: transform 0.6s var(--ease-out-expo);
    transform: translateZ(0);
}

.service-card:hover .service-card__image img {
    transform: scale(1.12);
}

.service-card__content {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 2rem;
    z-index: 3;
    transform: translateY(0);
    transition: transform 0.5s var(--ease-out-expo);
}

.service-card:hover .service-card__content {
    transform: translateY(-8px);
}

.service-card__title {
    font-family: var(--font-heading);
    font-size: clamp(1.4rem, 2vw, 1.8rem);
    font-weight: 700;
    letter-spacing: var(--tracking-snug);
    /* Clash Grotesk tiene un espacio estrecho, y con el tracking negativo en
       movil (17,5px) "Gestion y Mantenimiento" se leia como una sola palabra. */
    word-spacing: 0.08em;
    line-height: var(--leading-snug);
    margin-bottom: 0.75rem;
    color: var(--text-inverse);
    text-shadow: 0 2px 10px rgba(var(--color-ink-rgb), 0.3);
    transition: color 0.3s ease;
}

.service-card:hover .service-card__title {
    color: var(--text-inverse);
}

.service-card__desc {
    font-size: var(--text-sm);
    line-height: var(--leading-relaxed);
    color: var(--text-on-dark);
    margin-bottom: 1.5rem;
    opacity: 0;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.5s var(--ease-out-expo),
                opacity 0.5s var(--ease-out-expo);
    text-shadow: 0 1px 3px rgba(var(--color-ink-rgb), 0.4);
}

.service-card:hover .service-card__desc {
    opacity: 1;
    max-height: 120px;
}

.service-card__link {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    font-family: var(--font-primary);
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--text-inverse);
    text-decoration: none;
    opacity: 0;
    transform: translateY(10px);
    transition: background-color 0.4s var(--ease-out-expo),
                box-shadow 0.4s var(--ease-out-expo),
                opacity 0.4s var(--ease-out-expo),
                transform 0.4s var(--ease-out-expo);
    background: var(--color-primary);
    padding: 0.8rem 1.4rem;
    border-radius: var(--radius-pill);
    box-shadow: var(--glow-primary);
}

.service-card:hover .service-card__link {
    opacity: 1;
    transform: translateY(0);
}

.service-card__link:hover {
    background: var(--color-primary-hover);
    box-shadow: var(--glow-primary-strong);
    transform: translateY(-2px) !important;
}

.service-card__link svg {
    width: 16px;
    height: 16px;
    stroke: #fff;
    fill: none;
    stroke-width: 2;
    transition: transform 0.3s ease;
}

.service-card__link:hover svg {
    transform: translateX(4px);
}

/* Services Responsive */
@media (max-width: 1023px) {
    /* Quita la sangria extra de escritorio, pero no el relleno del contenedor:
       la cabecera tambien es .container, y el padding-left: 0 que habia aqui
       se lo llevaba por delante. En un movil de 375px el titular quedaba
       pegado al borde izquierdo con 24px de aire solo a la derecha. */
    .services-horizontal__header {
        text-align: center;
        padding-left: var(--container-pad);
    }
    
    .service-card {
        width: clamp(280px, 70vw, 350px);
        height: clamp(380px, 55vh, 480px);
        height: clamp(380px, 55svh, 480px);
    }
    
    .service-card__content {
        padding: 1.5rem;
    }
    
    .service-card__title {
        font-size: var(--text-md);
    }
}

/* Móvil: mostrar descripción y botón sin hover */
@media (max-width: 768px) {
    .service-card__desc,
    .service-card:hover .service-card__desc {
        opacity: 1 !important;
        max-height: 120px !important;
        overflow: visible !important;
    }
    
    .service-card__link,
    .service-card:hover .service-card__link {
        opacity: 1 !important;
        transform: translateY(0) !important;
    }
    
    .service-card__content {
        transform: translateY(-8px);
    }
    
    .service-card {
        width: clamp(260px, 75vw, 360px);
        height: clamp(380px, 58vh, 480px);
        height: clamp(380px, 58svh, 480px);
    }
}

@media (max-width: 600px) {
    .service-card {
        width: 75vw;
        height: clamp(340px, 52vh, 420px);
        height: clamp(340px, 52svh, 420px);
    }
    
    .services-horizontal__header {
        margin-bottom: 2rem;
    }
}

/* ========== STATS SECTION ========== */
.stats-section {
    position: relative;
    /* Era este mismo clamp escrito a mano. Al token, que es el que marca el
       ritmo del resto de secciones grandes. */
    padding: var(--section-gap-lg) 0;
    overflow: hidden;
    background: var(--surface-sunken);
    contain: layout style;
}

.stats-section::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 120px;
    background: linear-gradient(to bottom, var(--surface-sunken) 0%, transparent 100%);
    pointer-events: none;
    z-index: var(--z-elevated);
}

.stats-section::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 120px;
    background: linear-gradient(to top, var(--surface-sunken) 0%, transparent 100%);
    pointer-events: none;
    z-index: var(--z-elevated);
}

.stats-section__bg {
    position: absolute;
    inset: 0;
    z-index: 0;
    background: radial-gradient(ellipse 80% 60% at 50% 40%, rgba(255,107,107,0.08) 0%, transparent 70%);
}

.stats-section__overlay {
    position: absolute;
    inset: 0;
    z-index: var(--z-base);
    background: 
        radial-gradient(circle at 20% 80%, rgba(255,107,107,0.06) 0%, transparent 50%),
        radial-gradient(circle at 80% 20%, rgba(var(--color-ink-rgb), 0.04) 0%, transparent 50%);
    pointer-events: none;
    will-change: transform;
    transform: translateZ(0);
}

/* Stats floating shapes */
.stats-section__shapes {
    position: absolute;
    inset: 0;
    pointer-events: none;
    overflow: hidden;
    z-index: 0;
}

.stats-section__shape {
    position: absolute;
    border-radius: var(--radius-circle);
    filter: blur(60px);
    opacity: 0.5;
    will-change: transform;
    transform: translateZ(0);
}

.stats-section__shape--1 {
    width: 400px;
    height: 400px;
    background: rgba(255,107,107,0.15);
    top: -100px;
    right: -100px;
}

.stats-section__shape--2 {
    width: 300px;
    height: 300px;
    background: rgba(var(--color-ink-rgb), 0.08);
    bottom: -50px;
    left: -50px;
}

.stats-grid {
    display: grid;
    /* Tres, no cuatro: se cayeron las dos cifras que no se podian sostener. */
    grid-template-columns: repeat(3, 1fr);
    gap: 3rem;
    position: relative;
    z-index: 2;
}

.stat-item {
    text-align: center;
    /* Menos aire a los lados: con 2rem la columna se quedaba corta. */
    padding: 2rem 1rem;
    position: relative;
    /* La cifra y su simbolo son una sola unidad. Sin esto el % del 100 se caia
       a la linea de abajo y dejaba esa etiqueta un renglon mas baja que las
       otras tres. */
    white-space: nowrap;
}

.stat-item::after {
    content: '';
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 1px;
    height: 50%;
    background: rgba(var(--color-ink-rgb), 0.1);
}

.stat-item:last-child::after {
    display: none;
}

.stat-item__number {
    font-family: var(--font-heading);
    font-size: clamp(3rem, 8vw, 6rem);
    font-weight: 700;
    letter-spacing: -0.04em;
    line-height: var(--leading-none);
    display: inline;
    color: var(--color-ink);
    /* Cifras de ancho fijo. Sin esto el contador salta de ancho mientras
       cuenta -el 1 es mas estrecho que el 8- y arrastra a la etiqueta de al
       lado en cada fotograma. */
    font-variant-numeric: tabular-nums;
}

.stat-item__suffix {
    font-family: var(--font-heading);
    font-size: clamp(1.5rem, 4vw, 3rem);
    font-weight: 700;
    color: var(--color-primary);
}

.stat-item__label {
    display: block;
    /* El nowrap del padre es solo para la cifra: la etiqueta si puede partir. */
    white-space: normal;
    margin-top: 1rem;
    font-family: var(--font-accent);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--text-muted);
}

/* ========== PROCESS / COMO TRABAJAMOS ========== */
.process-section {
    /* Asimetrico a proposito: entra desde una seccion de fondo oscuro y
       necesita mas aire por arriba que por abajo para no parecer pegada. */
    padding-top: var(--section-gap-lg);
    padding-bottom: var(--section-gap);
    background: var(--surface-muted);
    position: relative;
    overflow: hidden;
}

/* Decorative background shapes */
.process-section__bg-shapes {
    position: absolute;
    inset: 0;
    pointer-events: none;
    overflow: hidden;
}

.process-section__bg-shape {
    position: absolute;
    border-radius: var(--radius-circle);
    filter: blur(80px);
    opacity: 0;
    transition: opacity 1.2s ease;
}

.process-section.is-visible .process-section__bg-shape {
    opacity: 1;
}

.process-section__bg-shape--1 {
    width: 500px;
    height: 500px;
    background: radial-gradient(circle, rgba(var(--color-primary-rgb), 0.06) 0%, transparent 70%);
    top: -100px;
    right: -150px;
}

.process-section__bg-shape--2 {
    width: 400px;
    height: 400px;
    background: radial-gradient(circle, rgba(78, 205, 196, 0.05) 0%, transparent 70%);
    bottom: -50px;
    left: -100px;
}

.process-section__bg-shape--3 {
    width: 300px;
    height: 300px;
    background: radial-gradient(circle, rgba(132, 94, 247, 0.04) 0%, transparent 70%);
    top: 40%;
    /* Centrada con calc y no con left:50% + translateX(-50%). El -50% lo ponia
       antes el @keyframes y ahora lo pondria GSAP, o sea que sin JS la mancha
       se quedaba 150px corrida. Asi el centrado es del CSS y no depende de
       nadie, y GSAP puede usar el transform entero para su vaiven. */
    left: calc(50% - 150px);
}




.process-section__header {
    text-align: center;
    margin-bottom: clamp(4rem, 8vh, 6rem);
    position: relative;
    z-index: 2;
}

.process-section__subtitle {
    font-size: clamp(1rem, 1.8vw, 1.15rem);
    color: var(--text-secondary);
    max-width: 500px;
    margin: 1.25rem auto 0;
    line-height: var(--leading-relaxed);
}

/* ========== TIMELINE LAYOUT ========== */
.process-timeline {
    position: relative;
    max-width: 900px;
    margin: 0 auto;
    padding-left: 40px;
}

/* Vertical timeline line */
.process-timeline__line {
    position: absolute;
    left: 15px;
    top: 0;
    bottom: 0;
    width: 2px;
    background: rgba(var(--color-primary-rgb), 0.1);
    border-radius: var(--radius-xs);
    z-index: var(--z-base);
}

.process-timeline__line-fill {
    width: 100%;
    /* Se anima `height` y no `transform: scaleY()`, que seria mas barato, porque
       el ::after de aqui abajo es el punto que marca el final del recorrido: un
       scaleY sobre el padre lo aplastaria y lo dejaria mal colocado. El coste de
       animar height aqui es asumible -es una barra de 4px dentro de un subarbol
       contenido- y ademas el JS ya solo actualiza esto mientras la seccion se ve,
       en vez de hacerlo siempre como antes. */
    height: 0%;
    background: linear-gradient(180deg, var(--color-primary), var(--color-primary-light));
    border-radius: var(--radius-xs);
    transition: height 0.1s linear;
    position: relative;
}

.process-timeline__line-fill::after {
    content: '';
    position: absolute;
    bottom: -4px;
    left: 50%;
    transform: translateX(-50%);
    width: 8px;
    height: 8px;
    border-radius: var(--radius-circle);
    background: var(--color-primary);
    box-shadow: 0 0 12px rgba(var(--color-primary-rgb), 0.5);
}

/* Each timeline item */
.process-timeline__item {
    position: relative;
    padding-bottom: clamp(2.5rem, 5vh, 4rem);
    opacity: 0;
    transform: translateY(40px);
}

.process-timeline__item:last-child {
    padding-bottom: 0;
}

.process-timeline__item.is-visible {
    opacity: 1;
    transform: translateY(0);
}

/* Timeline dot */
.process-timeline__dot {
    position: absolute;
    left: -33px;
    top: 2rem;
    width: 18px;
    height: 18px;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: center;
}

.process-timeline__dot-core {
    width: 12px;
    height: 12px;
    border-radius: var(--radius-circle);
    background: var(--surface-raised);
    border: 3px solid rgba(var(--color-primary-rgb), 0.3);
    transition: background-color 0.5s var(--ease-out-expo),
                border-color 0.5s var(--ease-out-expo),
                box-shadow 0.5s var(--ease-out-expo);
    position: relative;
    z-index: 2;
}

.process-timeline__item.is-visible .process-timeline__dot-core {
    background: var(--color-primary);
    border-color: var(--color-primary);
    box-shadow: 0 0 0 4px rgba(var(--color-primary-rgb), 0.15);
}

.process-timeline__dot-ping {
    position: absolute;
    inset: -4px;
    border-radius: var(--radius-circle);
    background: rgba(var(--color-primary-rgb), 0.2);
    opacity: 0;
    z-index: var(--z-base);
}



/* Timeline card */
.process-timeline__card {
    position: relative;
    margin-left: 1rem;
}

.process-timeline__card-glow {
    position: absolute;
    inset: -1px;
    border-radius: var(--radius-card);
    background: linear-gradient(135deg, 
        rgba(var(--color-primary-rgb), 0.15) 0%, 
        rgba(var(--color-primary-rgb), 0.0) 50%,
        rgba(78, 205, 196, 0.08) 100%);
    opacity: 0;
    transition: opacity 0.6s ease;
    z-index: 0;
    filter: blur(1px);
}

.process-timeline__card:hover .process-timeline__card-glow {
    opacity: 1;
}

.process-timeline__card-inner {
    position: relative;
    background: var(--surface-raised);
    border-radius: var(--radius-card);
    padding: clamp(2rem, 4vw, 2.5rem);
    box-shadow:
        0 1px 3px rgba(var(--color-ink-rgb), 0.03),
        0 8px 30px rgba(var(--color-ink-rgb), 0.05);
    border: 1px solid rgba(var(--color-ink-rgb), 0.05);
    transition: background-color 0.5s var(--ease-out-expo),
                border-color 0.5s var(--ease-out-expo),
                box-shadow 0.5s var(--ease-out-expo),
                color 0.5s var(--ease-out-expo),
                opacity 0.5s var(--ease-out-expo),
                transform 0.5s var(--ease-out-expo);
    overflow: hidden;
    z-index: var(--z-base);
}

.process-timeline__card-inner::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: linear-gradient(90deg, var(--color-primary), var(--color-primary-light), rgba(78, 205, 196, 0.6));
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.6s var(--ease-out-expo);
    border-radius: 24px 24px 0 0;
}

.process-timeline__item.is-visible .process-timeline__card-inner::before {
    transform: scaleX(1);
}

.process-timeline__card-inner:hover {
    box-shadow:
        0 1px 3px rgba(var(--color-ink-rgb), 0.03),
        0 20px 60px rgba(var(--color-ink-rgb), 0.08);
    transform: translateY(-4px);
    border-color: rgba(var(--color-primary-rgb), 0.1);
}

/* Card header with number and badge */
.process-timeline__card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1.5rem;
}

.process-timeline__number {
    font-family: var(--font-heading);
    font-size: clamp(2.5rem, 5vw, 3.5rem);
    font-weight: 700;
    line-height: var(--leading-none);
    letter-spacing: -0.04em;
    background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-light) 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.process-timeline__badge {
    font-family: var(--font-accent);
    font-size: var(--text-2xs);
    font-weight: 600;
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--color-primary);
    background: rgba(var(--color-primary-rgb), 0.08);
    padding: 0.4rem 1rem;
    border-radius: var(--radius-xl);
    border: 1px solid rgba(var(--color-primary-rgb), 0.12);
    opacity: 0;
    transform: translateX(10px);
    transition: opacity 0.5s var(--ease-out-expo) 0.3s,
                transform 0.5s var(--ease-out-expo) 0.3s;
}

.process-timeline__item.is-visible .process-timeline__badge {
    opacity: 1;
    transform: translateX(0);
}

/* Icon */
.process-timeline__icon-wrap {
    width: 56px;
    height: 56px;
    border-radius: var(--radius-lg);
    background: linear-gradient(135deg, rgba(var(--color-primary-rgb), 0.08) 0%, rgba(var(--color-primary-rgb), 0.03) 100%);
    border: 1px solid rgba(var(--color-primary-rgb), 0.1);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 1.25rem;
    transition: background-color 0.5s var(--ease-out-expo),
                opacity 0.5s var(--ease-out-expo),
                transform 0.5s var(--ease-out-expo);
    position: relative;
}

.process-timeline__icon-wrap::after {
    content: '';
    position: absolute;
    inset: -3px;
    border-radius: 19px;
    background: linear-gradient(135deg, rgba(var(--color-primary-rgb), 0.15), transparent 60%);
    opacity: 0;
    transition: opacity 0.4s ease;
    z-index: var(--z-below);
}

.process-timeline__card-inner:hover .process-timeline__icon-wrap {
    background: linear-gradient(135deg, rgba(var(--color-primary-rgb), 0.12) 0%, rgba(var(--color-primary-rgb), 0.06) 100%);
    transform: scale(1.08) rotate(-3deg);
}

.process-timeline__card-inner:hover .process-timeline__icon-wrap::after {
    opacity: 1;
}

.process-timeline__icon-wrap svg {
    width: 26px;
    height: 26px;
    color: var(--color-primary);
    transition: transform 0.4s ease;
}

.process-timeline__card-inner:hover .process-timeline__icon-wrap svg {
    transform: scale(1.1);
}

/* Title */
.process-timeline__title {
    font-family: var(--font-heading);
    font-size: clamp(1.3rem, 2.5vw, 1.6rem);
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: 0.75rem;
    line-height: var(--leading-snug);
    transition: color 0.3s ease;
}

.process-timeline__card-inner:hover .process-timeline__title {
    color: var(--color-primary-dark);
}

/* Text */
.process-timeline__text {
    font-size: clamp(0.92rem, 1.5vw, 1.05rem);
    color: var(--text-secondary);
    line-height: var(--leading-relaxed);
    max-width: 520px;
    margin-bottom: 1.25rem;
}

/* Tags */
.process-timeline__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.process-timeline__tag {
    font-family: var(--font-accent);
    /* Estaba a pelo en 0.72rem, 11.5px. Pasa al token, que ya no baja de 12. */
    font-size: var(--text-2xs);
    font-weight: 500;
    color: var(--text-secondary);
    background: var(--surface-muted);
    padding: 0.35rem 0.85rem;
    border-radius: var(--radius-xl);
    border: 1px solid rgba(var(--color-ink-rgb), 0.04);
    transition: background-color 0.3s ease,
                border-color 0.3s ease,
                color 0.3s ease,
                opacity 0.3s ease,
                transform 0.3s ease;
    opacity: 0;
    transform: translateY(8px);
}

.process-timeline__item.is-visible .process-timeline__tag {
    opacity: 1;
    transform: translateY(0);
}

.process-timeline__item.is-visible .process-timeline__tag:nth-child(1) { transition-delay: 0.4s; }
.process-timeline__item.is-visible .process-timeline__tag:nth-child(2) { transition-delay: 0.5s; }
.process-timeline__item.is-visible .process-timeline__tag:nth-child(3) { transition-delay: 0.6s; }

.process-timeline__card-inner:hover .process-timeline__tag {
    background: rgba(var(--color-primary-rgb), 0.06);
    border-color: rgba(var(--color-primary-rgb), 0.1);
    color: var(--color-primary-dark);
}

/* ========== PROCESS RESPONSIVE ========== */
@media (max-width: 768px) {
    /* Remove timeline line and dots — cards only */
    .process-timeline {
        padding-left: 0;
    }
    
    .process-timeline__line,
    .process-timeline__dot {
        display: none;
    }
    
    .process-timeline__card {
        margin-left: 0;
    }

    .process-timeline__card-inner {
        padding: 1.5rem;
    }
    
    .process-timeline__icon-wrap {
        width: 46px;
        height: 46px;
        border-radius: var(--radius-md);
    }

    .process-timeline__icon-wrap svg {
        width: 22px;
        height: 22px;
    }
    
    .process-section__bg-shape--1,
    .process-section__bg-shape--3 {
        display: none;
    }
}

@media (max-width: 480px) {
    .process-section {
        padding-top: clamp(4rem, 10vh, 8rem);
        padding-bottom: clamp(4rem, 8vh, 6rem);
    }

    .process-timeline__card-inner {
        padding: 1.25rem;
    }

    .process-timeline__number {
        font-size: var(--text-xl);
    }

    .process-timeline__icon-wrap {
        width: 40px;
        height: 40px;
    }

    .process-timeline__icon-wrap svg {
        width: 18px;
        height: 18px;
    }
    
    .process-timeline__badge {
        font-size: var(--text-2xs);
        padding: 0.3rem 0.7rem;
    }
    
    .process-timeline__tags {
        gap: 0.35rem;
    }
    
    .process-timeline__tag {
        font-size: var(--text-2xs);
        padding: 0.25rem 0.65rem;
    }
}

/* ========== COMPARISON SECTION ========== */
.comparison-section {
    padding: var(--section-gap) 0;
    background: var(--surface-sunken);
    position: relative;
    overflow: hidden;
}

.comparison-section__header {
    text-align: center;
    margin-bottom: clamp(3rem, 6vw, 5rem);
}

.comparison-section__subtitle {
    font-size: clamp(1rem, 2vw, 1.15rem);
    color: rgba(var(--color-ink-rgb), 0.6);
    margin-top: 1.5rem;
    max-width: 500px;
    margin-left: auto;
    margin-right: auto;
    line-height: var(--leading-normal);
}

.comparison-slider {
    max-width: 1000px;
    margin: 0 auto;
}

.comparison-slider__container {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 10;
    border-radius: var(--radius-card);
    overflow: hidden;
    box-shadow: 0 25px 80px rgba(var(--color-ink-rgb), 0.15);
    cursor: ew-resize;
    -webkit-user-select: none;
    user-select: none;
    touch-action: pan-y pinch-zoom;
    contain: layout paint;
}

/* Imagen Después - Capa inferior (siempre visible a la derecha) */
.comparison-slider__after {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: var(--z-base);
}

.comparison-slider__after img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    pointer-events: none;
    transform: translateZ(0);
}

/* Imagen Antes - Capa superior (se recorta con clip-path) */
.comparison-slider__before {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 2;
    clip-path: inset(0 50% 0 0);
    will-change: clip-path;
    backface-visibility: hidden;
}

.comparison-slider__before img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    pointer-events: none;
    transform: translateZ(0);
}

.comparison-slider__label {
    position: absolute;
    top: clamp(1rem, 3vw, 1.5rem);
    padding: 0.5rem 1.25rem;
    font-family: var(--font-accent);
    /* Estaba a pelo y a 768 px bajaba a 11,5. Al token, que tiene suelo de 12. */
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    border-radius: var(--radius-pill);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    z-index: 5;
    pointer-events: none;
    transform: translateZ(0);
    isolation: isolate;
}

.comparison-slider__label--before {
    left: clamp(1rem, 3vw, 1.5rem);
    background: rgba(var(--color-ink-rgb), 0.85);
    color: var(--text-inverse);
}

.comparison-slider__label--after {
    right: clamp(1rem, 3vw, 1.5rem);
    background: rgba(var(--color-primary-rgb), 0.9);
    color: var(--text-inverse);
}

.comparison-slider__handle {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    width: 50px;
    margin-left: -25px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    z-index: var(--z-elevated);
    cursor: ew-resize;
    will-change: left;
    backface-visibility: hidden;
}

.comparison-slider__handle-line {
    flex: 1;
    width: 4px;
    background: linear-gradient(180deg, 
        rgba(255, 255, 255, 0.3) 0%,
        #fff 15%,
        #fff 85%,
        rgba(255, 255, 255, 0.3) 100%);
    box-shadow: 
        0 0 20px rgba(var(--color-ink-rgb), 0.3),
        0 0 40px rgba(var(--color-primary-rgb), 0.15);
    border-radius: var(--radius-sm);
    position: relative;
}

.comparison-slider__handle-line::before,
.comparison-slider__handle-line::after {
    content: '';
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    width: 8px;
    height: 8px;
    background: var(--surface-raised);
    border-radius: var(--radius-circle);
    box-shadow: 0 0 10px rgba(var(--color-primary-rgb), 0.4);
}

.comparison-slider__handle-line::before {
    top: 0;
}

.comparison-slider__handle-line::after {
    bottom: 0;
}

.comparison-slider__handle-circle {
    width: clamp(48px, 9vw, 60px);
    height: clamp(48px, 9vw, 60px);
    background: linear-gradient(145deg, #ffffff 0%, #f0f0f0 100%);
    border-radius: var(--radius-circle);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    box-shadow: 
        0 4px 20px rgba(var(--color-ink-rgb), 0.25),
        0 8px 40px rgba(var(--color-primary-rgb), 0.15),
        inset 0 2px 4px rgba(255, 255, 255, 0.9),
        inset 0 -2px 4px rgba(var(--color-ink-rgb), 0.05);
    transition: transform 0.2s var(--ease-spring), 
                box-shadow 0.2s ease;
    flex-shrink: 0;
    border: 3px solid rgba(var(--color-primary-rgb), 0.2);
    position: relative;
}

/* El giro lo lleva GSAP, pero a un pseudo-elemento no llega: anima la variable
   sobre el circulo de verdad y aqui se lee. Sin JS se queda quieto en 0deg, que
   es un aro discontinuo perfectamente presentable. */
.comparison-slider__handle-circle::before {
    content: '';
    position: absolute;
    inset: -6px;
    border-radius: var(--radius-circle);
    border: 2px dashed rgba(var(--color-primary-rgb), 0.3);
    transform: rotate(calc(var(--giro-borde, 0) * 1deg));
}


.comparison-slider__handle-circle:hover {
    transform: scale(1.12);
    box-shadow: 
        0 6px 30px rgba(var(--color-ink-rgb), 0.3),
        0 12px 50px rgba(var(--color-primary-rgb), 0.25),
        inset 0 2px 4px rgba(255, 255, 255, 0.9),
        inset 0 -2px 4px rgba(var(--color-ink-rgb), 0.05);
    border-color: rgba(var(--color-primary-rgb), 0.4);
}

.comparison-slider__handle-circle svg {
    width: clamp(16px, 3.5vw, 20px);
    height: clamp(16px, 3.5vw, 20px);
    stroke: var(--color-primary);
    stroke-width: 2.5;
    filter: drop-shadow(0 1px 2px rgba(var(--color-primary-rgb), 0.3));
    transition: transform 0.2s ease;
}

.comparison-slider__handle-circle:hover svg {
    transform: scale(1.1);
}

.comparison-slider__container.is-dragging .comparison-slider__handle-circle {
    transform: scale(1.18);
    box-shadow: 
        0 8px 35px rgba(var(--color-primary-rgb), 0.45),
        0 0 0 4px rgba(var(--color-primary-rgb), 0.15);
    border-color: var(--color-primary);
}

/* Comparison Responsive */
@media (max-width: 768px) {
    .comparison-slider__container {
        aspect-ratio: 4 / 3;
        contain: style;
        min-height: 40vh;
        min-height: 40svh;
    }
    
    
    
    .comparison-slider__handle-circle {
        width: 48px;
        height: 48px;
    }
    
    .comparison-slider__handle-circle::before {
        inset: -4px;
    }
    
    .comparison-slider__handle-circle svg {
        width: 16px;
        height: 16px;
    }
    
    .comparison-slider__handle-line::before,
    .comparison-slider__handle-line::after {
        width: 6px;
        height: 6px;
    }
}

@media (max-width: 480px) {
    .comparison-section {
        padding: clamp(4rem, 10vh, 8rem) 0;
    }
    
    .comparison-slider__container {
        aspect-ratio: 3 / 4;
        border-radius: var(--radius-lg);
        contain: style;
        min-height: 50vh;
        min-height: 50svh;
    }
    
    .comparison-slider__label {
        top: 0.75rem;
        padding: 0.4rem 0.9rem;
        font-size: var(--text-2xs);
    }
    
    .comparison-slider__label--before {
        left: 0.75rem;
    }
    
    .comparison-slider__label--after {
        right: 0.75rem;
    }
}

/* ========== FAQ SECTION ========== */
.faq-section {
    padding: var(--section-gap) 0;
    background: var(--surface-raised);
    position: relative;
}

.faq-section::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 120px;
    background: linear-gradient(to bottom, #fff 0%, transparent 100%);
    pointer-events: none;
    z-index: 2;
}

.faq-section__header {
    text-align: center;
    margin-bottom: 4rem;
}

.faq-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 2rem;
    max-width: 1100px;
    margin: 0 auto;
}

.faq-item {
    background: #f8f9fa;
    border-radius: var(--radius-lg);
    padding: 2rem;
    transition: background-color 0.3s ease,
                box-shadow 0.3s ease,
                transform 0.3s ease;
    border: 1px solid rgba(var(--color-ink-rgb), 0.05);
}

.faq-item:hover {
    background: var(--surface-raised);
    box-shadow: 0 10px 40px rgba(var(--color-ink-rgb), 0.08);
    transform: translateY(-3px);
}

.faq-item__question {
    font-family: var(--font-heading);
    font-size: var(--text-md);
    font-weight: 600;
    color: var(--color-ink);
    margin-bottom: 1rem;
    line-height: var(--leading-snug);
}

.faq-item__answer p {
    font-size: var(--text-sm);
    line-height: var(--leading-relaxed);
    color: var(--text-secondary);
}

@media (max-width: 768px) {
    .faq-grid {
        grid-template-columns: 1fr;
    }
}

/* ========== CTA SECTION ========== */
.cta-section {
    padding: var(--section-gap-lg) 0;
    background: var(--surface-muted);
    position: relative;
}

.cta-section::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 120px;
    background: linear-gradient(to bottom, var(--surface-muted) 0%, transparent 100%);
    pointer-events: none;
    z-index: 2;
}

.cta-section__wrapper {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 5rem;
    align-items: start;
}

.cta-section__content {
    padding-right: 2rem;
}

.cta-section__title {
    font-family: var(--font-heading);
    font-size: clamp(2rem, 5vw, 3.5rem);
    font-weight: 700;
    line-height: var(--leading-tight);
    letter-spacing: var(--tracking-tight);
    margin-bottom: 1.5rem;
    color: var(--color-ink);
}

.cta-section__title .word {
    display: inline-block;
    overflow: hidden;
}

.cta-section__title .word-inner {
    display: inline-block;
}

.cta-section__desc {
    font-size: var(--text-md);
    line-height: var(--leading-relaxed);
    color: rgba(var(--color-ink-rgb), 0.6);
    margin-bottom: 3rem;
    max-width: 450px;
}

.cta-section__info {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.cta-section__info-item {
    display: flex;
    align-items: center;
    gap: 1rem;
    color: var(--text-secondary);
    font-size: var(--text-sm);
}

.cta-section__info-item svg {
    width: 20px;
    height: 20px;
    stroke: var(--color-primary);
    flex-shrink: 0;
}

.cta-section__info-item a:hover {
    color: var(--color-primary);
}

/* ========== CONTACT FORM ========== */
/* Solo se ve sin JavaScript: el formulario no puede enviarse y se ofrecen
   las alternativas. */
.contact-form__noscript {
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    color: var(--text-secondary);
    margin-bottom: 1.5rem;
}

.contact-form__noscript a {
    color: var(--color-primary);
}

.contact-form {
    background: var(--surface-raised);
    border: 1px solid rgba(var(--color-ink-rgb), 0.06);
    padding: clamp(2rem, 4vw, 3.5rem);
    border-radius: var(--radius-xl);
    box-shadow: 0 20px 60px rgba(var(--color-ink-rgb), 0.06);
}

.contact-form__group {
    position: relative;
    margin-bottom: 2rem;
}

.contact-form__input,
.contact-form__textarea {
    width: 100%;
    padding: 1.25rem 0 0.75rem;
    background: transparent;
    border: none;
    border-bottom: 2px solid rgba(var(--color-ink-rgb), 0.1);
    color: var(--color-ink);
    font-size: var(--text-base);
    font-family: inherit;
    outline: none;
    transition: border-color 0.3s ease;
}

.contact-form__input:focus,
.contact-form__textarea:focus {
    border-color: var(--color-primary);
}

.contact-form__textarea {
    resize: none;
    min-height: 120px;
}

.contact-form__label {
    position: absolute;
    left: 0;
    top: 1rem;
    font-size: var(--text-sm);
    color: var(--text-muted);
    pointer-events: none;
    transition: color 0.3s var(--ease-out-expo),
                font-size 0.3s var(--ease-out-expo),
                letter-spacing 0.3s var(--ease-out-expo),
                top 0.3s var(--ease-out-expo);
}

.contact-form__input:focus + .contact-form__label,
.contact-form__input:not(:placeholder-shown) + .contact-form__label,
.contact-form__textarea:focus + .contact-form__label,
.contact-form__textarea:not(:placeholder-shown) + .contact-form__label {
    top: -0.5rem;
    font-size: var(--text-2xs);
    color: var(--color-primary);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    font-weight: 600;
}

.contact-form__line {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 0;
    height: 2px;
    background: var(--color-primary);
    transition: width 0.5s var(--ease-out-expo);
}

.contact-form__input:focus ~ .contact-form__line,
.contact-form__textarea:focus ~ .contact-form__line {
    width: 100%;
}

.contact-form__submit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    width: 100%;
    padding: 1.25rem 2.5rem;
    background: var(--color-ink);
    color: var(--text-inverse);
    font-family: var(--font-accent);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    margin-top: 1rem;
    border-radius: var(--radius-pill);
    transition: box-shadow 0.5s var(--ease-out-expo),
                transform 0.5s var(--ease-out-expo);
    position: relative;
    overflow: hidden;
    box-shadow: 0 4px 20px rgba(var(--color-ink-rgb), 0.2);
}

.contact-form__submit::before {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--color-primary);
    transform: translateY(101%);
    transition: transform 0.5s var(--ease-out-expo);
    border-radius: var(--radius-pill);
}

.contact-form__submit:hover::before {
    transform: translateY(0);
}

.contact-form__submit:hover {
    box-shadow: var(--glow-primary);
}

.contact-form__submit span,
.contact-form__submit svg {
    position: relative;
    z-index: 2;
    transition: color 0.3s ease;
}

.contact-form__submit svg {
    width: 18px;
    height: 18px;
    stroke: currentColor;
    fill: none;
}

/* ========== FORMULARIO: HONEYPOT Y VERIFICACIÓN ========== */

/* Trampa anti-spam (honeypot): fuera de pantalla y no con display:none, porque
   hay bots que se saltan los campos ocultos con display:none. A los lectores de
   pantalla no les llega por el aria-hidden del HTML, y al tabulador tampoco por
   su tabindex="-1". Si llega relleno, la funcion responde ok sin enviar. */
.contact-form__trampa {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.contact-form__trampa label {
    display: none;
}

.contact-form__trampa input {
    position: absolute;
    left: -9999px;
}

/* Widget de Turnstile */
.contact-form__verificacion {
    margin: 1.5rem 0;
}

/* Información de privacidad básica (LOPDGDD art. 11).
   Texto pequeño pero legible, con contraste >= 4.5. */
.contact-form__privacidad {
    font-size: var(--text-xs);
    line-height: var(--leading-snug);
    color: var(--text-secondary);
    margin: 1.5rem 0;
}

.contact-form__privacidad a,
.contact-form__privacidad a:link,
.contact-form__privacidad a:visited,
.contact-form__privacidad a:any-link {
    color: var(--color-primary-text);
    text-decoration: underline;
    transition: color 0.3s ease;
}

.contact-form__privacidad a:hover,
.contact-form__privacidad a:focus-visible,
.contact-form__privacidad a:active {
    color: var(--color-primary);
}

/* Estado del formulario: mensajes de validación y éxito.
   aria-live="polite" anuncia cambios a lectores de pantalla. */
.contact-form__estado {
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
    color: var(--text-primary);
    margin-top: 1rem;
    min-height: 1.4em;
}

/* ========== POPUP DE CONTACTO ACCESIBLE ========== */

/* El popup se oculta con display: none cuando tiene [hidden],
   garantizado con !important por si hay estilos en línea. */
.contact-popup[hidden] {
    display: none !important;
}

/* ========== TARJETA DE SERVICIO: BOTÓN ZOOM ========== */

/* El botón de ampliar es un <button> que se estila como el ícono
   anterior pero con foco visible. */
.service-card__zoom-icon {
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    cursor: pointer;
    color: inherit;
    font: inherit;
    appearance: none;
    transition: transform 0.3s ease, color 0.3s ease;
}

.service-card__zoom-icon:hover,
.service-card__zoom-icon:focus-visible {
    transform: scale(1.1);
    color: var(--color-primary);
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.service-card__zoom-icon:active {
    transform: scale(0.95);
}

/* ========== FUERA DE VISTA: PAUSAR ANIMACIONES ========== */

/* ========== PÁGINAS LEGALES ========== */

/* Campo pendiente de completar (dato obligatorio que falta). */
.legal-page__pendiente {
    display: inline;
    padding: 0.2em 0.4em;
    background: var(--color-primary-text);
    color: #fff;
    border-radius: var(--radius-sm);
    font-size: 0.9em;
    font-weight: 600;
    white-space: nowrap;
}

/* Fecha de los textos legales (información de art. 13 RGPD). */
.legal-page__date {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    display: block;
    margin-top: 1rem;
}

/* ========== FOOTER MODERNO ========== */
.footer {
    background: var(--color-ink-deep);
    color: var(--text-on-dark-soft);
    position: relative;
    overflow: hidden;
}

.footer::before {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 80%;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent);
}

/* Footer CTA Section */
.footer__cta {
    padding: clamp(6rem, 12vh, 12rem) 0;
    text-align: center;
    position: relative;
}

.footer__cta-title {
    font-family: var(--font-heading);
    font-size: clamp(2.5rem, 8vw, 6rem);
    font-weight: 700;
    line-height: var(--leading-none);
    letter-spacing: var(--tracking-tight);
    color: var(--text-inverse);
    margin-bottom: 2rem;
}

.footer__cta-title em {
    font-style: normal;
    background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-soft) 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.footer__cta-btn {
    display: inline-flex;
    align-items: center;
    gap: 1rem;
    padding: 1.25rem 2.5rem;
    background: var(--color-primary);
    color: var(--text-inverse);
    font-family: var(--font-primary);
    font-size: var(--text-base);
    font-weight: 600;
    border-radius: var(--radius-pill);
    transition: color 0.5s var(--ease-out-expo),
                transform 0.5s var(--ease-out-expo);
    position: relative;
    overflow: hidden;
}

.footer__cta-btn::before {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--surface-raised);
    transform: translateY(101%);
    transition: transform 0.5s var(--ease-out-expo);
    border-radius: var(--radius-pill);
}

.footer__cta-btn:hover::before {
    transform: translateY(0);
}

.footer__cta-btn:hover {
    color: var(--color-ink);
}

.footer__cta-btn span,
.footer__cta-btn svg {
    position: relative;
    z-index: 2;
}

.footer__cta-btn svg {
    width: 20px;
    height: 20px;
    stroke: currentColor;
    fill: none;
    transition: transform 0.3s ease;
}

.footer__cta-btn:hover svg {
    transform: translateX(5px);
}

/* Footer Main Content */
.footer__main {
    padding: 4rem 0;
    border-top: 1px solid rgba(255,255,255,0.06);
    border-bottom: 1px solid rgba(255,255,255,0.06);
}

.footer__grid {
    display: grid;
    grid-template-columns: 1.5fr 1fr 1fr 1.5fr;
    gap: 4rem;
    max-width: 1440px;
    margin: 0 auto;
    padding: 0 clamp(1.5rem, 5vw, 5rem);
}

.footer__brand {
    position: relative;
}

.footer__brand-logo {
    margin-bottom: 1.5rem;
}

.footer__brand-logo img {
    height: 40px;
    width: auto;
}

.footer__brand p {
    font-size: var(--text-sm);
    color: var(--text-on-dark-muted);
    line-height: var(--leading-relaxed);
    max-width: 280px;
    margin-bottom: 2rem;
}

.footer__social {
    display: flex;
    gap: 0.75rem;
}

.footer__social-link {
    width: 42px;
    height: 42px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255,255,255,0.05);
    border-radius: var(--radius-circle);
    color: var(--text-on-dark-soft);
    transition: color 0.4s var(--ease-out-expo), background 0.4s var(--ease-out-expo), transform 0.4s var(--ease-out-expo), box-shadow 0.4s var(--ease-out-expo);
}

.footer__social-link:visited {
    color: var(--text-on-dark-soft);
}

.footer__social-link svg {
    width: 18px;
    height: 18px;
}

.footer__social-link:hover {
    background: var(--color-primary);
    color: var(--text-inverse);
    transform: translateY(-4px) rotate(5deg);
    box-shadow: var(--glow-primary-strong);
}

.footer__column {
    padding-top: 0.5rem;
}

.footer__column h4 {
    font-family: var(--font-primary);
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    margin-bottom: 1.5rem;
    color: var(--text-on-dark-muted);
}

.footer__links {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
}

.footer__link,
.footer__link:link,
.footer__link:visited,
.footer__link:any-link {
    font-size: var(--text-sm);
    color: rgba(255,255,255,0.7) !important;
    transition: color 0.3s ease;
    position: relative;
    display: inline-block;
    width: fit-content;
    text-decoration: none;
}

.footer__link::after {
    content: '';
    position: absolute;
    bottom: -2px;
    left: 0;
    width: 0;
    height: 1px;
    background: var(--color-primary);
    transition: width 0.4s var(--ease-out-expo);
}

.footer__link:hover,
.footer__link:focus-visible,
.footer__link:active {
    color: #fff !important;
}

.footer__link:hover::after,
.footer__link:focus-visible::after {
    width: 100%;
}

.footer__contact-item {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    margin-bottom: 1.25rem;
    font-size: var(--text-sm);
    color: var(--text-on-dark-soft);
    transition: color 0.3s ease;
}

.footer__contact-item svg {
    width: 18px;
    height: 18px;
    stroke: var(--color-primary);
    flex-shrink: 0;
    margin-top: 0.15rem;
}

.footer__contact-item a,
.footer__contact-item a:link,
.footer__contact-item a:visited,
.footer__contact-item a:any-link {
    color: rgba(255,255,255,0.6) !important;
    transition: color 0.3s ease;
}

.footer__contact-item:hover,
.footer__contact-item a:hover {
    color: #fff !important;
}

/* Footer Bottom */
.footer__bottom {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 2rem clamp(1.5rem, 5vw, 5rem);
    max-width: 1440px;
    margin: 0 auto;
    flex-wrap: wrap;
    gap: 1rem;
}

.footer__copyright {
    font-size: var(--text-xs);
    color: var(--text-on-dark-muted);
}

.footer__legal {
    display: flex;
    gap: 2rem;
}

.footer__legal a,
.footer__legal a:link,
.footer__legal a:visited,
.footer__legal a:any-link {
    font-size: var(--text-xs);
    /* Al 35 % de antes el contraste era de unos 3:1 y no llegaba al minimo de
       4,5:1. Al 72 % pasa de 9:1 y el pie sigue siendo discreto. No hace falta
       subrayado: son enlaces sueltos, no dentro de un parrafo. */
    color: rgba(255,255,255,0.72) !important;
    transition: color 0.3s ease;
}

.footer__legal a:hover {
    color: var(--color-primary) !important;
}

.footer__developer {
    font-size: var(--text-xs);
    color: rgba(255,255,255,0.25);
}

.footer__developer a,
.footer__developer a:link,
.footer__developer a:visited,
.footer__developer a:any-link {
    color: rgba(255,255,255,0.72) !important;
    transition: color 0.3s ease;
}

.footer__developer a:hover {
    color: var(--color-primary) !important;
}

/* Footer Marquee */
.footer__marquee {
    padding: 1.5rem 0;
    background: rgba(255,255,255,0.02);
    overflow: hidden;
    border-top: 1px solid rgba(255,255,255,0.04);
}

.footer__marquee-track {
    display: flex;
}

.footer__marquee-content {
    display: flex;
    align-items: center;
    gap: 3rem;
    padding-right: 3rem;
    white-space: nowrap;
}

.footer__marquee-item {
    font-family: var(--font-heading);
    font-size: clamp(1rem, 2vw, 1.5rem);
    font-weight: 600;
    color: rgba(255,255,255,0.15);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.footer__marquee-dot {
    width: 6px;
    height: 6px;
    background: var(--color-primary);
    border-radius: var(--radius-circle);
    opacity: 0.5;
}


/* ========== MAGNETIC BUTTON ========== */
.magnetic-btn {
    will-change: transform;
}

/* ========== RESPONSIVE ========== */
@media (max-width: 1200px) {
    .stats-grid {
        /* Con tres cifras siguen cabiendo las tres en fila hasta el movil, asi
           que no hace falta pasar a dos columnas ni esconder divisorias. */
        gap: 2rem;
    }
    
    .cta-section__wrapper {
        gap: 3rem;
    }
}

@media (max-width: 1023px) {
    
    body.nav-open {
        overflow: hidden;
    }
    
    .cta-section__wrapper {
        grid-template-columns: 1fr;
    }
    
    .footer__grid {
        grid-template-columns: 1fr 1fr;
    }

    /* Aqui habia una CUARTA regla de tamano para .service-card, y estaba
       matando a las otras tres.

       El tamano de la tarjeta se decide en una escalera de tres escalones
       -1023px, 768px y 600px- que vive junto al componente, unas 1.600 lineas
       mas arriba. Esta regla suelta tenia la misma especificidad y venia
       DESPUES en el fichero, asi que ganaba en TODO el rango: tambien por
       debajo de 768 y por debajo de 600, donde los otros dos escalones nunca
       llegaron a aplicarse.

       En un movil de 375px la tarjeta salia de 320x450 en vez de los 281x347
       que pide la escalera: casi la pantalla entera, sin dejar asomar la
       siguiente tarjeta, que es justo la pista de que el carrusel se desliza. */
}

@media (max-width: 768px) {
    .hero__bottom {
        flex-direction: column;
        align-items: flex-start;
    }
    
    .hero__counter {
        text-align: left;
    }
    
    .hero__scroll-hint {
        display: none;
    }
    
    .stats-grid {
        grid-template-columns: 1fr;
    }
    
    .stat-item::after {
        display: none;
    }
    
    .footer__grid {
        grid-template-columns: 1fr;
        gap: 2.5rem;
    }
    
    .footer__bottom {
        flex-direction: column;
        gap: 1rem;
        text-align: center;
    }
}

@media (max-width: 480px) {
    .section-title {
        font-size: clamp(2rem, 10vw, 3rem);
    }
    
    .hero__title {
        font-size: clamp(2.5rem, 14vw, 4rem);
    }
    
    .contact-form {
        padding: 1.5rem;
    }
}

/* ================================================================
   RED DE SEGURIDAD Y AJUSTES TRANSVERSALES
   ================================================================
   Aqui vivia una tira de nueve bloques -"VISIBILITY FIXES",
   "IMPROVED SERVICE CARDS", "ENHANCED SCROLL PROGRESS", "PRELOADER POLISH"...-
   que volvian a declarar selectores ya definidos 2.000 lineas mas arriba. El
   problema no era el tamano: era que para saber que ancho acababa teniendo la
   barra de progreso habia que leer las dos definiciones y decidir cual ganaba.

   Cada uno de esos ajustes se ha subido a la seccion que le corresponde. Lo
   que queda aqui es lo que de verdad es transversal y no pertenece a ninguna.
   ================================================================ */

/* Los elementos que animamos con GSAP arrancan invisibles. Si un ScrollTrigger
   no llega a dispararse, esta regla es lo unico que evita que la seccion se
   quede en blanco. Cada init tiene ademas su propio failsafe por temporizador;
   esto es el ultimo recurso.
   .stat-item queda fuera a proposito: lo controla su ScrollTrigger. */
.service-card,
.footer__brand,
.footer__column {
    visibility: visible !important;
}

/* Lenis pide desactivar los eventos de puntero sobre los iframes mientras hay
   scroll en curso; si no, el iframe se traga el gesto y el scroll se corta. */
.lenis.lenis-scrolling iframe {
    pointer-events: none;
}

/* Contexto de apilado propio para cada seccion, para que los adornos de fondo
   de una no se cuelen sobre la siguiente. */
section {
    position: relative;
}

/* Promocion a capa de GPU de lo unico que se mueve de forma continua.
   Se aplica a mano y no a todo: cada capa promovida ocupa memoria de video, y
   repartirla a discrecion empeora el rendimiento en vez de mejorarlo. */
.hero__content,
.service-card {
    transform: translateZ(0);
    backface-visibility: hidden;
}


/* Responsive */

/* ========== LEGAL PAGES ========== */
.legal-page {
    padding: clamp(8rem, 15vh, 12rem) 0 clamp(4rem, 8vh, 8rem);
    background: var(--surface-page);
    min-height: 100vh;
    min-height: 100dvh;
}

.legal-page__header {
    margin-bottom: 4rem;
    text-align: center;
}

.legal-page__title {
    font-family: var(--font-heading);
    font-size: clamp(2.5rem, 6vw, 4rem);
    font-weight: 700;
    color: var(--color-ink);
    letter-spacing: var(--tracking-snug);
    margin-bottom: 1rem;
}

.legal-page__content {
    max-width: 800px;
    margin: 0 auto;
    background: var(--surface-raised);
    border-radius: var(--radius-xl);
    padding: clamp(2rem, 5vw, 4rem);
    box-shadow: 0 4px 40px rgba(var(--color-ink-rgb), 0.04);
}

.legal-page__content h2 {
    font-family: var(--font-heading);
    font-size: var(--text-lg);
    font-weight: 600;
    color: var(--color-ink);
    margin: 2.5rem 0 1rem;
    padding-top: 1.5rem;
    border-top: 1px solid rgba(var(--color-ink-rgb), 0.06);
}

.legal-page__content h2:first-child {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
}

.legal-page__content h3 {
    font-family: var(--font-heading);
    font-size: var(--text-md);
    font-weight: 600;
    color: var(--color-ink);
    margin: 1.5rem 0 0.75rem;
}

.legal-page__content p {
    font-size: var(--text-base);
    line-height: var(--leading-relaxed);
    color: var(--text-secondary);
    margin-bottom: 1rem;
}

.legal-page__content ul,
.legal-page__content ol {
    margin: 1rem 0 1.5rem;
    padding-left: 1.5rem;
}

.legal-page__content li {
    font-size: var(--text-base);
    line-height: var(--leading-relaxed);
    color: var(--text-secondary);
    margin-bottom: 0.5rem;
}

.legal-page__content a {
    color: var(--color-primary);
    text-decoration: underline;
}

.legal-page__content strong {
    font-weight: 600;
    color: var(--color-ink);
}

.legal-page__back {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 3rem;
    padding: 0.875rem 1.5rem;
    background: rgba(var(--color-ink-rgb), 0.04);
    color: var(--color-ink);
    font-size: var(--text-sm);
    font-weight: 500;
    border-radius: var(--radius-pill);
    transition: background-color 0.3s ease,
                color 0.3s ease,
                transform 0.3s ease;
}

.legal-page__back svg {
    width: 16px;
    height: 16px;
    stroke: currentColor;
    fill: none;
    transition: transform 0.3s ease;
}

.legal-page__back:hover {
    background: var(--color-primary);
    color: var(--text-inverse);
}

.legal-page__back:hover svg {
    transform: translateX(-3px);
}

.legal-page__container {
    width: 100%;
    max-width: 1000px;
    margin: 0 auto;
    padding: 0 clamp(1.5rem, 5vw, 3rem);
}

.legal-page__date {
    font-size: var(--text-sm);
    color: var(--text-muted);
    margin-top: 0.5rem;
}

.legal-page__section {
    margin-bottom: 2.5rem;
}

.legal-page__section:last-child {
    margin-bottom: 0;
}


/* ========== POPUP DE CONTACTO ========== */
.contact-popup {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: var(--z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    padding: 1.5rem;
}

.contact-popup.active {
    pointer-events: all;
    opacity: 1;
    visibility: visible;
}

.contact-popup__overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(var(--color-ink-rgb), 0.8);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}

.contact-popup__container {
    position: relative;
    background: var(--surface-raised);
    border-radius: var(--radius-xl);
    padding: 3rem 2.5rem;
    max-width: 420px;
    width: 100%;
    text-align: center;
    box-shadow: 0 25px 80px rgba(var(--color-ink-rgb), 0.3);
}

.contact-popup__close {
    position: absolute;
    top: 1rem;
    right: 1rem;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    border-radius: var(--radius-circle);
    cursor: pointer;
    color: #888;
    transition: background-color 0.3s ease,
                color 0.3s ease;
}

.contact-popup__close:hover {
    background: var(--surface-sunken);
    color: var(--color-ink);
}

.contact-popup__icon {
    width: 80px;
    height: 80px;
    margin: 0 auto 1.5rem;
    display: none;
    border-radius: var(--radius-circle);
}

.contact-popup__icon svg {
    width: 100%;
    height: 100%;
}

/* Estado de éxito */
.contact-popup.success .contact-popup__icon--success {
    display: block;
    color: var(--color-success);
}

.contact-popup.success .contact-popup__container {
    border-top: 4px solid var(--color-success);
}

/* Estado de error */
.contact-popup.error .contact-popup__icon--error {
    display: block;
    color: var(--color-error);
}

.contact-popup.error .contact-popup__container {
    border-top: 4px solid var(--color-error);
}

.contact-popup__title {
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-ink);
    margin-bottom: 0.75rem;
    letter-spacing: -0.5px;
}

.contact-popup__message {
    font-size: var(--text-base);
    color: #666;
    line-height: var(--leading-normal);
    margin-bottom: 2rem;
}

.contact-popup__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 1rem 2.5rem;
    font-size: var(--text-base);
    font-weight: 600;
    border: none;
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: box-shadow 0.3s ease,
                transform 0.3s ease;
    min-width: 180px;
}

.contact-popup.success .contact-popup__btn {
    background: linear-gradient(135deg, var(--color-success) 0%, #16a34a 100%);
    color: var(--text-inverse);
}

.contact-popup.success .contact-popup__btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 25px rgba(34, 197, 94, 0.4);
}

.contact-popup.error .contact-popup__btn {
    background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-dark) 100%);
    color: var(--text-inverse);
}

.contact-popup.error .contact-popup__btn:hover {
    transform: translateY(-2px);
    box-shadow: var(--glow-primary-strong);
}

/* Animaciones del icono */


/* Loader del botón de envío */
.contact-form__submit.loading {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    opacity: 0.8;
    pointer-events: none;
}

/* Campo honeypot anti-spam (debe estar oculto) */

.btn-loader {
    width: 20px;
    height: 20px;
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-top-color: var(--text-inverse);
    border-radius: var(--radius-circle);
}


/* Responsive popup */
@media (max-width: 480px) {
    .contact-popup__container {
        padding: 2rem 1.5rem;
        border-radius: var(--radius-xl);
    }

    .contact-popup__icon {
        width: 64px;
        height: 64px;
        margin-bottom: 1rem;
    }

    .contact-popup__title {
        font-size: var(--text-lg);
    }

    .contact-popup__message {
        font-size: var(--text-sm);
    }

    .contact-popup__btn {
        width: 100%;
    }
}

/* ========== SERVICE LIGHTBOX ========== */
.service-lightbox {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s ease, visibility 0.3s ease;
}

.service-lightbox.active {
    opacity: 1;
    visibility: visible;
}

.service-lightbox__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(var(--color-ink-rgb), 0.9);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    cursor: pointer;
}

.service-lightbox__container {
    position: relative;
    max-width: 900px;
    max-height: 90vh;
    max-height: 90dvh;
    width: 100%;
    transform: scale(0.9) translateY(20px);
    transition: transform 0.4s var(--ease-spring);
}

.service-lightbox.active .service-lightbox__container {
    transform: scale(1) translateY(0);
}

.service-lightbox__image-wrapper {
    position: relative;
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: 0 25px 80px rgba(var(--color-ink-rgb), 0.5);
}

.service-lightbox__image {
    width: 100%;
    height: auto;
    display: block;
    max-height: 85vh;
    max-height: 85dvh;
    object-fit: contain;
}

.service-lightbox__close {
    position: absolute;
    top: -1rem;
    right: -1rem;
    width: 3rem;
    height: 3rem;
    background: var(--color-primary);
    border: none;
    border-radius: var(--radius-circle);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.3s ease, background 0.3s ease;
    z-index: var(--z-elevated);
}

.service-lightbox__close:hover {
    transform: scale(1.1) rotate(90deg);
    background: var(--color-primary-dark);
}

.service-lightbox__close svg {
    width: 1.25rem;
    height: 1.25rem;
    stroke: white;
    stroke-width: 2.5;
}

.service-lightbox__title {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 2rem;
    background: linear-gradient(to top, rgba(var(--color-ink-rgb), 0.95), transparent);
    color: var(--text-inverse);
    font-size: var(--text-lg);
    font-weight: 600;
    text-align: center;
}

/* Hacer las cards de servicio clickables */
.service-card--clickable {
    cursor: pointer;
}

.service-card--clickable .service-card__image {
    transition: transform 0.4s ease;
}

.service-card--clickable:hover .service-card__image img {
    transform: scale(1.05);
}

/* El tinte rojo al pasar por una tarjeta ampliable. En ::before y no en
   ::after, que es la capa del velo oscuro: ver .service-card__image::after. */
.service-card--clickable .service-card__image::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: var(--z-base);
    background: linear-gradient(to top, rgba(var(--color-primary-rgb), 0.3), transparent 50%);
    opacity: 0;
    transition: opacity 0.3s ease;
    pointer-events: none;
}

.service-card--clickable:hover .service-card__image::before {
    opacity: 1;
}

.service-card__zoom-icon {
    position: absolute;
    bottom: 1rem;
    right: 1rem;
    width: 2.5rem;
    height: 2.5rem;
    background: rgba(255, 255, 255, 0.95);
    border-radius: var(--radius-circle);
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transform: scale(0.8);
    transition: opacity 0.3s ease, transform 0.3s ease;
    z-index: 2;
}

.service-card--clickable:hover .service-card__zoom-icon,
.service-card--clickable:focus-within .service-card__zoom-icon {
    opacity: 1;
    transform: scale(1);
}

/* Con teclado el boton tiene que verse aunque el raton no este encima: antes solo
   aparecia con :hover y quien tabulaba enfocaba un boton invisible. */
.service-card__zoom-icon:focus-visible {
    opacity: 1;
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.service-card__zoom-icon svg {
    width: 1.25rem;
    height: 1.25rem;
    stroke: var(--color-ink);
    stroke-width: 2;
}

@media (max-width: 768px) {
    .service-lightbox {
        padding: 1rem;
    }
    
    .service-lightbox__close {
        top: -0.5rem;
        right: -0.5rem;
        width: 2.5rem;
        height: 2.5rem;
    }
    
    .service-lightbox__title {
        font-size: 1.125rem;
        padding: 1.5rem 1rem;
    }
}

/* ================================================================
   SERVICIOS EN TÁCTIL Y PANTALLA PEQUEÑA — carrusel nativo
   ================================================================
   La condición es el complemento EXACTO de MQ.pinOK en main.js:

       pinOK = (min-width: 1024px) AND (pointer: fine)
       aquí  = (max-width: 1023px) OR  (pointer: coarse)

   Si quedara un hueco entre las dos (ya pasó con el movimiento reducido, cuando
   pinOK lo excluía y este bloque no lo incluía), en ese caso no habría ni pin
   ni carrusel: el track se queda en `display:flex; width:max-content` dentro
   de un padre con `overflow:hidden` y seis de las ocho tarjetas quedan fuera de
   la pantalla. Si se toca una de las dos condiciones, hay que tocar la otra.

   En escritorio el track lo mueve GSAP con `transform` y un pin. Aquí no hay
   pin: lo mueve el scroll nativo del sistema, que con el dedo siempre va a ir
   más fluido que cualquier interpolación por JS. Se conserva el gesto
   horizontal del diseño en vez de apilar ocho tarjetas altas en una columna. */
@media (max-width: 1023px), (pointer: coarse) {
    .services-horizontal,
    .services-horizontal__wrapper {
        /* Sin pin no hay motivo para reservar una pantalla entera de alto. */
        min-height: 0;
    }

    .services-horizontal__track {
        width: auto;
        max-width: 100%;
        overflow-x: auto;
        overflow-y: hidden;
        scroll-snap-type: x mandatory;
        /* Que el gesto horizontal no se propague y acabe navegando atrás. */
        overscroll-behavior-x: contain;
        scroll-padding-inline: clamp(2rem, 5vw, 5rem);
        /* En modo scroll nativo, promover el track a capa es contraproducente:
           crea una capa del ancho de las ocho tarjetas juntas y se come memoria
           de GPU sin que nadie la anime. */
        will-change: auto;
        transform: none;
    }

    .services-horizontal__track > .service-card {
        scroll-snap-align: center;
    }

    /* El padding derecho de un contenedor flex no se respeta al final del
       scroll en varios navegadores; un hijo vacío sí ocupa. Sin esto, la última
       tarjeta queda pegada al borde. */
    .services-horizontal__track::after {
        content: '';
        flex: 0 0 clamp(0.5rem, 2vw, 2rem);
    }

    .services-horizontal__track::-webkit-scrollbar {
        height: 0;
    }
}

/* ================================================================
   COMPARADOR ANTES/DESPUÉS — gesto y foco
   ================================================================ */

/* pan-y reparte el gesto sin que JS tenga que intervenir: el navegador se queda
   el desplazamiento vertical (scroll de la página) y nos entrega el horizontal
   (arrastrar el comparador). Antes esto se resolvía con un listener touchmove
   global en `passive: false`, que obligaba al navegador a consultar a JS en
   cada gesto de toda la página antes de poder scrollear. */
/* El handle ahora es enfocable con el tabulador, así que tiene que verse.
   :focus-visible y no :focus para no dibujar el anillo a quien llega con el
   ratón, que ya sabe dónde ha hecho clic. */
.comparison-slider__handle:focus {
    outline: none;
}

.comparison-slider__handle:focus-visible {
    outline: none;
}

.comparison-slider__handle:focus-visible .comparison-slider__handle-circle {
    outline: 3px solid var(--color-primary);
    outline-offset: 4px;
    box-shadow: 0 0 0 6px rgba(var(--color-primary-rgb), 0.25);
}

/* Mientras se arrastra, el cursor no debe convertirse en "seleccionar texto". */
.comparison-slider__container.is-dragging {
    cursor: ew-resize;
    -webkit-user-select: none;
    user-select: none;
}

/* ================================================================
   TÁCTIL: ni hover pegado ni contenido escondido tras un hover
   ================================================================
   `hover: none` pregunta por la CAPACIDAD del dispositivo, no por el ancho de
   la pantalla. Es la diferencia que importa: una tablet de 900px es ancha pero
   no tiene puntero, así que con un breakpoint por anchura se quedaba fuera.

   Dos problemas distintos que se arreglan aquí:

   1. Contenido que solo aparece al pasar el ratón. Sin ratón no aparece nunca,
      o aparece al tocar y ya no se va. En táctil se muestra desde el principio.
   2. El "hover pegado": al tocar, el navegador aplica :hover y lo deja puesto
      hasta que tocas otra cosa. La tarjeta se queda levantada, el botón crecido
      y la imagen ampliada, sin motivo aparente para el usuario. */
@media (hover: none) {
    /* --- 1. Lo que estaba escondido tras el hover, visible --- */
    .service-card__desc,
    .service-card:hover .service-card__desc {
        opacity: 1;
        max-height: 120px;
        overflow: visible;
    }

    .service-card__link,
    .service-card:hover .service-card__link {
        opacity: 1;
        transform: translateY(0);
    }

    /* El icono de lupa indica que la tarjeta se puede abrir: en táctil no hay
       forma de descubrirlo si depende del hover. */
    .service-card--clickable .service-card__zoom-icon {
        opacity: 1;
        transform: none;
    }

    /* --- 2. Estados que se quedaban pegados tras el toque --- */
    .service-card:hover,
    .service-card__link:hover,
    .faq-item:hover,
    .process-timeline__card-inner:hover,
    .footer__social-link:hover,
    .header__menu-btn:hover,
    .hero__cta:hover,
    .service-lightbox__close:hover,
    .comparison-slider__handle-circle:hover {
        transform: none;
    }

    .service-card:hover .service-card__image img,
    .service-card--clickable:hover .service-card__image img,
    .service-card:hover .service-card__number,
    .service-card:hover .service-card__content,
    .service-card__link:hover svg,
    .process-timeline__card-inner:hover .process-timeline__icon-wrap,
    .process-timeline__card-inner:hover .process-timeline__icon-wrap svg,
    .comparison-slider__handle-circle:hover svg,
    .footer__cta-btn:hover svg,
    .legal-page__back:hover svg,
    .nav-fullscreen__visual:hover .nav-fullscreen__image {
        transform: none;
    }
}

/* ================================================================
   TÁCTIL: objetivos lo bastante grandes para un dedo
   ================================================================
   Medido en el navegador a 360 y 768 px: los enlaces del pie median 23 px de
   alto, los del bloque de contacto 24 y los iconos sociales 42x42. Un dedo
   necesita 44. En escritorio no se tocan, que ahí 23 px con un ratón se pulsan
   perfectamente y agrandarlos solo estiraría el pie sin motivo.

   Los enlaces que van DENTRO de una frase (el correo y la «política de
   privacidad» del formulario) se quedan como están: la propia norma (WCAG 2.2,
   2.5.8) los exceptúa, y agrandarlos rompería el interlineado del párrafo. */
@media (pointer: coarse) {
    .footer__links {
        /* El aire pasa del hueco al relleno de cada enlace: el ritmo visual se
           mantiene y lo pulsable crece. */
        gap: 0;
    }

    .footer__link,
    .footer__link:link,
    .footer__link:visited,
    .footer__link:any-link {
        padding-block: 0.65rem;
    }

    /* El subrayado se ancla al texto, no al borde de la caja rellenada. */
    .footer__link::after {
        bottom: calc(0.65rem - 2px);
    }

    .footer__contact-item a,
    .footer__contact-item a:link,
    .footer__contact-item a:visited,
    .footer__contact-item a:any-link {
        display: inline-block;
        padding-block: 0.6rem;
    }

    .footer__contact-item {
        margin-bottom: 0.5rem;
    }

    .footer__social-link {
        width: 44px;
        height: 44px;
    }

    /* Teléfono, correo e Instagram de la sección de contacto, los dos enlaces
       del menú a pantalla completa y los legales del pie: todos rondaban los
       21-24 px. */
    .cta-section__info-item a,
    .nav-fullscreen__contact a,
    .nav-fullscreen__social a,
    .footer__legal a,
    .footer__legal a:link,
    .footer__legal a:visited,
    .footer__legal a:any-link {
        display: inline-block;
        padding-block: 0.65rem;
    }

    .cta-section__info-item {
        /* El icono se recoloca solo al crecer el enlace; sin esto la fila se
           descuadraba respecto al svg. */
        align-items: center;
    }

    /* El botón de lupa de las tarjetas: el icono sigue midiendo lo mismo, lo
       que crece es la zona que responde al dedo. */
    .service-card__zoom-icon {
        min-width: 44px;
        min-height: 44px;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .header__logo {
        min-height: 44px;
    }
}

/* ================================================================
   FOCO VISIBLE — navegación por teclado
   ================================================================
   Sin esto, quien navega con el tabulador no sabe dónde está. Se usa
   :focus-visible y no :focus para que el anillo no le salga a quien acaba de
   hacer clic con el ratón, que ya sabe dónde ha pulsado. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
summary:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible {
    outline: 3px solid var(--color-primary);
    outline-offset: 3px;
    border-radius: var(--radius-sm);
}

/* Sobre fondo oscuro el rojo de marca no se despega lo suficiente. */
.nav-fullscreen a:focus-visible,
.footer a:focus-visible,
.footer button:focus-visible,
.service-card a:focus-visible {
    outline-color: var(--text-inverse);
    outline-offset: 4px;
}

/* Enlace para saltar al contenido: fuera de pantalla hasta que se le da foco.
   Es lo primero que encuentra alguien con teclado o lector, y le ahorra pasar
   por el menú entero en cada página. */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: var(--z-skip);
    padding: 0.9rem 1.4rem;
    background: var(--color-ink);
    color: var(--text-inverse);
    font-weight: 600;
    text-decoration: none;
    border-radius: 0 0 8px 0;
}

.skip-link:focus {
    left: 0;
}


/* ================================================================
   ACABADO TIPOGRÁFICO Y DE NAVEGACIÓN
   ================================================================ */

/* --- Los anclajes no deben quedar debajo de la cabecera fija ---------------
   El menú lleva a #servicios, #proceso, #contacto... y el JS lo resuelve bien,
   con un offsetY de 80px. Pero hay dos caminos que NO pasan por el JS:

     - Llegar con el ancla ya en la URL. Si alguien pasa por WhatsApp el enlace
       lecomanvalles.com/#contacto, el navegador salta al destino él solo, en
       cuanto encuentra el elemento, mucho antes de que GSAP exista.
     - Cualquier visita en la que el JS no llegue a ejecutarse.

   En los dos casos la sección aterrizaba con sus primeros 80px tapados por la
   cabecera: el titular quedaba justo detrás del logotipo. scroll-margin-top lo
   resuelve en el propio CSS, sin depender de nada. */
section[id] {
    scroll-margin-top: var(--anchor-offset);
}


/* --- Cortes de línea ------------------------------------------------------
   `balance` reparte las palabras de un titular entre sus líneas en vez de
   llenar la primera y dejar una palabra suelta en la última. Esa palabra
   huérfana es de las cosas que más delatan que una web no se ha rematado, y
   aparecía en varios titulares de sección al pasar por ciertos anchos.

   `pretty` hace lo mismo, más suave, en párrafos largos.

   Los navegadores que no lo entienden ignoran la línea y siguen partiendo como
   antes: no hay nada que se rompa. */
h1, h2, h3, h4,
.hero__title,
.section-title,
.process-timeline__title,
.faq-item__question,
.footer__cta-title {
    text-wrap: balance;
}

p,
.hero__subtitle,
.intro__text,
.service-card__desc,
.faq-item__answer {
    text-wrap: pretty;
}

/* Salvo donde partir a media palabra sería peor que desbordar. */
.hero__title,
.section-title,
.stat-item__number,
.hero__counter-number {
    overflow-wrap: normal;
}


/* --- Selección de texto ---------------------------------------------------
   El azul del sistema no pinta nada en una web cuyo acento es rojo. Es un
   detalle pequeño, pero es de los que se ven cada vez que alguien arrastra el
   ratón sobre un teléfono para copiarlo. */
::selection {
    background: var(--color-primary);
    color: var(--text-inverse);
    text-shadow: none;
}

::-moz-selection {
    background: var(--color-primary);
    color: var(--text-inverse);
    text-shadow: none;
}


/* ================================================================
   ALTO CONTRASTE DEL SISTEMA (forced-colors)
   ================================================================
   Windows en modo de contraste alto sustituye la paleta entera por la del
   sistema y, entre otras cosas, retira los fondos decorativos.

   Los titulares de esta web colorean la palabra destacada con un degradado
   recortado sobre el texto: `background: linear-gradient(...)` más
   `-webkit-text-fill-color: transparent`. Al quitar el fondo, lo que queda es
   texto relleno de transparente sobre nada: la palabra DESAPARECE. Y no es una
   palabra cualquiera: son las cinco de la web que llevan énfasis —el h1 del
   hero, cada titular de sección, el contador de proyectos del hero, el número
   de cada paso del proceso y el titular del pie—.

   Devolver el relleno a currentColor lo arregla en las cinco. */
@media (forced-colors: active) {
    .section-title em,
    .hero__title em,
    .hero__counter-number,
    .footer__cta-title em,
    .process-timeline__number,
    [style*="text-fill-color"] {
        background: none !important;
        -webkit-text-fill-color: currentColor !important;
        /* CanvasText y no LinkText. LinkText es el color que el sistema
           reserva para los ENLACES, y estos elementos son titulares y cifras.
           Pintarlos de color de enlace en alto contraste hace que parezcan
           pulsables: quien navega así se apoya justo en ese código de color
           para saber qué es un enlace y qué no. */
        color: CanvasText !important;
    }

    /* Los adornos puramente decorativos no aportan nada aquí y sí estorban. */
    .noise-overlay,
    .hero__shapes,
    .stats-section__shapes,
    .process-section__bg-shapes {
        display: none !important;
    }

    /* El cursor falso no se dibuja: en este modo el del sistema es esencial.
       Y hay que DEVOLVERLO explicitamente: esconder los puntos no basta,
       porque la clase .has-custom-cursor sigue puesta y con ella el
       `cursor: none`. Esconder uno sin restaurar el otro es justamente el
       fallo que dejaba la web sin ningun cursor. */
    .cursor,
    .cursor-follower {
        display: none !important;
    }

    html.has-custom-cursor,
    html.has-custom-cursor * {
        cursor: auto !important;
    }
}


/* ================================================================
   IMPRESIÓN
   ================================================================
   Una web de reformas se imprime más de lo que parece: alguien apunta el
   teléfono, se lleva la lista de servicios a una reunión o guarda el
   presupuesto. Sin esta hoja salían las nueve primeras páginas en negro
   —las secciones de fondo oscuro— y varias secciones en blanco, porque los
   elementos que anima GSAP arrancan con visibility: hidden y al imprimir
   nunca llega a dispararse el ScrollTrigger que los revela.
   ================================================================ */
@media print {
    /* Nada de esto tiene sentido en papel. */
    .preloader,
    .cursor,
    .cursor-follower,
    .noise-overlay,
    .scroll-progress,
    .header,
    .nav-fullscreen,
    .contact-popup,
    .service-lightbox,
    .hero__canvas,
    .hero__grid-overlay,
    .hero__shapes,
    .hero__scroll-hint,
    .footer__marquee,
    .stats-section__shapes,
    .process-section__bg-shapes {
        display: none !important;
    }

    /* Lo que GSAP deja oculto a la espera de un scroll que en papel no ocurre. */
    *,
    *::before,
    *::after {
        visibility: visible !important;
        opacity: 1 !important;
        transform: none !important;
        animation: none !important;
        transition: none !important;
        clip-path: none !important;
    }

    /* Tinta: fondo blanco y texto negro en todo, incluidas las secciones que
       en pantalla van sobre oscuro. */
    html,
    body,
    section,
    .footer,
    .stats-section,
    .cta-section,
    .services-horizontal {
        background: #fff !important;
        color: #000 !important;
        box-shadow: none !important;
    }

    h1, h2, h3, h4,
    .section-title,
    .hero__title,
    .footer__cta-title {
        color: #000 !important;
        -webkit-text-fill-color: #000 !important;
        background: none !important;
        page-break-after: avoid;
        break-after: avoid;
    }

    /* El carrusel de servicios se apila: en papel no hay scroll horizontal. */
    .services-horizontal__track,
    .services-horizontal {
        display: block !important;
        overflow: visible !important;
        height: auto !important;
        min-height: 0 !important;
        transform: none !important;
    }

    .service-card,
    .process-timeline__item,
    .faq-item,
    .stat-item {
        page-break-inside: avoid;
        break-inside: avoid;
        width: auto !important;
        height: auto !important;
        border: 1px solid #ccc;
        margin-bottom: 1rem;
    }

    /* Un enlace impreso sin su dirección no sirve de nada. Solo los externos y
       los de contacto: poner la URL detrás de cada ancla interna llenaría el
       papel de ruido. */
    a[href^="http"]::after,
    a[href^="mailto:"]::after,
    a[href^="tel:"]::after {
        content: " (" attr(href) ")";
        font-size: 0.8em;
        word-break: break-all;
    }

    /* Márgenes de página y sin repetir cabeceras. */
    @page {
        margin: 1.5cm;
    }
}
