/* ============================================================
   pagina-web.css — estilos exclusivos de public/paginas-web.php
   Separado de style.css (que ya estaba creciendo mucho) para que
   esta página tenga su propia hoja, cargada solo ahí.
   ============================================================ */

/* Hero: la imagen cubre TODA la sección (full-bleed), con el mismo
   efecto de zoom por scroll que usan Nosotros/Servicios (.parallax-
   visual, controlado por main.js) — pero SIN el fade de opacidad
   (main.js respeta el atributo data-no-opacity-fade). Además, un
   degradado claro protege el texto de la izquierda sin tapar la
   imagen — hacia la derecha se ve con total nitidez. */
.hero-video-section{
  position:relative; overflow:hidden;
  min-height:calc(100vh - 80px);
  min-height:calc(100dvh - 80px);
  display:flex; align-items:center;
  padding:70px 0;
  background-color:#F6F7FB;
}
.hero-video-section .parallax-visual{
  top:0; left:0; right:0; bottom:0; /* full-bleed real, sin el colchón -30vh que usa el hero de Nosotros */
}
.hero-video-section .parallax-media{position:absolute; inset:0; z-index:0;}
.hero-video-section .parallax-img{
  width:100%; height:100%; object-fit:cover; object-position:60% center;
  /* Desvanecido real de la propia imagen (no solo un overlay encima):
     se funde a transparente en el último tercio, dejando ver el fondo
     de la sección detrás — así nunca hay un borde recto, sin importar
     el scroll (esto es estático, no lo toca main.js). */
  -webkit-mask-image:linear-gradient(to bottom, #000 0%, #000 62%, transparent 100%);
  mask-image:linear-gradient(to bottom, #000 0%, #000 62%, transparent 100%);
}
.hero-video-section::before{
  content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(90deg,
    #F6F7FB 0%,
    #F6F7FB 32%,
    rgba(246,247,251,.88) 44%,
    rgba(246,247,251,.35) 60%,
    rgba(246,247,251,0) 74%
  );
}
/* Refuerzo del borde inferior: como la imagen ya se desvanece sola
   (mask-image de arriba), esto solo termina de emparejar el color
   exacto con la sección siguiente (#fff), bien ancho para que la
   transición sea larga y gradual, nunca un corte. */
.hero-video-section::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:42%; z-index:1;
  pointer-events:none;
  background:linear-gradient(180deg, transparent 0%, rgba(246,247,251,.5) 55%, #fff 100%);
}
.hero-video-section .hero-video-inner{position:relative; z-index:2; width:100%; max-width:1340px; margin:0 auto; padding:0 32px;}
.hero-video-content{max-width:560px;}
.hero-video-content h1{color:var(--navy); font-size:46px; line-height:1.15; margin:0;}
.hero-video-content h1 .accent{color:var(--crimson);}
.hero-video-content .sub{color:var(--navy); opacity:.72; font-size:17px; line-height:1.6; margin:18px 0 0;}
.hero-video-content .cta-row{margin-top:30px;}

@media (max-width:900px){
  .hero-video-section::before{
    background:linear-gradient(180deg,
      #F6F7FB 0%,
      #F6F7FB 50%,
      rgba(246,247,251,.85) 75%,
      rgba(246,247,251,.55) 100%
    );
  }
  .hero-video-content{max-width:none;}
}
@media (max-width:640px){
  .hero-video-section{min-height:calc(100vh - 80px); min-height:calc(100dvh - 80px); padding:40px 0;}
  .hero-video-content h1{font-size:32px;}
  .hero-video-content .sub{font-size:15.5px;}
}

/* ============================================================
   "TODO LO QUE TU WEB NECESITA" — carrusel de ancho completo
   (full-bleed, sale del .wrap), más grande que la sección de
   tarjetas que tenía antes. A diferencia del carrusel de Casos
   de Uso (que usa fundido de opacidad), este se desplaza en
   HORIZONTAL: todas las diapositivas están en fila dentro de
   .features-track, y el track se traslada con transform:translateX
   para deslizar de una a otra con una animación suave.
   ============================================================ */
.features-carousel-section{
  width:100%;
  background:#fff;
  padding:0;
}
.features-carousel-box{
  position:relative;
  background:var(--navy);
}

/* Título — overlay absoluto ARRIBA de la caja, encima de la imagen,
   no una barra separada que empuje todo hacia abajo. Sigue fuera de
   .features-track, así que nunca se mueve con la transición. */
.features-carousel-header{
  position:absolute; top:0; left:0; right:0; z-index:2;
  max-width:640px; margin:0 auto; padding:36px 32px 0; text-align:center;
  pointer-events:none;
}
.features-carousel-header h2{color:#fff; text-shadow:0 2px 12px rgba(0,0,0,.4);}
.features-carousel-header p{color:#E3E6F0; text-shadow:0 2px 10px rgba(0,0,0,.4);}

.features-carousel{
  position:relative; overflow:hidden;
  /* height definida (no min-height): con solo min-height, el alto de
     .features-track/.features-slide-media (que usan height:100%) no
     tenía una base fija de dónde resolver ese 100% y terminaban
     achicándose al tamaño natural de la imagen — por eso la foto no
     llegaba al borde inferior y se veía cortada antes de la ola.
     620px (antes 560px): más aire para separar el texto centrado
     tanto del título de arriba como de las pestañas de abajo. */
  height:620px;
}
.features-track{
  display:flex;
  height:100%;
  transition:transform .6s cubic-bezier(.4,0,.2,1);
  will-change:transform;
}
.features-slide{
  flex:0 0 100%;
  min-width:100%;
  display:grid; grid-template-columns:1.05fr 1fr;
  /* stretch (default de grid), NO center: con center, .features-slide-media
     quedaba centrada dentro de la fila en vez de estirarse a la altura
     completa, dejando un hueco de navy antes de la ola divisoria — se
     veía como un corte en la imagen en vez de cubrir hasta el borde. */
}

.features-slide-text{
  /* Centrado vertical real dentro de toda la altura de la diapositiva
     (antes el texto arrancaba pegado arriba con un padding-top fijo).
     align-items:flex-start (no el "stretch" por defecto de flex-column):
     si no, el badge y los títulos se estiran a todo el ancho de la
     columna en vez de quedarse del tamaño de su propio contenido. */
  height:100%;
  display:flex; flex-direction:column; justify-content:center; align-items:flex-start;
  /* Alinea el texto exactamente con el logo del header: mismo cálculo
     que .site-header .wrap (max-width:1340px + padding:32px). */
  padding:40px clamp(32px, 6vw, 90px) 40px max(32px, calc((100vw - 1340px) / 2 + 32px));
  /* Empuja el bloque centrado hacia abajo (margin, no padding: así no
     compite con el centrado vertical) para que quede más lejos del
     título/subtítulo superpuesto arriba (.features-carousel-header),
     que antes quedaba pegado al badge y al h3. Se compensa con más
     alto total en .features-carousel para no comerle el espacio de
     abajo (quedaba muy junto a las pestañas). */
  margin-top:40px; margin-bottom:20px;
}
.features-slide-text .badge{margin-bottom:16px;}
.features-slide-text h3{color:#fff; font-size:38px; font-weight:800; margin-bottom:16px; line-height:1.15;}
.features-slide-text p{color:#fff; font-size:18px; font-weight:500; line-height:1.65; max-width:460px;}
.features-slide-text ul{
  list-style:none; margin:20px 0 0; padding:0;
  display:flex; flex-direction:column; gap:10px; max-width:460px;
}
.features-slide-text ul li{
  color:#C7CEE3; font-size:15.5px; line-height:1.5;
  padding-left:22px; position:relative;
}
.features-slide-text ul li::before{
  content:""; position:absolute; left:0; top:8px;
  width:7px; height:7px; border-radius:50%;
  background:var(--crimson);
}

/* La imagen ocupa TODA la mitad de la diapositiva (no una tarjeta
   flotante), fundiéndose hacia el navy con un degradado — mismo
   tratamiento que .casos-slide-media. */
.features-slide-media{position:relative; height:100%; min-height:520px; overflow:hidden;}
.features-slide-media img{width:100%; height:100%; object-fit:cover; display:block;}
.features-slide-media::before{
  content:""; position:absolute; inset:0; z-index:1;
  background:linear-gradient(90deg, var(--navy) 0%, rgba(30,44,81,.55) 30%, transparent 65%);
}

/* Pestañas — overlay absoluto ABAJO de la caja, encima de la imagen,
   fuera de .features-track (no se mueven con la transición). */
.features-tabs{
  position:absolute; left:0; right:0; bottom:0; z-index:2;
  display:flex; flex-wrap:wrap; justify-content:center; gap:10px 34px;
  padding:0 32px 26px;
}
.features-tab{
  padding:6px 2px; border:none; background:none;
  color:#E3E6F0; font-weight:700; font-size:15.5px;
  text-shadow:0 2px 10px rgba(0,0,0,.5);
  font-family:'Poppins'; cursor:pointer; position:relative;
  transition:color .25s ease;
}
.features-tab::after{
  content:""; position:absolute; left:0; bottom:0; width:100%; height:2px;
  background:var(--crimson); border-radius:2px;
  transform:scaleX(0); transform-origin:center;
  transition:transform .3s cubic-bezier(.4,0,.2,1);
}
.features-tab:hover{color:#fff;}
.features-tab.is-active{color:#fff;}
.features-tab.is-active::after{transform:scaleX(1);}

@media (max-width:900px){
  /* En mobile .features-slide-media pasa a order:-1 (la foto queda
     arriba), así que el header (position:absolute; top:0) termina
     flotando sobre la foto en vez de sobre el navy sólido de fondo —
     el text-shadow solo no bastaba con fotos claras. Un degradado
     propio detrás del texto garantiza contraste sin importar la foto. */
  .features-carousel-header{
    background:linear-gradient(180deg, rgba(18,24,46,.82) 0%, rgba(18,24,46,.5) 65%, transparent 100%);
    padding-bottom:34px;
  }
  .features-slide{grid-template-columns:1fr;}
  .features-slide-text{height:auto; display:block; padding:32px 28px 0;}
  .features-slide-text h3{font-size:28px;}
  .features-slide-text p{font-size:15.5px; max-width:none;}
  .features-slide-text ul{max-width:none;}
  .features-slide-media{min-height:240px; order:-1;}
  .features-slide-media::before{background:linear-gradient(180deg, transparent 40%, var(--navy) 100%);}
  .features-carousel{height:auto; min-height:0;}
  /* En desktop .features-tabs queda anclado (position:absolute) al
     fondo de .features-carousel-box, que mide lo mismo que el
     carrusel (560px fijo) — ahí nunca se cruza con el texto. En
     mobile el carrusel pasa a height:auto según el contenido de cada
     slide, así que ese mismo "bottom:0" terminaba superponiendo las
     pestañas con las últimas líneas del texto/lista. Con position:
     static las pestañas vuelven al flujo normal, siempre después de
     todo el contenido del slide, sin superponerse nunca. */
  .features-tabs{position:static; gap:8px 20px; padding:18px 20px 24px;}
  .features-tab{font-size:13.5px;}
}
@media (max-width:480px){
  .features-slide-text h3{font-size:23px;}
  .features-tabs{gap:6px 14px;}
  .features-tab{font-size:12.5px;}
}

/* ============================================================
   "TU NEGOCIO NECESITA PRESENCIA ONLINE" — switcher de imágenes:
   4 ejemplos de sitios a la izquierda (uno visible a la vez), que
   flotan suavemente con sombra, y transicionan en VERTICAL al
   presionar el nombre correspondiente a la derecha. La flotación
   continua vive en un wrapper aparte (.portfolio-switch-img-wrap)
   separado de la transición de cambio (.portfolio-switch-slide),
   para que ninguno de los dos transforms compita con el otro.
   ============================================================ */
.portfolio-switch-section{padding:100px 0;}
.apple-scroll-panel.portfolio-switch-section{padding-top:60px !important;}
.portfolio-switch-section .wrap{max-width:1360px;}
.portfolio-switch-grid{
  display:grid; grid-template-columns:1.4fr 1fr; gap:56px; align-items:center;
}

.portfolio-switch-media{
  position:relative; overflow:hidden;
  width:100%;
  aspect-ratio:16 / 9;
  margin:0 auto;
  border-radius:20px;
  background:var(--paper);
  box-shadow:0 30px 60px -20px rgba(30,44,81,.35);
  animation:portfolioFloat 6s ease-in-out infinite;
}
.portfolio-switch-track{
  display:flex; flex-direction:column;
  height:100%;
  transition:transform .6s cubic-bezier(.4,0,.2,1);
  will-change:transform;
}
.portfolio-switch-slide{
  flex:0 0 100%;
  /* height, no min-height: el JS mueve el track con
     translateY(-index*100%) asumiendo que TODAS las diapositivas miden
     exactamente igual — con min-height, si el contenido de alguna
     necesitaba un poco más de alto, esa diapositiva podía crecer más
     de la cuenta, desalineando el cálculo y dejando que la SIGUIENTE
     foto (completamente distinta) se asomara por el borde inferior. */
  height:100%;
  display:flex; align-items:center; justify-content:center;
  background:var(--paper);
  overflow:hidden;
}
.portfolio-switch-slide img{
  width:100%; height:100%; object-fit:contain; display:block;
}
/* ARCA Tax Services y Elite Grill Perú: el mockup (laptop + celular)
   viene con más lienzo negro alrededor que las otras capturas, así
   que con el mismo encuadre quedaban más chicas, con espacio vacío a
   los costados. Solo a estas dos: cover + zoom leve para que el
   dispositivo llene la tarjeta — el resto de diapositivas se queda
   con el encuadre original (contain), que ya se veía bien. */
.portfolio-switch-slide img.is-zoomed{object-fit:cover; transform:scale(1.08);}
@keyframes portfolioFloat{
  0%, 100%{transform:translateY(0);}
  50%{transform:translateY(-14px);}
}
@media (prefers-reduced-motion: reduce){
  .portfolio-switch-media{animation:none;}
}

.portfolio-switch-list{
  margin-top:24px; padding:0; list-style:none;
  display:flex; flex-direction:column; gap:6px;
}
.portfolio-switch-btn{
  width:100%; text-align:left;
  display:flex; align-items:flex-start; gap:12px;
  padding:13px 16px; border-radius:12px; border:1.5px solid transparent;
  background:none; cursor:pointer;
  color:#C7CEE3; font-family:'Poppins';
  transition:color .25s ease, background-color .25s ease, border-color .25s ease;
}
.portfolio-switch-btn svg{flex-shrink:0; margin-top:2px; opacity:.6; transition:opacity .25s ease, color .25s ease;}
.portfolio-switch-btn:hover{background:rgba(255,255,255,.08); color:#fff;}
.portfolio-switch-btn.is-active{
  background:rgba(234,33,81,.16); border-color:var(--crimson);
  color:#fff;
}
.portfolio-switch-btn.is-active svg{opacity:1; color:var(--crimson);}

.portfolio-switch-btn-content{display:flex; flex-direction:column; min-width:0;}
.portfolio-switch-btn-name{font-weight:600; font-size:16px; line-height:1.3;}

/* Descripción: colapsada por defecto, se despliega debajo del
   nombre justo cuando el botón pasa a is-active — en el mismo
   momento en que cambia la imagen (misma clase, mismo trigger). */
.portfolio-switch-btn-desc{
  display:block; max-height:0; opacity:0; overflow:hidden;
  font-size:12.5px; font-weight:500; color:#B9C2E0; line-height:1.5;
  transition:max-height .45s cubic-bezier(.4,0,.2,1), opacity .35s ease .05s, margin-top .45s cubic-bezier(.4,0,.2,1);
}
.portfolio-switch-btn.is-active .portfolio-switch-btn-desc{
  max-height:80px; opacity:1; margin-top:4px;
}

@media (max-width:900px){
  /* min-width:0 es necesario acá: por defecto, un ítem de grid no se
     encoge más allá del tamaño mínimo de su contenido — y como
     .portfolio-switch-list de adentro es un carrusel horizontal con
     varias tarjetas (aunque solo se vea una por vez con overflow-x),
     el navegador puede seguir calculando el ancho "natural" como la
     suma de todas ellas, ensanchando toda la columna y la página
     entera en vez de respetar 1fr. Sin esto, el texto quedaba cortado
     al borde de la pantalla en vez de ajustarse. */
  .portfolio-switch-grid{grid-template-columns:1fr; gap:36px;}
  .portfolio-switch-grid > *{min-width:0;}
  .portfolio-switch-media{aspect-ratio:16 / 9;}
  .portfolio-switch-section{padding:70px 0;}

  /* La lista vertical con los 6 nombres pasa a carrusel horizontal:
     una tarjeta a la vez, deslizable hacia los costados con scroll
     nativo (scroll-snap soporta swipe solo, sin JS de arrastre). Cada
     <li> ocupa el 100% del ancho, así que solo se ve un ítem por vez
     en vez de la lista completa apilada. */
  .portfolio-switch-list{
    flex-direction:row; flex-wrap:nowrap;
    overflow-x:auto; scroll-snap-type:x mandatory;
    -webkit-overflow-scrolling:touch;
    max-width:100%;
    margin-left:-4px; margin-right:-4px;
    /* Oculta la barra de scroll nativa (el swipe sigue funcionando
       igual) — el indicador real son los puntos de abajo. */
    scrollbar-width:none;
  }
  .portfolio-switch-list::-webkit-scrollbar{display:none;}
  .portfolio-switch-list > li{
    flex:0 0 100%; scroll-snap-align:center; scroll-snap-stop:always;
    padding:0 4px;
  }

  /* Ya no hace falta el ícono de check ni el colapsado/expandido: acá
     cada tarjeta muestra un solo proyecto a la vez, así que el nombre
     y la descripción se ven siempre completos, centrados. */
  .portfolio-switch-btn{
    flex-direction:column; align-items:center; text-align:center;
    padding:22px 20px; border-radius:16px;
    background:rgba(255,255,255,.05); border-color:rgba(255,255,255,.1);
  }
  .portfolio-switch-btn svg{display:none;}
  .portfolio-switch-btn-content{align-items:center;}
  .portfolio-switch-btn-name{font-size:16.5px;}
  .portfolio-switch-btn-desc{
    max-height:none !important; opacity:1 !important; margin-top:6px !important;
    font-size:13px;
  }

  .portfolio-switch-dots{
    display:flex; justify-content:center; align-items:center; gap:8px;
    margin-top:18px;
  }
  .portfolio-switch-dot{
    width:7px; height:7px; border-radius:50%;
    background:rgba(255,255,255,.25);
    transition:background-color .25s ease, transform .25s ease;
  }
  .portfolio-switch-dot.is-active{
    background:var(--crimson); transform:scale(1.3);
  }

  /* Flechas a los costados del carrusel: el swipe ya alcanza, son un
     indicio visual de que se puede navegar. Se paran sobre el borde
     de la tarjeta activa (position:relative en el wrap las ubica). */
  .portfolio-switch-list-wrap{position:relative;}
  .portfolio-switch-arrow{
    position:absolute; top:50%; transform:translateY(-50%);
    display:flex; align-items:center; justify-content:center;
    background:none; border:none; padding:6px;
    color:#fff; opacity:.7; cursor:pointer; z-index:2;
    transition:opacity .2s ease;
  }
  .portfolio-switch-arrow:active{opacity:1; color:var(--crimson);}
  .portfolio-switch-arrow-prev{left:2px;}
  .portfolio-switch-arrow-next{right:2px;}

  /* El botón de WhatsApp quedaba pegado a la izquierda (.cta-row no
     centra por defecto) — acá sí se centra, igual que el resto del
     bloque. */
  .portfolio-switch-grid .cta-row{justify-content:center;}
}
@media (min-width:901px){
  .portfolio-switch-dots{display:none;}
  .portfolio-switch-arrow{display:none;}
}

/* ============================================================
   FONDO ESTILO APPLE (sticky + desenfoque progresivo) — envuelve
   las secciones "¿Qué tipo de sitio necesitas?", "Tu negocio
   necesita presencia online" y "Nuestro proceso". La imagen queda
   fija en pantalla (position:sticky) mientras esas 3 secciones
   siguen bajando encima; a medida que se hace scroll, main.js le
   sube el filter:blur() progresivamente — nítida al entrar, cada
   vez más desenfocada según cuánto avances.
   ============================================================ */
.apple-scroll-wrap{position:relative;}

.apple-scroll-bg-sticky{
  position:absolute; top:0; left:0; width:100%;
  height:100vh;
  z-index:0;
  overflow:hidden;
  pointer-events:none;
}
.apple-scroll-bg-img{
  width:100%; height:100%; object-fit:cover;
  will-change:filter;
}
.apple-scroll-bg-overlay{
  position:absolute; inset:0;
  background:rgba(255,255,255,.25);
}

/* Las 3 secciones quedan por encima del fondo fijo. */
.apple-scroll-panel{position:relative; z-index:1;}

/* Tarjetas en NAVY sobre la imagen de fondo — más presencia y
   contraste que el vidrio blanco anterior, en línea con la marca. */
.apple-scroll-card{
  background:rgba(30,44,81,.92) !important;
  backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
  border-color:rgba(255,255,255,.14) !important;
  box-shadow:0 20px 40px -18px rgba(0,0,0,.45);
}
.apple-scroll-card h3{color:#fff;}
.apple-scroll-card p{color:#C7CEE3 !important;}
.apple-scroll-card .icon-box{background:rgba(234,33,81,.18); color:#ff8fa9;}

.apple-scroll-card-text{
  padding:32px; border-radius:20px;
  box-shadow:0 20px 44px -22px rgba(30,44,81,.3);
}
/* Antes blanco (pensado para el fondo oscuro que tenía esta zona);
   con el fondo claro nuevo, blanco sobre claro no se notaba. Navy +
   una sombra clara de respaldo, por si el texto cae justo sobre la
   parte más oscura de la foto (la pantalla del laptop del mockup). */
.apple-scroll-panel .section-head h2{
  color:var(--navy);
  text-shadow:0 2px 18px rgba(255,255,255,.85), 0 1px 4px rgba(255,255,255,.9);
}
.apple-scroll-panel .section-head p{
  color:var(--navy);
  opacity:.82;
  text-shadow:0 2px 14px rgba(255,255,255,.85);
}

.apple-scroll-intro-head{
  text-align:center; max-width:560px; margin:0 auto;
}

@media (prefers-reduced-motion: reduce){
  .apple-scroll-bg-img{filter:none !important;}
}

@media (max-width:900px){
  /* En mobile el efecto sticky + blur progresivo no se nota (espacio
     muy angosto) y como imagen fija tampoco aportaba — se saca
     directamente en vez de intentar arreglarla. */
  .apple-scroll-bg-sticky{display:none;}
}

/* ============================================================
   CTA FINAL ("¿Estás listo para lanzar tu web?") — fondo-pasos.jpg
   cubre TODO el hero de la sección (no solo la tarjeta .final-cta
   que va encima), igual tratamiento que .process-section en
   software-a-medida.php: imagen a baja opacidad sobre una base
   sólida oscura.
   ============================================================ */
.cta-final-section{
  position:relative;
  padding-top:60px !important; padding-bottom:60px;
  background-color:var(--navy-ink);
}
.cta-final-section::before{
  content:"";
  position:absolute; inset:0;
  background-image:url('../img/fondo-pasos.jpg');
  background-size:cover; background-position:center;
  opacity:.16;
}
.cta-final-section .wrap{position:relative; z-index:1;}

/* Sin recuadro: el CTA se apoya directo sobre el fondo de la
   sección (que ya tiene fondo-pasos.jpg + base oscura), en vez de
   ir dentro de la tarjeta con degradado que traía por defecto. */
.cta-final-section .final-cta{
  background:none !important;
  border-radius:0 !important;
  box-shadow:none !important;
  padding:40px 0 !important;
}
.cta-final-section .final-cta h2,
.cta-final-section .final-cta p{color:#fff;}
.cta-final-section .final-cta p{color:#C7CEE3;}

@media (max-width:860px){
  /* El global .final-cta pasa a columna y queda pegado a la
     izquierda (align-items:flex-start) — acá se centra el título,
     el párrafo y el botón, igual que el resto de los CTA del sitio. */
  .cta-final-section .final-cta{align-items:center; text-align:center;}
}

/* ============================================================
   "¿QUÉ TIPO DE SITIO NECESITAS?" — ilustraciones reemplazando los
   íconos chicos, más margen respecto al título/subtítulo de la
   sección, descripciones más largas (ya vienen así desde el PHP).
   ============================================================ */
.tipos-grid{margin-top:64px;}

.tipo-card-img{
  width:100%; max-width:220px; height:auto;
  display:block; margin:0 auto 14px;
}
.tipo-card h3{margin-top:0; text-align:center;}
.tipo-card p{text-align:center;}

/* Flotación en paralelo: cada tarjeta sube/baja suave y sin parar,
   alternando sentido con su vecina (una sube mientras la otra baja)
   para que no se vean todas moviéndose exactamente igual a la vez. */
.tipo-float-up{animation:tipoFloatUp 5s ease-in-out infinite;}
.tipo-float-down{animation:tipoFloatDown 5s ease-in-out infinite;}
@keyframes tipoFloatUp{
  0%, 100%{transform:translateY(0);}
  50%{transform:translateY(-12px);}
}
@keyframes tipoFloatDown{
  0%, 100%{transform:translateY(0);}
  50%{transform:translateY(12px);}
}
@media (prefers-reduced-motion: reduce){
  .tipo-float-up, .tipo-float-down{animation:none;}
}

@media (max-width:640px){
  .tipos-grid{margin-top:40px;}
}

/* ============================================================
   "NUESTRO PROCESO" — 4 pasos en fila horizontal (no escalera
   diagonal como en software-a-medida.php), conectados por líneas
   rectas que se dibujan progresivamente al hacer scroll — mismo
   mecanismo de main.js (offsetLeft/offsetTop + stroke-dashoffset +
   cadena por transitionend), solo que el trazado es horizontal en
   vez de ortogonal ↓→↓.
   ============================================================ */
.proceso-timeline{position:relative; margin-top:56px;}
.proceso-lines{
  position:absolute; inset:0; z-index:0;
  width:100%; height:100%;
  overflow:visible; pointer-events:none;
}
.proceso-line{
  fill:none; stroke:#E81F53; stroke-width:2;
}

.proceso-steps{
  position:relative; z-index:1;
  display:grid; grid-template-columns:repeat(4, 1fr); gap:28px;
}
.proceso-step{
  padding:40px 24px 30px;
  position:relative; overflow:visible;
  opacity:0; transform:translateY(40px) scale(.96);
  transition:opacity .45s cubic-bezier(.2,.8,.2,1),
             transform .45s cubic-bezier(.2,.8,.2,1),
             box-shadow .3s ease;
  border-radius:18px;
  text-align:left;
}
.proceso-step.is-in-view{opacity:1; transform:translateY(0) scale(1);}
.proceso-step:hover{
  transform:translateY(-8px) scale(1);
  box-shadow:0 26px 50px -18px rgba(0,0,0,.5);
}
.proceso-step:hover .proceso-num{transform:scale(1.08);}

.proceso-num{
  position:absolute; top:-18px; left:24px; z-index:2;
  width:52px; height:52px; border-radius:14px;
  background:var(--crimson); color:#fff;
  display:flex; align-items:center; justify-content:center;
  font-family:'Montserrat'; font-weight:800; font-size:17px;
  box-shadow:0 12px 26px -6px rgba(234,33,81,.6);
  transition:transform .3s ease;
}
.proceso-step h3{color:#fff; font-size:19px; margin-bottom:10px;}
.proceso-step p{color:#B9C2E0; font-size:14px; line-height:1.65;}

@media (prefers-reduced-motion: reduce){
  .proceso-step{transition:none; opacity:1; transform:none;}
}

@media (max-width:900px){
  .proceso-steps{grid-template-columns:1fr; gap:20px;}
  .proceso-lines{display:none;}
}