/* ---------------------------------------------------------
   Odesa Caribe — hoja de estilos principal (mobile-first)
   Paleta: navy de marca #001F98 + acento turquesa + arena.
--------------------------------------------------------- */

:root{
  --navy: #001F98;
  --navy-deep: #000E45;
  --teal: #0BA79A;
  --teal-dark: #08867C;
  --sand: #F5F1E6;
  --sand-dark: #ECE6D6;
  --mist: #F0F2FF; /* fondo suave azulado del design-canvas, reemplaza --sand en algunas secciones de la home */
  --ink: #14161F;
  --ink-soft: #4C4F5E;
  --ink-faint: #7B7E8C;
  --white: #FFFFFF;
  --line: rgba(20,22,31,0.12);
  --radius: 22px;
  --shadow: 0 20px 40px -24px rgba(0,14,69,0.35);
  --wa-green: #25D366;
  --wa-green-dark: #1EBE5D;
}

*, *::before, *::after{ box-sizing:border-box; }
[hidden]{ display:none !important; }
html{ scroll-behavior:smooth; }
body{
  margin:0;
  font-family:'Quicksand', ui-sans-serif, system-ui, sans-serif;
  font-weight:500;
  font-size:20px;
  color:var(--ink);
  background:var(--white);
  line-height:1.6;
}
img{ max-width:100%; display:block; }
a{ color:inherit; text-decoration:none; }
button{ font-family:inherit; cursor:pointer; }

.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;
}

.wrap{ max-width:1140px; margin:0 auto; padding:0 1.25rem; }

h1, h2, h3{
  font-family:'Oswald', ui-sans-serif, system-ui, sans-serif;
  font-weight:700;
  text-transform:uppercase;
  letter-spacing:0.01em;
  text-wrap:balance;
  margin:0;
  color:var(--ink);
}

.eyebrow{
  display:inline-flex; align-items:center;
  font-size:0.78rem; font-weight:700; letter-spacing:0.08em;
  text-transform:uppercase; color:var(--teal);
  margin:0 0 0.6rem;
}
.eyebrow--center{ justify-content:center; text-align:center; width:100%; }
.eyebrow--light{ color:#8FF3E6; }

.h2{ font-size:clamp(2rem, 4vw + 1.2rem, 55px); font-weight:700; }
.h2--center{ text-align:center; margin:0 auto 2rem; max-width:40ch; }
.h2--light{ color:var(--white); }

.lead{ font-size:20px; color:var(--ink-soft); max-width:56ch; }
.lead--light{ color:#D8DDF3; }
.lead--center{ text-align:center; margin:0 auto 2.5rem; }

.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:0.5rem;
  font-weight:700; font-size:0.92rem; padding:0.85rem 1.5rem;
  border-radius:999px; border:1px solid transparent; transition:transform .15s ease, opacity .15s ease;
}
.btn:hover{ transform:translateY(-1px); }
.btn--primary{ background:var(--navy); color:var(--white); }
.btn--primary:hover{ background:var(--navy-deep); }
.btn--ghost{ background:rgba(255,255,255,0.08); border-color:rgba(255,255,255,0.4); color:var(--white); }
.btn--outline{ border-color:var(--navy); color:var(--navy); }
.btn--outline:hover{ background:var(--navy); color:var(--white); }
.btn__play{ display:inline-flex; }

/* ---------------- Navbar ---------------- */
.site-nav{
  position:sticky; top:0; z-index:50;
  background:var(--white);
  box-shadow:0 2px 10px rgba(0,14,69,0.06);
}
.site-nav__inner{
  max-width:1140px; margin:0 auto; padding:0.9rem 1.25rem;
  display:flex; align-items:center; justify-content:space-between;
}
.site-nav__logo{ display:flex; align-items:center; }
.site-nav__logo-img{ height:40px; width:auto; display:block; }
.site-nav__toggle{
  background:none; border:none; padding:0.4rem;
}
.site-nav__burger, .site-nav__burger::before, .site-nav__burger::after{
  display:block; width:22px; height:2px; background:var(--ink); position:relative;
}
.site-nav__burger::before, .site-nav__burger::after{ content:""; position:absolute; left:0; }
.site-nav__burger::before{ top:-6px; }
.site-nav__burger::after{ top:6px; }
/* Animación hamburguesa → X: la línea del medio (el propio elemento) se
   vuelve transparente sin afectar a ::before/::after (son sus hijos en
   el árbol de cajas, así que opacity en el padre también los ocultaría);
   las otras dos líneas se centran (top:0) y rotan 45°/-45° para formar
   la X. El estado abierto se lee del aria-expanded que ya pone el JS del
   toggle, sin necesidad de una clase aparte. */
.site-nav__burger, .site-nav__burger::before, .site-nav__burger::after{
  transition:background-color .25s ease, transform .3s ease, top .3s ease;
}
.site-nav__toggle[aria-expanded="true"] .site-nav__burger{ background-color:transparent; }
.site-nav__toggle[aria-expanded="true"] .site-nav__burger::before{ top:0; transform:rotate(45deg); }
.site-nav__toggle[aria-expanded="true"] .site-nav__burger::after{ top:0; transform:rotate(-45deg); }
@media (prefers-reduced-motion: reduce){
  .site-nav__burger, .site-nav__burger::before, .site-nav__burger::after{ transition:none; }
}

.site-nav__menu{
  position:absolute; top:100%; left:0; right:0;
  background:var(--white); border-bottom:1px solid var(--line);
  flex-direction:column; padding:0.5rem 1.25rem 1rem;
  display:none;
}
.site-nav__menu.is-open{ display:flex; }
.site-nav__menu a{
  padding:0.7rem 0; font-weight:600; font-size:0.92rem; color:var(--ink-soft);
  border-bottom:1px solid var(--line);
}
.site-nav__menu a.is-active{ color:var(--navy); }

/* Botón "Tienda": en hover el texto se desliza hacia arriba y sale, y el
   logo de Aquatico entra deslizando desde abajo — dos "caras" apiladas en
   .site-nav__store-slide, cada una con el alto exacto del botón, que se
   desplaza -2.6rem (un alto completo) al hacer hover. overflow:hidden en
   el botón recorta lo que queda fuera. */
.site-nav__store{
  order:1;
  margin-top:0.6rem; height:2.6rem;
  background:var(--navy); color:var(--white) !important;
  border-radius:999px; padding:0 1.2rem !important;
  font-weight:700; position:relative; overflow:hidden; border-bottom:none !important;
  display:flex; align-items:stretch;
}
.site-nav__store-slide{
  display:flex; flex-direction:column; width:100%;
  transition:transform .3s ease;
}
.site-nav__store-face{
  height:2.6rem; flex-shrink:0;
  display:flex; align-items:center; justify-content:center;
}
.site-nav__store:hover .site-nav__store-slide,
.site-nav__store:focus-visible .site-nav__store-slide{ transform:translateY(-2.6rem); }
.site-nav__store-logo{ height:16px; width:auto; }
@media (prefers-reduced-motion: reduce){
  .site-nav__store-slide{ transition:none; }
}

/* ---------------- Hero ---------------- */
.hero{
  position:relative; overflow:hidden;
  display:flex; align-items:center;
  min-height:78vh;
  padding:4rem 1.25rem;
  background:linear-gradient(155deg, var(--navy) 0%, var(--navy-deep) 100%);
  color:var(--white);
}
.hero .wrap{ position:relative; width:100%; display:flex; align-items:center; }
.hero__video-wrap{
  position:absolute; inset:0; overflow:hidden; z-index:0; pointer-events:none;
}
.hero__video{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover; border:0;
}
.hero__overlay{
  position:absolute; inset:0; z-index:1;
  pointer-events:none; /* decorativo: si no, se roba los clics del botón de play */
  background:rgba(0,0,0,0.6); /* #000000 @ 60% */
}
@media (prefers-reduced-motion: reduce){
  .hero__video-wrap{ display:none; } /* deja el fondo navy sólido de .hero */
}
.hero__content{ position:relative; z-index:2; max-width:620px; text-align:left; }
.hero__title{ font-size:clamp(2.25rem, 6vw + 1rem, 55px); line-height:1.05; color:var(--white); }
.hero__sub{ margin:1.1rem 0 0; color:#C7CEEF; max-width:44ch; }
.hero__actions{ display:flex; flex-direction:column; gap:0.8rem; margin-top:1.8rem; align-items:flex-start; }
/* ---------------- Lightbox de imágenes (proyectos) ---------------- */
.image-lightbox{ position:fixed; inset:0; z-index:200; display:flex; align-items:center; justify-content:center; padding:1.5rem; }
.image-lightbox[hidden]{ display:none; }
.image-lightbox__backdrop{ position:absolute; inset:0; background:rgba(0,15,72,0.85); }
.image-lightbox__panel{ position:relative; max-width:min(1100px, 92vw); max-height:88vh; }
.image-lightbox__panel img{ display:block; max-width:100%; max-height:88vh; margin:0 auto; border-radius:12px; object-fit:contain; }
.image-lightbox__close{
  position:absolute; top:-3.2rem; right:0; width:2.4rem; height:2.4rem; border-radius:50%;
  background:rgba(255,255,255,0.16); border:1px solid rgba(255,255,255,0.5); color:#fff;
  display:flex; align-items:center; justify-content:center;
}
.image-lightbox__close:hover{ background:rgba(255,255,255,0.28); }

/* ---------------- About ---------------- */
.about{ padding:3.5rem 0; background:var(--white); }
.about__grid{ display:grid; gap:2rem; }
.about__media{
  aspect-ratio:4/3; border-radius:var(--radius);
  background:linear-gradient(140deg, var(--sand-dark), var(--sand));
}

/* ---------------- Services ---------------- */
/* padding-bottom grande a propósito: las tarjetas en hover crecen fuera
   del flujo (position:absolute) hasta 28rem — sin este colchón, las de
   la última fila se meterían visualmente sobre la sección de Proyectos. */
.services{ padding:3.5rem 0 14rem; background:var(--mist); }
.services .h2--center{ margin-bottom:0; } /* el párrafo de abajo va pegado al título */
.services__grid{ display:grid; gap:1rem; grid-template-columns:1fr; }

/* .service-card-slot es el item real del grid — con ALTO FIJO explícito
   (no depende del contenido de la tarjeta ni de align-items:stretch del
   grid, que es lo que causaba tarjetas de alto distinto en reposo y un
   posible reajuste momentáneo del resto de la página al hacer hover).
   Con un alto fijo, el grid nunca tiene que recalcular nada, pase lo que
   pase adentro del slot. .service-card llena el slot al 100% en reposo
   (por eso las 4 quedan parejas), y al hacer hover pasa a
   position:absolute anclada en el mismo punto exacto — al salir del
   flujo, crece libre por encima de todo sin afectar al slot ni al grid.
   z-index la sube por encima de las tarjetas vecinas y de lo que sigue
   más abajo. */
.service-card-slot{ position:relative; height:15rem; }
.service-card-slot:hover{ z-index:10; }
.service-card{
  position:relative; z-index:1; width:100%;
  background:var(--white); border-radius:var(--radius); padding:1.6rem 1.3rem;
  box-shadow:var(--shadow); text-align:left;
  /* min-height Y max-height iguales (no "height") fuerzan el mismo alto
     en las 4 tarjetas en reposo, sin importar cuánto texto tenga cada
     una. En hover solo max-height sube — cada tarjeta crece según SU
     propio contenido real (no un valor fijo compartido, que es lo que
     hacía que el botón se saliera en las tarjetas con más texto), hasta
     ese techo. max-height sí se puede animar suave (a diferencia de
     height:auto), así que la transición sigue sin saltos. */
  min-height:15rem; max-height:15rem; overflow:hidden;
  transition: max-height .45s cubic-bezier(.4,0,.2,1);
}
.service-card:hover{ position:absolute; top:0; left:0; max-height:28rem; z-index:10; }

/* El cuadro del ícono se expande en hover para mostrar una imagen del
   servicio, recortada por su propio overflow:hidden (el cuadro ES la
   máscara). El margen negativo en hover lo hace "sangrar" hasta los bordes
   de la tarjeta (contrarresta el padding del .service-card), y el radio
   pasa de redondeado-completo (ícono chico) a solo-arriba (imagen ancha,
   alineada con las esquinas superiores de la tarjeta). El texto de abajo
   no necesita animación propia: al estar en flujo normal después del
   cuadro, baja solo a medida que el cuadro crece (dentro de la tarjeta,
   que ya está aislada del grid). */
.service-card__media{
  position:relative;
  width:2.6rem; height:2.6rem; margin:0 0 1rem;
  border-radius:8px; overflow:hidden;
  background-color:var(--navy); background-size:cover; background-position:center;
  transition:
    width .45s cubic-bezier(.4,0,.2,1),
    height .45s cubic-bezier(.4,0,.2,1),
    margin .45s cubic-bezier(.4,0,.2,1),
    border-radius .45s ease;
}
.service-card:hover .service-card__media{
  width:calc(100% + 2.6rem); height:11rem;
  margin:-1.6rem -1.3rem 1rem;
  border-radius: var(--radius) var(--radius) 0 0;
}
.service-card__media-tint{
  position:absolute; inset:0; background:var(--navy);
  transition:opacity .35s ease;
}
.service-card__icon{
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  transition:opacity .25s ease;
}
/* Los SVG llegaron en negro sólido/trazo negro sobre fondo transparente —
   se invierten a blanco para que se vean sobre el cuadro navy, sin tener
   que tocar los archivos originales. */
.service-card__icon-img{ width:20px; height:20px; filter:invert(1) brightness(2); }
.service-card:hover .service-card__media-tint,
.service-card:hover .service-card__icon{ opacity:0; }
@media (prefers-reduced-motion: reduce){
  .service-card, .service-card__media, .service-card__media-tint, .service-card__icon{ transition:none; }
}

.service-card h3{ font-size:1rem; text-transform:none; letter-spacing:0; margin:0 0 0.5rem; }
.service-card p{ font-size:0.88rem; color:var(--ink-soft); margin:0; }
/* Solo aparece cuando la tarjeta está expandida en hover — a alto fijo de
   reposo no le sobra espacio y no tiene sentido mostrarlo ahí. */
.service-card__cta{ display:none; margin-top:1rem; padding:0.6rem 1.2rem; font-size:0.82rem; }
.service-card:hover .service-card__cta{ display:inline-flex; }

/* En mobile no hay hover real (pantalla táctil) — el estado expandido
   pasa a ser el único estado de la tarjeta, en flujo normal (sin
   position:absolute, que era para no empujar al resto del grid al pasar
   el mouse; en columna única no hace falta). Se repiten los selectores
   :hover para pisar también un posible hover "pegado" (sticky hover) de
   algunos navegadores táctiles tras un tap. */
@media (max-width:639.98px){
  .service-card-slot, .service-card-slot:hover{ height:auto; z-index:1; }
  .service-card, .service-card:hover{
    position:relative; top:auto; left:auto; max-height:none; overflow:visible; z-index:1;
  }
  .service-card__media, .service-card:hover .service-card__media{
    width:calc(100% + 2.6rem); height:11rem;
    margin:-1.6rem -1.3rem 1rem;
    border-radius:var(--radius) var(--radius) 0 0;
  }
  .service-card__media-tint, .service-card:hover .service-card__media-tint,
  .service-card__icon, .service-card:hover .service-card__icon{ opacity:0; }
  .service-card__cta, .service-card:hover .service-card__cta{ display:inline-flex; }
  /* Sin tarjetas position:absolute que se salgan del flujo, no hace
     falta el colchón de 14rem pensado para el hover de desktop. */
  .services{ padding-bottom:3.5rem; }
}

/* ---------------- Projects ---------------- */
.projects{ padding:3.5rem 0; background:var(--navy-deep); }
.projects__grid{ display:grid; gap:0.6rem; }
.projects__item{
  position:relative; overflow:hidden;
  aspect-ratio:1; border-radius:8px;
  background:linear-gradient(140deg, #1A2A6B, #26418F); /* fallback si la imagen no carga */
  background-size:cover; background-position:center;
}

/* Fila de proyectos (home): banda de ancho completo que se desplaza sola
   hacia la izquierda muy despacio — el truco de "marquee" sin fin es
   duplicar el mismo listado dentro de .projects__track (el segundo juego
   tiene aria-hidden y sin botón de zoom, es puramente decorativo) y animar
   translateX de 0% a -50%: como los dos juegos miden lo mismo, -50% es
   exactamente el ancho de UN juego, así que el salto de vuelta a 0% es
   invisible y el loop se ve continuo. La duración (--marquee-duration, en
   segundos, calculada en PHP a partir de la cantidad de proyectos) mantiene
   la MISMA velocidad en píxeles/segundo sin importar cuántas imágenes haya,
   en vez de una duración fija que aceleraría o frenaría según el total. */
.projects__marquee{ overflow:hidden; margin:2rem 0; }
.projects__track{
  display:flex; gap:0.6rem; width:max-content;
  animation:projects-marquee var(--marquee-duration, 60s) linear infinite;
}
.projects__marquee:hover .projects__track,
.projects__track:focus-within{ animation-play-state:paused; }
.projects__marquee .projects__item{ flex:0 0 220px; }
@keyframes projects-marquee{
  from{ transform:translateX(0); }
  to{ transform:translateX(-50%); }
}
@media (prefers-reduced-motion: reduce){
  .projects__track{ animation:none; }
}
@media (min-width:640px){
  .projects__marquee .projects__item{ flex-basis:260px; }
}
.projects__zoom{
  position:absolute; top:50%; left:50%; z-index:2;
  transform:translate(-50%, -50%) scale(0.7);
  width:2.6rem; height:2.6rem; border-radius:50%;
  background:rgba(0,15,72,0.55); border:1px solid rgba(255,255,255,0.6); color:#fff;
  display:flex; align-items:center; justify-content:center;
  opacity:0; transition:opacity .2s ease, transform .2s ease, background .2s ease;
}
.projects__item:hover .projects__zoom,
.projects__zoom:focus-visible{
  opacity:1; transform:translate(-50%, -50%) scale(1);
}
.projects__zoom:hover{ background:rgba(0,15,72,0.75); }
@media (prefers-reduced-motion: reduce){
  .projects__zoom{ transition:none; }
}

/* ---------------- Testimonials ---------------- */
.testimonials{ padding:3.5rem 0; background:var(--white); }
.testimonials__viewport{ position:relative; }
/* Scroll horizontal en una sola línea — así caben todos los testimonios
   sin importar cuántos haya, en vez de un grid que se desborda o
   comprime en varias filas. mask-image difumina los bordes izquierdo y
   derecho (mismo recurso que .keyword-row) en vez de cortar la tarjeta de
   golpe — así se nota que hay más contenido para desplazar. El padding
   lateral es mayor que el fade: deja aire entre las flechas y la primera/
   última tarjeta, así en reposo el degradado no las tapa ni se monta sobre
   ellas. Barra de scroll oculta (scrollbar-width/::-webkit-scrollbar) —
   el desplazamiento sigue funcionando igual, solo no se ve el control nativo. */
.testimonials__scroll{
  /* overflow-y:clip (no "visible"): con overflow-x:auto, "visible" en el
     otro eje se recalcula solo a "auto" por spec — clip es el único
     valor que de verdad evita el mini-scroll vertical (y el recorte de
     las tarjetas que causaba) sin heredar scroll en Y. */
  display:flex; gap:1rem; overflow-x:auto; overflow-y:clip;
  margin:0 -1.25rem; padding:0.25rem 3.5rem 1rem;
  scroll-snap-type:x proximity; -webkit-overflow-scrolling:touch; scroll-behavior:smooth;
  -webkit-mask-image:linear-gradient(to right, transparent, black 56px, black calc(100% - 56px), transparent);
  mask-image:linear-gradient(to right, transparent, black 56px, black calc(100% - 56px), transparent);
  scrollbar-width:none; -ms-overflow-style:none;
}
.testimonials__scroll::-webkit-scrollbar{ display:none; }
/* Tarjeta horizontal: imagen y texto se ven como dos paneles independientes
   (cada uno con su propio radio y sombra, separados por un gap) pero son
   la MISMA tarjeta — un solo flex item que las agrupa. Sin alto fijo:
   align-items:stretch (default de flex-direction:row) en
   .testimonials__scroll ya iguala la altura de todas las tarjetas de la
   fila a la de la más alta, y justify-content:center en el body centra el
   texto verticalmente dentro de ese alto cuando el testimonio es corto. */
.testimonial-card{
  flex:0 0 380px; scroll-snap-align:start;
  margin:0; gap:0.7rem;
  display:flex; flex-direction:row;
}
/* Placeholder en degradado (mismo recurso que .about__media/.service-row__media)
   hasta que falte una imagen real; si el testimonio trae 'image', esa url
   se aplica inline y pisa el degradado. */
.testimonial-card__media{
  width:170px; flex:0 0 170px; border-radius:var(--radius);
  background:linear-gradient(140deg, var(--sand-dark), var(--sand)) center/cover no-repeat;
}
.testimonial-card__body{
  position:relative; overflow:hidden;
  flex:1 1 auto; min-width:0;
  background:var(--mist); border-radius:var(--radius);
  display:flex; flex-direction:column; justify-content:center;
  padding:1.4rem 1.2rem 1.2rem;
}
/* Comilla grande decorativa: la de apertura en azul de marca, chica y sobre
   el texto; la de cierre gigante, azul al 15% de opacidad, de fondo,
   recortada por el overflow:hidden del panel — mismo glyph SVG
   (format_quote), rotado 180° para la de cierre. */
.testimonial-card__quote-open{ display:block; color:var(--navy); margin-bottom:0.4rem; }
.testimonial-card__quote-close{
  position:absolute; right:-0.5rem; bottom:-0.8rem; z-index:0;
  color:var(--navy); opacity:0.15; transform:rotate(180deg); pointer-events:none;
}
.testimonial-card__body > p,
.testimonial-card__body > cite,
.testimonial-card__body > span{ position:relative; z-index:1; }
.testimonial-card__body p{ font-size:0.8rem; color:var(--ink-soft); margin:0 0 0.8rem; }
.testimonial-card__name{ display:block; font-style:normal; font-weight:700; font-size:0.82rem; }
.testimonial-card__role{ display:block; font-weight:500; font-size:0.74rem; color:var(--ink-soft); margin-top:0.1rem; }
.testimonial-card__project{ font-size:0.7rem; color:var(--ink-faint); opacity:0.65; margin:0.5rem 0 0; }

/* Flechas de desplazamiento — círculo del color de acento (--teal),
   centradas verticalmente sobre el borde de la fila. */
.testimonials__arrow{
  position:absolute; top:50%; transform:translateY(-50%); z-index:2;
  width:2.6rem; height:2.6rem; border-radius:50%; border:none;
  background:var(--teal); color:var(--white);
  display:flex; align-items:center; justify-content:center;
  box-shadow:var(--shadow); transition:background .2s ease, transform .15s ease;
}
.testimonials__arrow:hover{ background:var(--teal-dark); transform:translateY(-50%) scale(1.06); }
.testimonials__arrow--prev{ left:-0.4rem; }
.testimonials__arrow--next{ right:-0.4rem; }
/* En mobile las flechas dejan de flotar sobre los bordes de las tarjetas
   (ahí estorban en pantallas angostas) y bajan juntas debajo de la fila.
   El truco es flex-wrap:wrap en el viewport con .testimonials__scroll a
   flex-basis:100% — al ocupar toda la línea fuerza el salto de renglón,
   y las dos flechas (sin basis) quedan juntas en el renglón siguiente,
   sin necesidad de envolverlas en un contenedor aparte. Se quita también
   el degradado de los bordes y el padding lateral que dejaba hueco antes
   de la primera/última tarjeta, para que lleguen hasta el borde real de
   la pantalla. */
@media (max-width:639.98px){
  .testimonials__viewport{
    display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:0.9rem;
  }
  .testimonials__scroll{
    order:1; flex-basis:100%;
    margin:0 -1.25rem; padding:0.25rem 0 0.25rem;
    -webkit-mask-image:none; mask-image:none;
  }
  .testimonials__arrow{ position:static; order:2; transform:none; }
  .testimonials__arrow:hover{ transform:scale(1.06); }
}
@media (min-width:640px){
  .testimonial-card{ flex-basis:440px; }
  .testimonials__arrow--prev{ left:-1.3rem; }
  .testimonials__arrow--next{ right:-1.3rem; }
}
@media (prefers-reduced-motion: reduce){
  .testimonials__scroll{ scroll-behavior:auto; }
  .testimonials__arrow{ transition:none; }
}

/* ---------------- Blog teaser ---------------- */
.blog-teaser{ padding:3rem 0; background:var(--mist); }
.blog-teaser__inner{
  display:flex; flex-direction:column; gap:1.5rem; align-items:flex-start;
}

/* ---------------- Página "en desarrollo" (Tienda Aquatico) ---------------- */
/* Sin footer en esta página (a propósito, ver tienda.php) — llena el resto
   del viewport bajo el navbar para no dejar un espacio en blanco vacío
   donde iría el footer. */
.coming-soon{
  min-height:calc(100vh - 73px); display:flex; align-items:center; justify-content:center; text-align:center;
  padding:4rem 1.25rem;
  background:linear-gradient(155deg, var(--navy) 0%, var(--navy-deep) 100%);
}
.coming-soon__title{ color:var(--white); font-size:clamp(2rem, 5vw + 1rem, 55px); }

/* ---------------- Closing / Contacto ---------------- */
.closing{
  position:relative; padding:4rem 1.25rem; text-align:center; overflow:hidden;
  background:linear-gradient(155deg, var(--navy-deep), #001B7A);
}
.closing__media{
  position:absolute; inset:0;
  background:radial-gradient(circle at 20% 80%, rgba(11,167,154,0.35), transparent 55%);
}
.closing__content{ position:relative; display:flex; flex-direction:column; align-items:center; gap:1rem; }
.closing .btn--primary{ background:var(--white); color:var(--navy); }
.closing .btn--primary:hover{ background:var(--navy-deep); color:var(--white); }

/* ---------------- Footer ---------------- */
.site-footer{ background:var(--navy-deep); color:#B9C0E6; padding:2.75rem 1.25rem 1.5rem; }
.site-footer__inner{
  max-width:1140px; margin:0 auto; display:grid; gap:2.2rem;
  grid-template-columns:1fr;
}
.site-footer__col p{ font-size:0.85rem; max-width:34ch; margin:0 0 0.5rem; }
.site-footer__col p a{ color:inherit; text-decoration:underline; text-decoration-color:rgba(185,192,230,0.4); text-underline-offset:2px; }
.site-footer__col p a:hover{ color:var(--white); text-decoration-color:var(--teal); }
.site-footer__heading{
  font-size:0.78rem; font-weight:700; letter-spacing:0.06em; text-transform:uppercase;
  color:var(--white); margin-bottom:0.9rem;
}
.site-footer__logo{ height:32px; width:auto; display:block; margin-bottom:0.6rem; }
.site-footer__social{ display:flex; gap:0.8rem; margin-top:1rem; }
.site-footer__social a{
  width:2rem; height:2rem; border-radius:50%; background:rgba(255,255,255,0.1);
  display:flex; align-items:center; justify-content:center;
}
.site-footer__social svg{ width:1rem; height:1rem; fill:var(--white); }
.site-footer__links{ display:flex; flex-direction:column; gap:0.7rem; font-size:0.85rem; }
.site-footer__legal{ text-align:center; font-size:0.75rem; color:#8189B0; margin:2rem 0 0; }

/* ---------------- Encabezado de página interna ---------------- */
.page-header{
  padding:2.8rem 1.25rem 2.2rem;
  background:var(--mist);
  border-bottom:1px solid var(--line);
}
/* Banner navy con letra blanca del design-canvas — aplicado a todas las
   subpáginas (antes solo lo tenía proyectos.php). El glow radial es el
   mismo detalle decorativo que ya usa .hero. */
.page-header--dark{
  position:relative; overflow:hidden;
  background:linear-gradient(155deg, var(--navy) 0%, var(--navy-deep) 100%);
  border-bottom:none;
}
.page-header--dark::before{
  content:""; position:absolute; width:480px; height:480px; border-radius:50%;
  background:radial-gradient(circle, rgba(11,167,154,0.3), transparent 65%);
  top:-200px; right:-120px; pointer-events:none;
}
/* Header de la subpágina de Proyectos: mismo título que .page-header--dark
   pero sin el banner degradado ni el glow — fondo azul oscuro sólido, igual
   al de la sección .projects de más abajo, para que ambas se vean como un
   único bloque continuo en vez de una franja separada. */
.page-header--projects{
  position:relative; overflow:hidden;
  background:var(--navy-deep);
  border-bottom:none;
}
.page-header__title{ position:relative; font-size:clamp(2rem, 5vw + 1rem, 55px); }
.page-header__title--light{ color:var(--white); }
.page-header__row{ position:relative; display:flex; align-items:center; justify-content:space-between; gap:1.5rem; flex-wrap:wrap; }

/* ---------------- Teasers de sección (home) ---------------- */
.section-teaser__cta{ text-align:center; margin-top:2rem; }
.btn--on-dark{ border-color:rgba(255,255,255,0.4); }

/* ---------------- Servicios (página detallada) ---------------- */
.services-detail{ padding:3rem 0 1rem; background:var(--white); }
.service-row{
  display:grid; gap:1.5rem; align-items:center;
  padding:2.2rem 0; border-bottom:1px solid var(--line);
}
.service-row:last-child{ border-bottom:none; }
.service-row__media{
  aspect-ratio:4/3; border-radius:var(--radius);
  background:linear-gradient(140deg, var(--sand-dark), var(--sand));
}
.service-row__body h2{ font-size:1.4rem; margin-bottom:0.7rem; }
.service-row__body .lead{ margin-bottom:1.1rem; }

/* ---------------- Galería "en obra" (Nosotros) ---------------- */
.about-gallery{ padding:1rem 0 3.5rem; background:var(--white); }
.projects__item--light{ background:linear-gradient(140deg, var(--sand-dark), var(--sand)); }
.projects--full{ padding-top:3rem; }

/* Galería de la subpágina de Proyectos: mosaico de columnas CSS en vez de
   un grid de celdas con column-span — ese enfoque anterior dejaba huecos
   cuando el algoritmo "dense" no encontraba una imagen del tamaño justo
   para tapar el espacio libre. column-count apila cada imagen debajo de la
   anterior EN SU PROPIA COLUMNA, así que nunca queda un espacio suelto sin
   llenar, sea que la fila se reparta en 2, 3 o 4 columnas. El parámetro que
   define el tamaño (alto) de cada imagen es su POSICIÓN en la lista:
   nth-child cicla un patrón de 5 proporciones distintas. */
.projects--full .projects__grid{
  display:block; column-count:2; column-gap:0.6rem;
}
.projects--full .projects__item{
  break-inside:avoid; -webkit-column-break-inside:avoid;
  width:100%; margin:0 0 0.6rem; aspect-ratio:1; border-radius:14px;
}
.projects--full .projects__item:nth-child(5n+2){ aspect-ratio:3/4; }
.projects--full .projects__item:nth-child(5n+4){ aspect-ratio:4/5; }
.projects--full .projects__item:nth-child(5n+5){ aspect-ratio:1/1.4; }
@media (min-width:640px){
  .projects--full .projects__grid{ column-count:3; }
}
@media (min-width:1024px){
  .projects--full .projects__grid{ column-count:4; }
}

/* ---------------- Blog ---------------- */
.blog-index{ padding:3rem 0 1rem; background:var(--white); }

.blog-search{ margin:0; }
.blog-search input{
  width:280px; max-width:100%; padding:0.7rem 1rem; border-radius:9px;
  border:1px solid rgba(255,255,255,0.35); background:rgba(255,255,255,0.12);
  color:var(--white); font-size:0.9rem; font-family:inherit;
}
.blog-search input::placeholder{ color:rgba(255,255,255,0.7); }
.blog-search input:focus{ outline:none; border-color:rgba(255,255,255,0.7); background:rgba(255,255,255,0.18); }
.blog-search input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,0.75)' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'/%3E%3Cline x1='6' y1='6' x2='18' y2='18'/%3E%3C/svg%3E") no-repeat center center;
  background-size: 13px 13px;
  cursor: pointer;
  opacity: 0.8;
  transition: opacity .18s ease, transform .18s ease;
  margin-left: 0.5rem;
}
.blog-search input::-webkit-search-cancel-button:hover {
  opacity: 1;
  transform: scale(1.15);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'/%3E%3Cline x1='6' y1='6' x2='18' y2='18'/%3E%3C/svg%3E");
}

.blog-filters{ display:flex; flex-wrap:wrap; gap:0.6rem; margin-bottom:2rem; }
.blog-filter-pill{
  display:inline-flex; align-items:center; padding:0.4rem 1rem; border-radius:999px;
  font-size:0.82rem; font-weight:700; border:1.5px solid var(--tag-color, var(--line));
  color:var(--tag-color, var(--ink-soft)); background:#fff; text-decoration:none;
}
.blog-filter-pill.is-active{ background:var(--tag-color, var(--navy)); color:#fff; border-color:var(--tag-color, var(--navy)); }

.blog-empty{ text-align:center; color:var(--ink-faint); padding:2rem 0 3rem; }
.blog-empty a{ color:var(--navy); font-weight:600; }

/* Badge de tag — mismo componente visual que el panel admin: rectángulo de
   esquinas redondeadas, relleno del color del tag. */
.tag-ribbon{
  position:absolute; top:0.9rem; left:0.9rem; z-index:2; display:inline-flex; align-items:center;
  height:24px; padding:0 14px; font-size:0.72rem; font-weight:700; color:#fff;
  background:var(--tag-color, var(--navy)); border-radius:999px; white-space:nowrap;
  text-transform:none; letter-spacing:0;
}

/* Keywords tipo hashtag — una sola línea con fade a la derecha si no caben
   (mask-image); en la página de post individual se usa --wrap para verlas todas. */
.keyword-row{
  display:flex; flex-wrap:nowrap; gap:0.4rem; overflow:hidden; margin-top:0.7rem;
  -webkit-mask-image:linear-gradient(to right, black calc(100% - 48px), transparent 100%);
  mask-image:linear-gradient(to right, black calc(100% - 48px), transparent 100%);
}
.keyword-row--wrap{ flex-wrap:wrap; overflow:visible; -webkit-mask-image:none; mask-image:none; }
.keyword-chip{
  flex:none; font-size:0.72rem; font-weight:600; color:var(--ink-soft); opacity:0.4;
  border:1px solid var(--ink-soft); border-radius:999px; padding:0.15rem 0.6rem; white-space:nowrap;
}

.blog-grid{ display:grid; gap:1.4rem; grid-template-columns:1fr; padding-bottom:3rem; }
.blog-card{ position:relative; border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow); }
.blog-card__thumb{
  display:block; aspect-ratio:16/10;
  background:linear-gradient(140deg, var(--navy), var(--teal)) center/cover no-repeat;
}
.blog-card__body{ padding:1.2rem 1.3rem; background:var(--white); }
.blog-card__body time{ font-size:0.72rem; color:var(--ink-faint); text-transform:uppercase; letter-spacing:0.05em; }
.blog-card__body h2{ font-size:1.1rem; text-transform:none; letter-spacing:0; margin:0.4rem 0 0; }
.blog-card__body h2 a{ color:var(--ink); }
.blog-card__body h2 a:hover{ color:var(--navy); }

/* Tarjeta fijada — ancho completo, imagen a la derecha en desktop (columna
   invertida en móvil vía DOM: body primero, imagen después, ver post.php/index.php). */
.blog-card--pinned{
  position:relative; display:flex; flex-direction:column-reverse; border-radius:var(--radius);
  overflow:hidden; box-shadow:var(--shadow); margin-bottom:1.6rem;
}
.blog-card--pinned__body{ padding:3.2rem 1.8rem 1.8rem; background:var(--white); display:flex; flex-direction:column; gap:0.5rem; justify-content:center; }
.blog-card--pinned__body time{ font-size:0.72rem; color:var(--ink-faint); text-transform:uppercase; letter-spacing:0.05em; }
.blog-card--pinned__body h2{ font-size:1.6rem; margin:0.2rem 0 0.4rem; text-transform:none; letter-spacing:0; }
.blog-card--pinned__body h2 a{ color:var(--ink); }
.blog-card--pinned__body h2 a:hover{ color:var(--navy); }
.blog-card--pinned__body p{ color:var(--ink-soft); margin:0; }
.blog-card--pinned__media{
  display:block; aspect-ratio:16/9;
  background:linear-gradient(140deg, var(--navy), var(--teal)) center/cover no-repeat;
}

/* Banner del post individual — el header oscuro pasa a mostrar la imagen de
   portada (más alto para que se vea bien), con el mismo botón de ampliar de
   Proyectos (.projects__zoom, centrado, visible al hover/focus). */
.blog-post-banner{
  min-height:340px; background-size:cover; background-position:center; background-repeat:no-repeat;
}
.blog-post-banner::before{ display:none; }
@media (min-width: 768px){
  .blog-post-banner{ min-height:440px; }
}
.blog-post-banner:hover .projects__zoom,
.blog-post-banner .projects__zoom:focus-visible{
  opacity:1; transform:translate(-50%, -50%) scale(1);
}

.blog-post{ padding:2.5rem 0 1rem; background:var(--white); }
.blog-post__wrap{ max-width:720px; }
.blog-post__title{ font-size:clamp(1.7rem, 4vw + 1rem, 42px); margin:0.5rem 0 1.4rem; }
.blog-post__content{ font-size:20px; color:var(--ink-soft); margin-bottom:1.2rem; }
.blog-post__content p{ margin:0 0 1.2rem; }
.blog-post__keywords{ border-top:1px solid var(--line); padding-top:1.4rem; margin-bottom:2rem; }
.blog-post__keywords-label{
  display:block; font-size:0.75rem; font-weight:700; text-transform:uppercase;
  letter-spacing:0.05em; color:var(--ink-faint); margin-bottom:0.7rem;
}
.blog-post__back{
  display:inline-flex; align-items:center; gap:0.4rem; color:var(--ink-soft);
  font-weight:600; font-size:0.9rem; text-decoration:none;
}
.blog-post__back:hover{ color:var(--navy); }

/* ---------------- Botón "volver arriba" ---------------- */
.back-to-top{
  position:fixed; left:50%; bottom:1.1rem; z-index:59;
  transform:translateX(-50%) translateY(0.6rem);
  width:2.2rem; height:2.2rem; border-radius:50%; border:none;
  background:var(--navy); color:var(--white); display:flex; align-items:center; justify-content:center;
  box-shadow:0 6px 16px rgba(0,14,69,0.3);
  opacity:0; pointer-events:none;
  transition:opacity .2s ease, transform .2s ease;
}
.back-to-top.is-visible{ opacity:1; pointer-events:auto; transform:translateX(-50%) translateY(0); }
.back-to-top:hover{ background:var(--navy-deep); }
@media (prefers-reduced-motion: reduce){ .back-to-top{ transition:opacity .2s ease; } }

/* ---------------- WhatsApp float button ---------------- */
.wa-float{
  position:fixed; right:1.1rem; bottom:1.1rem; z-index:60;
  width:3.4rem; height:3.4rem; border-radius:50%;
  background:var(--wa-green); display:flex; align-items:center; justify-content:center;
  box-shadow:0 10px 24px rgba(0,0,0,0.25);
  transition:transform .2s ease, background .2s ease;
  line-height:0;
}
.wa-float:hover{ transform:scale(1.08); background:var(--wa-green-dark); }
.wa-float svg{ width:30px; height:30px; display:block; margin:auto; }

/* ---------------- Scroll reveal ---------------- */
/* Aparición al hacer scroll, en toda la web (mobile y desktop). JS
   (main.js) solo agrega/quita "is-visible" vía IntersectionObserver, una
   sola vez por elemento — no se repite si subes y bajas el scroll otra
   vez. Progressive enhancement real: [data-reveal]/[data-reveal-media] se
   ven normales por defecto; el estado oculto-antes-de-revelar SOLO se
   activa si <html> tiene "js-reveal-ready", que un script inline en
   <head> agrega nada más si el navegador soporta IntersectionObserver
   (ver head-meta.php) — el contenido nunca depende de JS para mostrarse,
   solo la animación de entrada. */
[data-reveal]{
  transition: opacity .6s cubic-bezier(0,0,.2,1), transform .6s cubic-bezier(0,0,.2,1);
}
.js-reveal-ready [data-reveal]{ opacity:0; transform:translateY(28px); }
.js-reveal-ready [data-reveal].is-visible{ opacity:1; transform:none; }

/* Imágenes/tarjetas: el propio contenedor (ya recortado por su
   border-radius normal) hace de máscara — clip-path lo "cierra" del todo
   y se va abriendo de abajo hacia arriba, como una cortina, en vez de
   solo aparecer. Al llegar a inset(0) no hay ningún recorte extra y el
   contenedor vuelve a mostrar su propio border-radius tal cual. */
[data-reveal-media]{
  transition: opacity .6s cubic-bezier(0,0,.2,1), clip-path .7s cubic-bezier(0,0,.2,1);
}
/* opacity (no solo clip-path) es lo que de verdad los oculta: un
   clip-path que recorta el 100% del elemento le deja área renderizada
   cero, y con área cero Chrome nunca lo reporta como "entrando en
   pantalla" — el IntersectionObserver queda esperando para siempre un
   elemento que, para el navegador, nunca mide nada. Con opacity de por
   medio (mismo mecanismo ya probado en los textos) el disparo del reveal
   no depende de que el clip-path tenga área. */
.js-reveal-ready [data-reveal-media]{ opacity:0; clip-path: inset(55% 0 0 0); }
.js-reveal-ready [data-reveal-media].is-visible{ opacity:1; clip-path: inset(0 0 0 0); }

/* Cascada en grupos chicos apilados verticalmente (hero, banda de cierre
   de WhatsApp): cada hijo directo entra un poco después que el anterior.
   Sirve para cualquier bloque texto+texto+botón marcado con
   data-reveal-group, no hace falta una regla por sección. */
[data-reveal-group] > *:nth-child(2){ transition-delay:90ms; }
[data-reveal-group] > *:nth-child(3){ transition-delay:180ms; }
[data-reveal-group] > *:nth-child(4){ transition-delay:270ms; }

/* Cascada en grids/filas de tarjetas repetidas (servicios, blog,
   proyectos): el retraso depende de la posición de la TARJETA, no del
   elemento con data-reveal en sí — así funciona igual cuando la tarjeta
   anima su imagen y su texto por separado (dos elementos anidados). Los
   testimonios (carrusel horizontal) quedan afuera a propósito: cada
   tarjeta ahí aparece en un momento distinto (scroll de página para la
   primera, flecha del carrusel para las siguientes), no tiene sentido
   escalonarlas entre sí. */
.services__grid > .service-card-slot:nth-child(2) [data-reveal],
.services__grid > .service-card-slot:nth-child(2) [data-reveal-media],
.blog-grid > .blog-card:nth-child(2) [data-reveal],
.blog-grid > .blog-card:nth-child(2) [data-reveal-media],
.projects__grid > .projects__item:nth-child(2){ transition-delay:90ms; }

.services__grid > .service-card-slot:nth-child(3) [data-reveal],
.services__grid > .service-card-slot:nth-child(3) [data-reveal-media],
.blog-grid > .blog-card:nth-child(3) [data-reveal],
.blog-grid > .blog-card:nth-child(3) [data-reveal-media],
.projects__grid > .projects__item:nth-child(3){ transition-delay:180ms; }

.services__grid > .service-card-slot:nth-child(4) [data-reveal],
.services__grid > .service-card-slot:nth-child(4) [data-reveal-media],
.blog-grid > .blog-card:nth-child(4) [data-reveal],
.blog-grid > .blog-card:nth-child(4) [data-reveal-media],
.projects__grid > .projects__item:nth-child(4){ transition-delay:270ms; }

.blog-grid > .blog-card:nth-child(5) [data-reveal],
.blog-grid > .blog-card:nth-child(5) [data-reveal-media],
.projects__grid > .projects__item:nth-child(5){ transition-delay:360ms; }

.blog-grid > .blog-card:nth-child(6) [data-reveal],
.blog-grid > .blog-card:nth-child(6) [data-reveal-media],
.projects__grid > .projects__item:nth-child(6){ transition-delay:450ms; }

@media (prefers-reduced-motion: reduce){
  [data-reveal], [data-reveal-media]{ transition:none; }
  .js-reveal-ready [data-reveal],
  .js-reveal-ready [data-reveal-media]{ opacity:1; transform:none; clip-path:none; }
}

/* =============== Breakpoints =============== */
@media (min-width: 640px){
  .services__grid{ grid-template-columns:repeat(2, 1fr); }
  .hero__actions{ flex-direction:row; justify-content:flex-start; }
  .site-footer__inner{ grid-template-columns:1fr 1fr; }
  .blog-grid{ grid-template-columns:repeat(2, 1fr); }
  .blog-card--pinned{ flex-direction:row; }
  .blog-card--pinned__body, .blog-card--pinned__media{ flex:1 1 50%; }
  .blog-card--pinned__media{ aspect-ratio:auto; }
}

@media (min-width: 1024px){
  .site-nav__toggle{ display:none; }
  .site-nav__menu{
    position:static; display:flex !important; flex-direction:row; align-items:center;
    border-bottom:none; padding:0; background:transparent; gap:1.1rem;
  }
  .site-nav__menu a{ border-bottom:none; padding:0; font-size:0.86rem; white-space:nowrap; }
  .site-nav__store{ order:0; margin-top:0; }

  .services__grid{ grid-template-columns:repeat(4, 1fr); }
  .about__grid{ grid-template-columns:1fr 1fr; align-items:center; }
  .blog-teaser__inner{ flex-direction:row; align-items:center; justify-content:space-between; }

  .site-footer__inner{ grid-template-columns:1.4fr 1fr 1fr; }

  .service-row{ grid-template-columns:1fr 1fr; gap:3rem; }
  .service-row--reverse .service-row__media{ order:2; }
  .service-row--reverse .service-row__body{ order:1; }

  .blog-grid{ grid-template-columns:repeat(3, 1fr); }
}
