/* ==========================================================================
   gt-ui.css · Capa de interacción compartida de grupoterra.com.co
   --------------------------------------------------------------------------
   Vive fuera de <x-dc>: se carga desde el <head> real de cada página, así que
   no depende del render de support.js y está disponible antes del primer
   pintado. Solo añade comportamiento (movimiento, estados, navegación móvil);
   la identidad visual la siguen fijando los tokens del manual de marca.
   Fuente de verdad de color y escala: design-system/grupo-terra/MASTER.md
   ========================================================================== */

:root{
  --gt-ease:cubic-bezier(.2,.7,.2,1);
  --gt-rapido:.2s;
  --gt-medio:.42s;
  --gt-lento:.8s;
  --gt-z-nav:60;
  --gt-z-flotante:40;
  --gt-z-carga:90;

  /* Réplica de los tokens de marca imprescindibles, por si este archivo se
     carga antes de que la página declare los suyos. Las páginas los redefinen. */
  --claro:#D7EEBB; --teal:#009683; --logo:#A0C878;
  --profundo:#1F3719; --blanco:#FFFFFF; --carbon:#2F2E2D;
  --teal-texto:#007264;
}

/* ==========================================================================
   1 · Pantalla de carga
   Se pinta desde el HTML, antes de que React y support.js hayan resuelto.
   Se retira añadiendo .gt-ready al <html>; nunca bloquea más de 6 s.
   ========================================================================== */
.gt-carga{
  position:fixed;inset:0;z-index:var(--gt-z-carga);
  background:var(--claro);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:26px;
  transition:opacity .5s ease,visibility .5s ease;
}
html.gt-ready .gt-carga{opacity:0;visibility:hidden;pointer-events:none;}
.gt-carga[hidden]{display:none!important;}
.gt-carga-marca{width:132px;height:auto;animation:gt-latido 2.2s var(--gt-ease) infinite;}
.gt-carga-barra{
  width:min(200px,44vw);height:2px;border-radius:2px;
  background:rgba(31,55,25,.14);overflow:hidden;
}
.gt-carga-barra::after{
  content:"";display:block;height:100%;width:42%;border-radius:2px;
  background:var(--teal-texto);animation:gt-recorre 1.15s var(--gt-ease) infinite;
}
.gt-carga-pie{
  font-family:"General Sans",Helvetica,Arial,sans-serif;
  font-size:12px;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(31,55,25,.55);
}
@keyframes gt-latido{0%,100%{opacity:1;transform:none}50%{opacity:.55;transform:scale(.97)}}
@keyframes gt-recorre{0%{transform:translateX(-105%)}100%{transform:translateX(340%)}}

/* Entrada y salida de página. El guion enciende .gt-saliendo al pulsar un
   enlace interno; el navegador descarta el estilo al navegar, así que no hace
   falta limpiarlo. */
#dc-root{animation:gt-entra .5s var(--gt-ease) both;}
html.gt-saliendo #dc-root{opacity:0;transition:opacity .22s ease;}
@keyframes gt-entra{from{opacity:0}to{opacity:1}}

/* ==========================================================================
   2 · Revelado al hacer scroll
   El atributo data-gt-anim marca el gesto; .gt-in lo dispara. El guion añade
   la clase con IntersectionObserver, así que funciona en todos los navegadores
   (a diferencia de animation-timeline:view(), solo Chromium). Sin JavaScript
   el contenido se ve completo y quieto: el estado de reposo solo se aplica
   cuando el guion ha marcado el documento con .gt-js.
   ========================================================================== */
html.gt-js [data-gt-anim]{
  opacity:0;
  transition:opacity var(--gt-lento) var(--gt-ease),transform var(--gt-lento) var(--gt-ease);
  transition-delay:var(--gt-d,0ms);
  will-change:opacity,transform;
}
html.gt-js [data-gt-anim="sube"]     {transform:translateY(26px);}
html.gt-js [data-gt-anim="baja"]     {transform:translateY(-20px);}
html.gt-js [data-gt-anim="izquierda"]{transform:translateX(-30px);}
html.gt-js [data-gt-anim="derecha"]  {transform:translateX(30px);}
html.gt-js [data-gt-anim="acerca"]   {transform:scale(.955);}
html.gt-js [data-gt-anim="traza"]    {transform:scaleX(0);transform-origin:left;opacity:1;}
html.gt-js [data-gt-anim].gt-in{opacity:1;transform:none;}
html.gt-js [data-gt-anim="traza"].gt-in{transform:scaleX(1);}
/* Una vez revelado, el elemento deja de reservar capa de composición. */
html.gt-js [data-gt-anim].gt-visto{will-change:auto;}

/* ==========================================================================
   3 · Esqueletos de imagen
   El hueco verde del manual ya hace de marcador; aquí solo se le añade el
   barrido y el fundido de entrada de la fotografía cuando termina de cargar.
   ========================================================================== */
.gt-skel{position:relative;overflow:hidden;}
.gt-skel::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(100deg,
    rgba(255,255,255,0) 20%,rgba(255,255,255,.42) 48%,rgba(255,255,255,0) 76%);
  background-size:220% 100%;
  animation:gt-barrido 1.5s ease-in-out infinite;
}
.gt-skel.gt-cargada::after{animation:none;opacity:0;transition:opacity .4s ease;}
@keyframes gt-barrido{0%{background-position:120% 0}100%{background-position:-120% 0}}

html.gt-js img.gt-fade{opacity:0;transition:opacity .55s ease;}
html.gt-js img.gt-fade.gt-cargada{opacity:1;}

/* Bloques de texto en carga. */
.gt-skel-linea{
  height:1em;border-radius:6px;background:rgba(31,55,25,.10);
  position:relative;overflow:hidden;
}
.gt-skel-linea::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(100deg,rgba(255,255,255,0) 20%,rgba(255,255,255,.55) 48%,rgba(255,255,255,0) 76%);
  background-size:220% 100%;animation:gt-barrido 1.4s ease-in-out infinite;
}

/* ==========================================================================
   4 · Microinteracciones
   Regla del sistema: el hover levanta y oscurece, el :active hunde. Ningún
   estado depende solo del color, para no perder la señal en daltonismo.
   ========================================================================== */
.gt-press{transition:transform var(--gt-rapido) var(--gt-ease),
                    box-shadow var(--gt-rapido) var(--gt-ease),
                    background var(--gt-rapido) ease,
                    color var(--gt-rapido) ease,
                    border-color var(--gt-rapido) ease;}
.gt-press:hover{transform:translateY(-2px);box-shadow:0 12px 26px rgba(31,55,25,.18);}
.gt-press:active{transform:translateY(0) scale(.985);box-shadow:0 4px 10px rgba(31,55,25,.14);}

/* Botón sólido del sistema, con brillo que barre al pasar. */
.gt-btn{
  position:relative;overflow:hidden;isolation:isolate;
  display:inline-flex;align-items:center;justify-content:center;gap:12px;
  border:1px solid transparent;border-radius:999px;cursor:pointer;
  font-family:inherit;font-size:var(--cuerpo,18px);line-height:1.4;
  padding:14px 30px;background:var(--teal-texto);color:var(--blanco);
  text-decoration:none;
  transition:transform var(--gt-rapido) var(--gt-ease),
             box-shadow var(--gt-rapido) var(--gt-ease),
             background var(--gt-rapido) ease,color var(--gt-rapido) ease,
             border-color var(--gt-rapido) ease;
}
.gt-btn::before{
  content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(120deg,transparent 25%,rgba(255,255,255,.22) 50%,transparent 75%);
  background-size:250% 100%;background-position:130% 0;
  transition:background-position .6s var(--gt-ease);
}
.gt-btn:hover{background:var(--profundo);color:var(--blanco);transform:translateY(-2px);
              box-shadow:0 14px 30px rgba(31,55,25,.22);}
.gt-btn:hover::before{background-position:-130% 0;}
.gt-btn:active{transform:translateY(0) scale(.985);box-shadow:0 4px 10px rgba(31,55,25,.16);}
.gt-btn[disabled],.gt-btn[aria-disabled="true"]{opacity:.55;pointer-events:none;}
.gt-btn-linea{background:transparent;color:var(--profundo);border-color:rgba(31,55,25,.42);}
.gt-btn-linea:hover{background:var(--profundo);color:var(--claro);border-color:var(--profundo);}

/* Subrayado que crece bajo los enlaces de navegación. */
.gt-sub{position:relative;}
.gt-sub::after{
  content:"";position:absolute;left:0;right:0;bottom:-6px;height:1px;
  background:currentColor;transform:scaleX(0);transform-origin:right;
  transition:transform .3s var(--gt-ease);
}
.gt-sub:hover::after,.gt-sub:focus-visible::after{transform:scaleX(1);transform-origin:left;}
.gt-sub[aria-current="page"]::after{transform:scaleX(1);opacity:.5;}

/* Pastilla "Contacto" de la cabecera y CTA de teal a profundo en las páginas
   interiores. Llevaban un atributo style-hover inventado que el motor de
   plantillas no interpreta —nunca se aplicaba—, así que al pasar el ratón
   solo entraba en juego el a:hover genérico de la página (color:teal-texto),
   que deja el texto exactamente del color del fondo. Necesita !important
   porque compite con el fondo fijado en línea en el marcado. */
.gt-cta-pill:hover{background:var(--profundo)!important;color:var(--blanco)!important;}

/* ---------------------------------------------------------------
   "Proyectos" destacado en la navegación.
   Esto es una constructora: la obra es lo que el visitante viene a
   ver, y en la barra competía de igual a igual con "Nosotros" —dos
   enlaces de texto idénticos—. La pastilla perfilada lo sube un
   escalón sin robarle el papel a "Contacto", que sigue siendo la
   única pastilla sólida, es decir, la única conversión.
   Sobre la portada resuelve además un problema de legibilidad: la
   tinta oscura iba directamente sobre la fotografía, sin fondo
   propio, justo donde el vídeo tiene más follaje.
   --------------------------------------------------------------- */
.gt-nav-destacado{
  display:inline-flex;align-items:center;gap:9px;
  border:1px solid var(--teal-texto);border-radius:999px;
  padding:9px 22px;
  background:rgba(255,255,255,.55);
  color:var(--profundo);
  transition:background var(--gt-rapido) ease,
             border-color var(--gt-rapido) ease,
             color var(--gt-rapido) ease;
}
/* Punto de acento en verde logo. Va por ::before y no por marcado
   porque la barra se repite en las seis páginas. */
.gt-nav-destacado::before{
  content:"";width:7px;height:7px;border-radius:50%;
  background:var(--logo);flex:none;
}
/* El !important repite el motivo del bloque .gt-cta-pill de arriba:
   compite con el a:hover genérico de cada página, que deja el texto
   del mismo color que el fondo al que entra. */
.gt-nav-destacado:hover{
  background:var(--teal-texto);border-color:var(--teal-texto);
  color:var(--blanco)!important;
}
.gt-nav-destacado:hover::before{background:var(--claro);}
.gt-nav-destacado[aria-current]{
  background:var(--logo);border-color:var(--logo);
}

/* Sobre la fotografía de portada el relleno claro pesa más que el
   blanco translúcido, y el filete va en profundo para acompañar al
   botón sólido de Contacto, que allí también es profundo. */
.nav-portada .gt-nav-destacado{
  background:rgba(215,238,187,.82);
  border-color:var(--profundo);
}
.nav-portada .gt-nav-destacado:hover{
  background:var(--profundo);border-color:var(--profundo);
  color:var(--claro)!important;
}
.nav-portada .gt-nav-destacado:hover::before{background:var(--logo);}

/* Mismo criterio en el panel móvil, donde la lista es vertical y el
   peso lo da el recuadro. La bajada explica de qué portafolio se
   trata: en móvil el visitante no tiene la sección 07 a la vista. */
.gt-mnav-destacado{
  border:1px solid rgba(160,200,120,.55);
  border-radius:20px;
  background:rgba(160,200,120,.12);
  padding:18px 20px;
  margin:8px 0;
}
.gt-mnav-destacado[aria-current]{
  background:rgba(160,200,120,.2);
  border-color:rgba(160,200,120,.75);
}
.gt-mnav-etiqueta{display:flex;flex-direction:column;gap:6px;min-width:0;}
.gt-mnav-etiqueta small{
  font-size:13px;line-height:1.4;font-weight:400;
  color:rgba(215,238,187,.72);
}

/* Tarjetas de proyecto del listado: mismo problema, con style-hover sobre
   el borde.

   El realce al pasar el puntero se reparte en cuatro gestos que entran
   juntos: la tarjeta se levanta y proyecta sombra, la fotografía hace un
   acercamiento lento, un velo oscuro sube desde el pie para que el borde
   inferior de la imagen no compita con el texto, y la flecha de «Ver ficha»
   avanza. El acercamiento vive dentro de .gt-hueco, que ya recorta con
   overflow:hidden: la imagen crece sin desbordar el radio de la tarjeta.

   Todo se declara bajo @media (hover:hover) porque en pantalla táctil el
   :hover se queda pegado tras el toque y la tarjeta quedaría levantada. */
.gt-tarjeta-proyecto:hover{border-color:var(--profundo)!important;}
.gt-ver-ficha i{
  font-style:normal;display:inline-block;
  transition:transform .45s cubic-bezier(.2,.7,.3,1);
}

@media (hover:hover){
  .gt-tarjeta-proyecto{
    transition:transform .5s cubic-bezier(.2,.7,.3,1),
               box-shadow .5s cubic-bezier(.2,.7,.3,1),
               border-color .35s ease;
  }
  .gt-tarjeta-proyecto:hover,
  .gt-tarjeta-proyecto:focus-visible{
    transform:translateY(-6px);
    box-shadow:0 24px 44px -26px rgba(31,55,25,.6);
  }
  /* ::before y no ::after: el ::after de este mismo hueco lo ocupa el
     esqueleto de carga (.gt-skel), que gt-ui.js monta sobre el contenedor. */
  .gt-tarjeta-proyecto .gt-hueco:has(img.foto)::before{
    content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
    background:linear-gradient(to top,rgba(31,55,25,.42),rgba(31,55,25,0) 58%);
    opacity:0;transition:opacity .5s ease;
  }
  .gt-tarjeta-proyecto:hover .gt-hueco:has(img.foto)::before,
  .gt-tarjeta-proyecto:focus-visible .gt-hueco:has(img.foto)::before{opacity:1;}

  /* Se repite el fundido de entrada de img.gt-fade porque esta declaración
     lo sobreescribiría: una sola transition por regla. */
  html.gt-js .gt-tarjeta-proyecto img.foto{
    transition:opacity .55s ease,
               transform .75s cubic-bezier(.2,.7,.3,1),
               filter .55s ease;
  }
  .gt-tarjeta-proyecto img.foto{
    transition:transform .75s cubic-bezier(.2,.7,.3,1),filter .55s ease;
  }
  .gt-tarjeta-proyecto:hover img.foto,
  .gt-tarjeta-proyecto:focus-visible img.foto{
    transform:scale(1.07);
    filter:saturate(1.06) contrast(1.03);
  }

  .gt-tarjeta-proyecto:hover .gt-ver-ficha i,
  .gt-tarjeta-proyecto:focus-visible .gt-ver-ficha i{transform:translateX(7px);}
}

/* En pantalla táctil no hay puntero al que responder, así que el mismo realce
   lo dispara el recorrido: gt-ui.js §3 bis pone .gt-realce en la tarjeta que
   está pasando por el centro de la pantalla y lo quita al salir. Los gestos
   son los de escritorio, un punto más suaves —el desplazamiento es continuo y
   no un gesto puntual del visitante— y con la respuesta al toque encima. */
@media (hover:none){
  .gt-tarjeta-proyecto{
    transition:transform .55s cubic-bezier(.2,.7,.3,1),
               box-shadow .55s cubic-bezier(.2,.7,.3,1),
               border-color .35s ease;
  }
  .gt-tarjeta-proyecto.gt-realce{
    border-color:var(--profundo)!important;
    transform:translateY(-4px);
    box-shadow:0 18px 34px -22px rgba(31,55,25,.55);
  }
  .gt-tarjeta-proyecto .gt-hueco:has(img.foto)::before{
    content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
    background:linear-gradient(to top,rgba(31,55,25,.42),rgba(31,55,25,0) 58%);
    opacity:0;transition:opacity .6s ease;
  }
  .gt-tarjeta-proyecto.gt-realce .gt-hueco:has(img.foto)::before{opacity:1;}

  html.gt-js .gt-tarjeta-proyecto img.foto{
    transition:opacity .55s ease,transform .9s cubic-bezier(.2,.7,.3,1);
  }
  .gt-tarjeta-proyecto img.foto{transition:transform .9s cubic-bezier(.2,.7,.3,1);}
  .gt-tarjeta-proyecto.gt-realce img.foto{transform:scale(1.05);}
  .gt-tarjeta-proyecto.gt-realce .gt-ver-ficha i{transform:translateX(7px);}

  /* Respuesta al toque. Va la última: mientras el dedo está encima manda
     sobre el realce, que es un estado de fondo. */
  .gt-tarjeta-proyecto:active{transform:scale(.985);transition-duration:.12s;}
}

/* Foco visible homogéneo (WCAG 2.4.7) en todo el sitio. */
a:focus-visible,button:focus-visible,input:focus-visible,
select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible{
  outline:2px solid var(--teal-texto);outline-offset:3px;border-radius:4px;
}
.banda a:focus-visible,.banda button:focus-visible,
.gt-oscuro a:focus-visible,.gt-oscuro button:focus-visible{outline-color:var(--logo);}

/* Salto al contenido: primer tabulador de cada página. */
.gt-salto{
  position:absolute;left:-9999px;top:0;z-index:100;
  background:var(--profundo);color:var(--claro);
  padding:12px 20px;border-radius:0 0 14px 0;font-size:15px;text-decoration:none;
}
.gt-salto:focus{left:0;}

/* ==========================================================================
   5 · Navegación móvil
   Vive fuera de <x-dc> como hermano de la plantilla, así que React nunca la
   vuelve a pintar y el panel no se cierra solo al cambiar de estado. El botón
   es fijo para seguir accesible durante todo el recorrido.
   ========================================================================== */
/* La altura es una variable porque no todas las páginas tienen lo mismo
   encima: el home lleva la franja de servicio y ahí el botón baja para no
   taparla (ver el bloque de la portada en Home.dc.html). */
.gt-burger{
  position:fixed;top:var(--gt-burger-top,18px);right:16px;z-index:var(--gt-z-nav);
  display:none;align-items:center;gap:9px;
  background:var(--teal-texto);color:var(--blanco);
  border:1px solid var(--teal-texto);border-radius:999px;
  padding:10px 16px 10px 14px;cursor:pointer;
  font-family:inherit;font-size:13px;letter-spacing:.06em;text-transform:uppercase;
  box-shadow:0 8px 22px rgba(31,55,25,.14);
  transition:background var(--gt-rapido) ease,color var(--gt-rapido) ease,
             border-color var(--gt-rapido) ease,transform var(--gt-rapido) var(--gt-ease);
}
.gt-burger:active{transform:scale(.96);}
.gt-burger-trazos{width:18px;height:12px;position:relative;flex:none;}
.gt-burger-trazos i{
  position:absolute;left:0;right:0;height:1.5px;border-radius:2px;background:currentColor;
  transition:transform .3s var(--gt-ease),opacity .2s ease;
}
.gt-burger-trazos i:nth-child(1){top:0;}
.gt-burger-trazos i:nth-child(2){top:5.25px;}
.gt-burger-trazos i:nth-child(3){top:10.5px;}
html.gt-nav-abierta .gt-burger{background:var(--profundo);color:var(--claro);
                               border-color:var(--profundo);}
html.gt-nav-abierta .gt-burger-trazos i:nth-child(1){transform:translateY(5.25px) rotate(45deg);}
html.gt-nav-abierta .gt-burger-trazos i:nth-child(2){opacity:0;transform:scaleX(.4);}
html.gt-nav-abierta .gt-burger-trazos i:nth-child(3){transform:translateY(-5.25px) rotate(-45deg);}

.gt-mnav{
  position:fixed;inset:0;z-index:calc(var(--gt-z-nav) - 1);
  background:var(--profundo);color:var(--claro);
  display:flex;flex-direction:column;justify-content:center;gap:2px;
  padding:96px 28px 36px;
  opacity:0;visibility:hidden;transform:translateY(-12px);
  transition:opacity .32s ease,transform .38s var(--gt-ease),visibility .32s ease;
  overflow-y:auto;overscroll-behavior:contain;
}
html.gt-nav-abierta .gt-mnav{opacity:1;visibility:visible;transform:none;}
html.gt-nav-abierta{overflow:hidden;}
.gt-mnav-item{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  color:var(--claro);text-decoration:none;
  font-size:clamp(24px,7vw,34px);font-weight:300;line-height:1.15;
  padding:16px 0;border-bottom:1px solid rgba(215,238,187,.18);
}
/* El estado de partida -invisible y un poco mas abajo- se declara solo donde
   la entrada va a correr de verdad. Antes vivia en la regla de arriba, y eso
   ataba la unica manera de VER el menu a que una animacion llegara a
   ejecutarse: bastaba una hoja que anulara `animation` -la portada tenia una
   para movimiento reducido- para que el panel se abriera en verde profundo y
   sin ninguna opcion a la vista. Ahora el enlace es visible por defecto y la
   entrada es un adorno que se añade encima. Un navegador que no entienda
   prefers-reduced-motion tampoco casa con no-preference y se queda con el
   menu quieto y legible, que es el fallo correcto. */
@media (prefers-reduced-motion:no-preference){
  .gt-mnav-item{opacity:0;transform:translateY(14px);}
  html.gt-nav-abierta .gt-mnav-item{
    animation:gt-entra-item .5s var(--gt-ease) both;
    animation-delay:calc(90ms + var(--i,0) * 60ms);
  }
}
@keyframes gt-entra-item{to{opacity:1;transform:none}}
.gt-mnav-item[aria-current="page"]{color:var(--logo);}
.gt-mnav-item svg{width:20px;height:20px;flex:none;fill:none;
  stroke:var(--logo);stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;
  transition:transform .28s var(--gt-ease);}
.gt-mnav-item:hover svg{transform:translate(3px,-3px);}
.gt-mnav-pie{
  margin-top:28px;display:flex;flex-direction:column;gap:16px;
}
/* Mismo criterio que en los enlaces: el pie se ve, y la entrada es aparte. */
@media (prefers-reduced-motion:no-preference){
  .gt-mnav-pie{opacity:0;}
  html.gt-nav-abierta .gt-mnav-pie{animation:gt-entra-item .5s .42s var(--gt-ease) both;}
}
.gt-mnav-cta{
  align-self:flex-start;background:var(--logo);color:var(--profundo);
  border-radius:999px;padding:14px 28px;font-size:16px;text-decoration:none;
  transition:background var(--gt-rapido) ease,transform var(--gt-rapido) var(--gt-ease);
}
.gt-mnav-cta:hover{background:var(--claro);transform:translateY(-2px);}
.gt-mnav-datos{font-size:13px;line-height:1.7;color:rgba(215,238,187,.72);}
.gt-mnav-datos a{color:var(--claro);text-decoration:none;}

@media (max-width:860px){
  .gt-burger{display:inline-flex;}
  /* La navegación de escritorio cede el paso; el logotipo se queda. */
  .gt-nav,.nav-portada{display:none!important;}
}
@media (min-width:861px){
  .gt-mnav{display:none;}
}

/* ==========================================================================
   6 · Botones flotantes: volver arriba y WhatsApp
   Se apilan en columna para que nunca se solapen, y el de volver arriba solo
   aparece cuando ya hay recorrido que deshacer.
   ========================================================================== */
.gt-flotantes{
  position:fixed;right:24px;bottom:24px;z-index:var(--gt-z-flotante);
  display:flex;flex-direction:column;align-items:flex-end;gap:12px;
}
.gt-top{
  position:relative;
  width:48px;height:48px;border-radius:999px;cursor:pointer;padding:0;
  display:grid;place-items:center;
  background:var(--claro);color:var(--profundo);
  border:1px solid rgba(31,55,25,.28);
  box-shadow:0 10px 24px rgba(31,55,25,.16);
  opacity:0;visibility:hidden;transform:translateY(12px) scale(.9);
  transition:opacity .3s ease,transform .3s var(--gt-ease),visibility .3s ease,
             background var(--gt-rapido) ease,color var(--gt-rapido) ease;
}
html.gt-hay-scroll .gt-top{opacity:1;visibility:visible;transform:none;}
.gt-top:hover{background:var(--profundo);color:var(--claro);}
.gt-top:active{transform:scale(.94);}
.gt-top svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.6;
            stroke-linecap:round;stroke-linejoin:round;
            transition:transform .28s var(--gt-ease);}
.gt-top:hover svg{transform:translateY(-2px);}
/* Anillo de progreso de lectura alrededor del botón. */
.gt-top::before{
  content:"";position:absolute;inset:-4px;border-radius:999px;pointer-events:none;
  background:conic-gradient(var(--teal-texto) calc(var(--gt-progreso,0) * 1%),transparent 0);
  -webkit-mask:radial-gradient(circle,transparent 61%,#000 62%);
          mask:radial-gradient(circle,transparent 61%,#000 62%);
  opacity:.85;
}

/* El FAB de WhatsApp que ya traía cada página entra en la misma columna.
   isolation:auto es obligatorio: .gt-btn crea contexto de apilamiento propio
   (isolation:isolate) para su brillo (::before, z-index:-1), y combinado con
   la columna flex eso hace que Chromium le atribuya al FAB los clics que
   caen sobre el botón de volver arriba, un palmo más arriba —el botón se ve
   bien pero nunca responde. Sin contexto propio, el clic vuelve a resolver
   contra el elemento que de verdad está bajo el puntero. */
.gt-flotantes .gt-fab,.gt-flotantes .fab{position:static!important;isolation:auto!important;}

@media (max-width:760px){
  .gt-flotantes{right:14px;bottom:14px;gap:10px;}
  .gt-top{width:42px;height:42px;}
  /* Con el rótulo puesto, el FAB medía media pantalla y se sentaba encima
     de lo que hubiera en la esquina -en el home, el nombre de la obra del
     carrusel-. En móvil se queda en disco: el icono ya dice qué es y el
     texto sigue en el árbol de accesibilidad para quien no lo ve.
     Gana a los overrides .gt-fab!important de cada plantilla por
     especificidad, que es justo lo que se busca. */
  .gt-flotantes .gt-fab{
    width:52px;height:52px;padding:0!important;gap:0;
    font-size:0;border-radius:999px;justify-content:center;
  }
  .gt-flotantes .gt-fab svg{width:23px;height:23px;}
}
@media print{
  .gt-flotantes,.gt-burger,.gt-mnav,.gt-carga{display:none!important;}
  /* Al imprimir no hay scroll que dispare el revelado: todo visible o la
     hoja saldría en blanco. */
  html.gt-js [data-gt-anim]{opacity:1!important;transform:none!important;}
  html.gt-js [data-gt-anim="hijos"] > *{opacity:1!important;animation:none!important;}
  [data-gt-secuencia] > *{animation:none!important;}
  html.gt-js .gt-traza-circulo circle{stroke-dashoffset:0!important;}
  html.gt-js img.gt-fade{opacity:1!important;}
  #dc-root{animation:none!important;}
  .gt-hdr{position:static!important;}
}

/* ==========================================================================
   7 · Botones de redes sociales
   Trazo sobre fondo claro, relleno al pasar. Sobre fondo oscuro se invierten.
   ========================================================================== */
.gt-rrss{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
.gt-rrss a{
  width:38px;height:38px;border-radius:12px;display:grid;place-items:center;
  border:1px solid rgba(31,55,25,.24);color:var(--profundo);
  transition:background var(--gt-rapido) ease,color var(--gt-rapido) ease,
             border-color var(--gt-rapido) ease,transform var(--gt-rapido) var(--gt-ease);
}
.gt-rrss a:hover{background:var(--profundo);color:var(--claro);
                 border-color:var(--profundo);transform:translateY(-2px);}
.gt-rrss a:active{transform:translateY(0) scale(.94);}
.gt-rrss svg{width:18px;height:18px;fill:currentColor;display:block;}
.gt-rrss-claro a{border-color:rgba(215,238,187,.30);color:var(--claro);}
.gt-rrss-claro a:hover{background:var(--logo);color:var(--profundo);border-color:var(--logo);}

/* ==========================================================================
   8 · Banda de llamada a la acción repetida
   Mismo bloque en varias páginas y a varias alturas del recorrido: es el CTA
   que el documento de contenido pide repetir.
   ========================================================================== */
.gt-ctaband{
  background:var(--profundo);color:var(--claro);
  border-radius:32px;padding:clamp(30px,4vw,52px);
  display:grid;grid-template-columns:minmax(0,1fr) auto;gap:clamp(22px,3vw,44px);
  align-items:center;position:relative;overflow:hidden;
}
/* Motivo del manual: el símbolo recortado como campo gráfico, nunca centrado. */
.gt-ctaband-marca{
  position:absolute;right:-2%;bottom:-42%;height:190%;width:auto;opacity:.10;
  pointer-events:none;user-select:none;
}
.gt-ctaband-texto{position:relative;z-index:1;display:flex;flex-direction:column;gap:12px;}
.gt-ctaband-rotulo{font-size:12px;line-height:1.4;letter-spacing:.14em;
                   text-transform:uppercase;color:var(--logo);}
.gt-ctaband-titulo{margin:0;font-size:clamp(24px,3vw,38px);line-height:1.15;
                   font-weight:300;text-wrap:balance;}
/* Cifra dentro del titular de la banda: mismo gesto que en el home,
   el numero se lee antes que la frase. */
.gt-ctaband-cifra{font-size:clamp(42px,5.2vw,68px);line-height:.85;font-weight:300;
                  font-variant-numeric:tabular-nums;letter-spacing:-.02em;
                  display:inline-block;vertical-align:-.04em;}
.gt-ctaband-cuerpo{margin:0;font-size:16px;line-height:1.55;max-width:52ch;
                   color:rgba(255,255,255,.82);}
.gt-ctaband-acciones{position:relative;z-index:1;display:flex;gap:14px;flex-wrap:wrap;}
.gt-ctaband .gt-btn{background:var(--logo);color:var(--profundo);}
.gt-ctaband .gt-btn:hover{background:var(--claro);color:var(--profundo);}
.gt-ctaband .gt-btn-linea{background:transparent;color:var(--claro);
                          border-color:rgba(215,238,187,.42);}
.gt-ctaband .gt-btn-linea:hover{background:var(--claro);color:var(--profundo);
                                border-color:var(--claro);}
@media (max-width:900px){
  .gt-ctaband{grid-template-columns:1fr;}
  .gt-ctaband-acciones .gt-btn{flex:1 1 100%;}
}

/* ==========================================================================
   10 · Formulario: validación y estados
   ========================================================================== */
.gt-form{display:flex;flex-direction:column;gap:18px;}
.gt-campos{display:grid;grid-template-columns:1fr 1fr;gap:16px;}
@media (max-width:760px){.gt-campos{grid-template-columns:1fr;}}
.gt-campo{display:flex;flex-direction:column;gap:7px;
          font-size:12px;line-height:1.4;color:var(--profundo);}
.gt-req{color:var(--teal-texto);}
.gt-input{
  border:1px solid var(--teal);border-radius:14px;padding:13px 16px;
  font-family:inherit;font-size:var(--cuerpo,18px);line-height:1.4;
  background:var(--blanco);color:var(--profundo);width:100%;
  transition:border-color var(--gt-rapido) ease,box-shadow var(--gt-rapido) ease,
             background var(--gt-rapido) ease;
}
.gt-input::placeholder{color:rgba(47,46,45,.45);}
.gt-input:hover{border-color:var(--teal-texto);}
.gt-input:focus{border-color:var(--teal-texto);
                box-shadow:0 0 0 3px rgba(0,150,131,.16);outline:none;}
textarea.gt-input{resize:vertical;min-height:118px;}
/* El error no depende solo del color: cambia el borde, añade fondo y un
   mensaje con icono. */
.gt-input[aria-invalid="true"]{
  border-color:#B3261E;background:#FFF6F5;
  box-shadow:0 0 0 3px rgba(179,38,30,.12);
}
.gt-input[data-gt-ok="true"]{border-color:var(--teal-texto);}
.gt-msj-error{
  display:flex;align-items:flex-start;gap:7px;
  font-size:12px;line-height:1.45;color:#8C1D18;
  animation:gt-sacude .34s var(--gt-ease) both;
}
.gt-msj-error svg{width:14px;height:14px;flex:none;margin-top:1px;fill:none;
                  stroke:currentColor;stroke-width:1.6;stroke-linecap:round;}
@keyframes gt-sacude{
  0%{transform:translateX(0)}22%{transform:translateX(-4px)}
  55%{transform:translateX(3px)}100%{transform:translateX(0)}
}
.gt-check{display:flex;gap:11px;align-items:flex-start;
          font-size:12px;line-height:1.55;color:var(--carbon);cursor:pointer;}
.gt-check input{margin-top:2px;width:17px;height:17px;accent-color:var(--teal-texto);
                flex:none;cursor:pointer;}
.gt-check-mal{color:#8C1D18;}
.gt-contador{font-size:12px;color:var(--carbon);text-align:right;
             font-variant-numeric:tabular-nums;}
.gt-contador-tope{color:#8C1D18;}

/* Estado de envío del botón. */
.gt-hilando{
  width:16px;height:16px;border-radius:999px;flex:none;display:inline-block;
  border:2px solid rgba(255,255,255,.35);border-top-color:currentColor;
  animation:gt-gira .7s linear infinite;
}
@keyframes gt-gira{to{transform:rotate(360deg)}}

/* Éxito y error del envío. */
.gt-aviso{
  border-radius:24px;padding:32px;display:flex;flex-direction:column;gap:10px;
  align-items:flex-start;animation:gt-aviso-entra .45s var(--gt-ease) both;
}
@keyframes gt-aviso-entra{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.gt-aviso-ok{border:1px solid var(--teal);background:rgba(0,150,131,.07);}
.gt-aviso-mal{border:1px solid #B3261E;background:#FFF6F5;}
.gt-aviso-icono{width:46px;height:46px;border-radius:999px;display:grid;place-items:center;
                flex:none;margin-bottom:4px;}
.gt-aviso-ok .gt-aviso-icono{background:var(--logo);color:var(--profundo);}
.gt-aviso-mal .gt-aviso-icono{background:#B3261E;color:#fff;}
.gt-aviso-icono svg{width:24px;height:24px;fill:none;stroke:currentColor;stroke-width:1.8;
                    stroke-linecap:round;stroke-linejoin:round;}
.gt-aviso-titulo{font-size:22px;font-weight:300;line-height:1.25;}
.gt-aviso-ok .gt-aviso-titulo{color:var(--teal-texto);}
.gt-aviso-mal .gt-aviso-titulo{color:#8C1D18;}
.gt-aviso-cuerpo{margin:0;font-size:16px;line-height:1.55;color:var(--profundo);}
.gt-aviso-nota{font-size:12px;line-height:1.6;color:var(--carbon);}

/* Honeypot: fuera de pantalla, nunca display:none (algunos robots lo detectan). */
.gt-trampa{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;}

/* Pastilla de opción (la intención del formulario). El estado activo se
   distingue por el relleno, no solo por el color del borde. */
.gt-chip{
  border:1px solid var(--teal-texto);background:transparent;color:var(--profundo);
  border-radius:999px;padding:11px 22px;cursor:pointer;
  font-family:inherit;font-size:var(--cuerpo,18px);line-height:1.4;
  transition:background var(--gt-rapido) ease,color var(--gt-rapido) ease,
             transform var(--gt-rapido) var(--gt-ease),box-shadow var(--gt-rapido) ease;
}
.gt-chip:hover{background:rgba(0,150,131,.10);transform:translateY(-2px);
               box-shadow:0 8px 18px rgba(31,55,25,.10);}
.gt-chip:active{transform:translateY(0) scale(.97);box-shadow:none;}
.gt-chip-on{background:var(--teal-texto);color:var(--blanco);}
.gt-chip-on:hover{background:var(--profundo);color:var(--blanco);}

/* ==========================================================================
   11 · Cabecera al hacer scroll
   ========================================================================== */
/* La cabecera de las páginas interiores acompaña el recorrido. Es pegajosa
   siempre —así no hay salto al aparecer— y solo gana fondo, filete y una
   altura más corta cuando ya se ha bajado. */
.gt-hdr{
  position:sticky;top:0;z-index:30;
  background:transparent;border-bottom:1px solid transparent;
  transition:padding .3s var(--gt-ease),background .3s ease,
             border-color .3s ease,box-shadow .3s ease;
}
html.gt-scrolled .gt-hdr{
  background:rgba(215,238,187,.92);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  border-bottom-color:rgba(0,150,131,.20);
  box-shadow:0 6px 20px rgba(31,55,25,.06);
  padding-top:15px!important;padding-bottom:15px!important;
}

/* ==========================================================================
   11 · Carrusel
   Mecánica común; el aspecto lo pone cada página. Las diapositivas se apilan
   y se cruzan por opacidad -no por desplazamiento- para que la fotografía
   nunca deje ver un borde. La activa deriva despacio mientras está en pantalla
   y el punto de mando llena su barra en el mismo lapso: cuando termina, ese
   `animationend` es la señal de relevo que espera gt-ui.js §9. Un solo reloj,
   el del compositor, y por eso pausar es solo `animation-play-state`.
   ========================================================================== */
[data-gt-carrusel]{--gt-lapso:6.5s;}
[data-gt-diapo]{opacity:0;transition:opacity 1.15s var(--gt-ease);}
[data-gt-diapo].gt-activa{opacity:1;}
[data-gt-diapo] img{transform:scale(1.03);will-change:transform;}
/* Impares y pares derivan en sentidos opuestos: dos fotos seguidas no repiten
   el mismo gesto y el conjunto no se lee como un bucle. */
[data-gt-diapo].gt-activa img{animation:gt-deriva var(--gt-lapso) linear both;}
[data-gt-diapo]:nth-of-type(even).gt-activa img{animation-name:gt-deriva-b;}
@keyframes gt-deriva{
  from{transform:scale(1.02) translate3d(0,0,0)}
  to  {transform:scale(1.085) translate3d(-1.6%,-1.1%,0)}
}
@keyframes gt-deriva-b{
  from{transform:scale(1.085) translate3d(1.4%,1%,0)}
  to  {transform:scale(1.02) translate3d(0,0,0)}
}

.gt-punto-relleno{display:block;transform:scaleX(0);transform-origin:left;}
[data-gt-punto].gt-activo .gt-punto-relleno{animation:gt-punto var(--gt-lapso) linear both;}
@keyframes gt-punto{from{transform:scaleX(0)}to{transform:scaleX(1)}}

/* Fuera de pantalla, con la pestaña oculta, con el ratón encima o con el foco
   dentro: el ciclo se congela donde está y sigue exactamente ahí al volver. */
[data-gt-carrusel].gt-pausado [data-gt-punto].gt-activo .gt-punto-relleno,
[data-gt-carrusel].gt-pausado [data-gt-diapo].gt-activa img{animation-play-state:paused;}

/* ==========================================================================
   11 bis · Vídeo de fondo
   Mecánica común de un campo que respira; el encuadre y el velo los pone
   cada página. Se numera «11 bis» y no «16» por dos motivos: va junto al
   carrusel, que es el otro modo de llenar ese mismo fondo, y sobre todo
   tiene que quedar ANTES de §12, que es la última palabra en movimiento
   reducido. Puesta después, la sección se saltaría esa regla.

   Hay dos capas superpuestas y en este orden importa cuál gana:
     · el póster, que es una fotografía normal y es lo único que existe sin
       JavaScript, con la red apretada o con el movimiento reducido;
     · el vídeo, que entra encima y solo cuando ya tiene fotogramas que
       enseñar. Sin esa espera se ve un cuadro negro entre que el elemento
       existe y el primer fotograma llega, que es justo el destello que la
       portada no puede permitirse.
   El vídeo no lleva `poster`: el póster es el <picture> de debajo, que sabe
   servir WebP y se precarga desde el <head>. Duplicarlo en el atributo
   obligaría al navegador a bajar la misma imagen dos veces.
   ========================================================================== */
[data-gt-video]{position:absolute;inset:0;overflow:hidden;}
[data-gt-video] > picture{position:absolute;inset:0;display:block;}
[data-gt-video] img,
[data-gt-video] video{position:absolute;inset:0;display:block;
                      width:100%;height:100%;object-fit:cover;}
[data-gt-video] video{opacity:0;transition:opacity 1s var(--gt-ease);
                      will-change:opacity;}
/* La clase la pone gt-ui.js §11 en el primer `playing`, no en `canplay`:
   `canplay` promete que se puede empezar, no que ya se esté viendo algo. */
/* .998 y no 1, a proposito. Chrome sobre Windows puede sacar un video de la
   composicion normal y entregarlo a un overlay de DirectComposition, y volver
   a meterlo, segun lo que tenga encima y segun se mueva la pagina; cada ruta
   convierte el color a su manera y el cambio se ve como un salto de tono en
   todo lo que se pinta semitransparente sobre el video -en la portada, el
   degradado del velo-. Un overlay exige opacidad exactamente 1: con .998 el
   video se queda siempre en la ruta normal y el tono no cambia nunca. La
   diferencia con 1 no se ve; el poster de debajo es el mismo fotograma. */
[data-gt-video].gt-video-visible video{opacity:.998;}

/* Mando de movimiento. Nace oculto y lo destapa el guion: si el vídeo no
   llega a montarse -sin JS, con datos ahorrados o con movimiento reducido-
   un botón de pausa no tendría nada que pausar. */
[data-gt-video-toggle][hidden]{display:none!important;}
/* Dos iconos en el mismo botón; se enseña el que corresponde al gesto que
   toca, no al estado actual, que es lo que espera quien lo va a pulsar. */
[data-gt-video-toggle] .gt-icono-play{display:none;}
[data-gt-video-toggle][aria-pressed="true"] .gt-icono-play{display:block;}
[data-gt-video-toggle][aria-pressed="true"] .gt-icono-pausa{display:none;}

/* ==========================================================================
   11 ter · Segunda capa de micromovimiento
   Gestos compartidos que las páginas interiores no tenían y el home solo a
   medias. Todos se resuelven con transform y opacity, en 150–800 ms, y §12
   los apaga de raíz. Nada de esto cambia color, tamaño de tipo ni maqueta:
   son la misma página, un poco más viva.
   ========================================================================== */

/* --- a · Secuencia de entrada de la portadilla interior.
   Lo que en el home hace la portada (rótulo → titular → regla → cuerpo)
   aquí lo hace el atributo: cada hijo directo entra por turnos, sin
   JavaScript y sin esperar al scroll, porque está por encima del pliegue. */
@media (prefers-reduced-motion:no-preference){
  [data-gt-secuencia] > *{
    animation:gt-surge .8s var(--gt-ease) both;
    animation-delay:calc(.08s + var(--gt-n,0) * .11s);
  }
  [data-gt-secuencia] > :nth-child(2){--gt-n:1}
  [data-gt-secuencia] > :nth-child(3){--gt-n:2}
  [data-gt-secuencia] > :nth-child(4){--gt-n:3}
  [data-gt-secuencia] > :nth-child(5){--gt-n:4}
  [data-gt-secuencia] > :nth-child(n+6){--gt-n:5}
}
@keyframes gt-surge{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}

/* --- b · Cascada de hijos.
   data-gt-anim="hijos" marca un contenedor —rejilla de tarjetas, nube de
   píldoras, lista de filas— cuyos hijos entran uno tras otro. El contenedor
   no se mueve: gt-ui.js §2 lo vigila como a cualquier otro y numera a sus
   hijos en --gt-i. Se usa animation y no transition para no pisar las
   transiciones de hover que ya traen los hijos (las tarjetas de proyecto,
   por ejemplo); al pasar a .gt-visto la animación se retira y el hijo queda
   en su estado natural, con su hover intacto. El tope de 700 ms evita que
   una nube de catorce píldoras tarde un segundo entero en completarse. */
html.gt-js [data-gt-anim="hijos"]{opacity:1;transform:none;transition:none;will-change:auto;}
html.gt-js [data-gt-anim="hijos"] > *{opacity:0;}
html.gt-js [data-gt-anim="hijos"].gt-in > *{
  opacity:1;
  animation:gt-surge .7s var(--gt-ease) both;
  animation-delay:calc(var(--gt-d,0ms) + min(var(--gt-i,0) * 65ms, 700ms));
}
html.gt-js [data-gt-anim="hijos"].gt-visto > *{animation:none;}

/* --- c · Reentrada tras filtrar (portafolio). gt-filtros.js la pone en cada
   tarjeta que queda visible y la retira al terminar. */
.gt-reentra{animation:gt-surge .5s var(--gt-ease) both;
            animation-delay:calc(min(var(--gt-i,0) * 45ms, 360ms));}

/* --- d · Enlace con la flecha diagonal del manual, para las páginas
   interiores. Es el mismo gesto que .enlace del home: el texto va en verde
   profundo y el icono en teal; al pasar, la flecha avanza en diagonal. */
.gt-enlace{display:inline-flex;align-items:center;gap:12px;
           font-size:var(--cuerpo,18px);line-height:1.4;color:var(--profundo);}
.gt-flecha{width:23px;height:23px;flex:none;overflow:visible;
           transition:transform .25s var(--gt-ease);}
.gt-flecha circle,.gt-flecha path{fill:none;stroke:currentColor;stroke-width:1;
                                  stroke-linecap:round;stroke-linejoin:round;}
.gt-enlace .gt-flecha{color:var(--teal-texto);}
.gt-enlace:hover{color:var(--teal-texto);}
.gt-enlace:hover .gt-flecha,.gt-enlace:focus-visible .gt-flecha{transform:translate(3px,-3px);}
.gt-enlace-atras .gt-flecha{transform:scaleX(-1);}
.gt-enlace-atras:hover .gt-flecha,.gt-enlace-atras:focus-visible .gt-flecha{transform:scaleX(-1) translate(3px,-3px);}
.gt-oscuro .gt-enlace,.gt-ctaband .gt-enlace{color:var(--claro);}
.gt-oscuro .gt-enlace .gt-flecha{color:var(--logo);}
/* «Ver ficha» de la tarjeta del portafolio: el icono avanza con el hover de
   la tarjeta entera, como ya hacía el <i> antiguo. */
.gt-ver-ficha{display:inline-flex;align-items:center;gap:10px;}
.gt-ver-ficha .gt-flecha{transition:transform .45s cubic-bezier(.2,.7,.3,1);}
@media (hover:hover){
  .gt-tarjeta-proyecto:hover .gt-ver-ficha .gt-flecha,
  .gt-tarjeta-proyecto:focus-visible .gt-ver-ficha .gt-flecha{transform:translate(4px,-4px);}
}
@media (hover:none){
  .gt-tarjeta-proyecto.gt-realce .gt-ver-ficha .gt-flecha{transform:translate(4px,-4px);}
}

/* --- e · El círculo hairline de la flecha grande se traza al revelarse.
   Circunferencia de r=11 ≈ 69,1; el trazo no escala con el tamaño. */
html.gt-js .gt-traza-circulo circle{stroke-dasharray:70;stroke-dashoffset:70;
  transition:stroke-dashoffset 1.1s var(--gt-ease) .15s;}
html.gt-js .gt-in .gt-traza-circulo circle,
html.gt-js .gt-traza-circulo.gt-in circle{stroke-dashoffset:0;}

/* --- f · La banda de llamada a la acción: el símbolo recortado se asienta al
   revelarse y responde despacio al puntero. Es un campo gráfico, no un
   logotipo: el manual solo veta sombras y deformación sobre el logotipo. */
html.gt-js .gt-ctaband .gt-ctaband-marca{
  transform:translate3d(3%,5%,0) scale(1.06);
  transition:transform 1.6s var(--gt-ease);
}
html.gt-js .gt-in .gt-ctaband-marca,
html.gt-js .gt-ctaband.gt-in .gt-ctaband-marca{transform:none;}
@media (hover:hover){
  html.gt-js .gt-in .gt-ctaband:hover .gt-ctaband-marca,
  html.gt-js .gt-ctaband.gt-in:hover .gt-ctaband-marca{transform:translate3d(-1.5%,-2.5%,0) scale(1.03);}
}

/* --- g · Cabecera interior: el logotipo cede un poco de tamaño cuando la
   barra se compacta, en lugar de quedarse rígido mientras todo lo demás
   encoge. Solo escala: ni color ni sombra, como manda el manual. */
.gt-hdr img{transition:transform .3s var(--gt-ease);transform-origin:left center;}
html.gt-scrolled .gt-hdr img{transform:scale(.86);}

/* --- h · Pastilla de opción: pequeño rebote al elegirla. La clase la pone el
   guion al pulsar, no la plantilla, así que la carga inicial no rebota. */
.gt-chip.gt-pop{animation:gt-pop .32s var(--gt-ease);}
@keyframes gt-pop{0%{transform:scale(.96)}55%{transform:scale(1.035)}100%{transform:none}}

/* --- i · Campos del formulario: la etiqueta acompaña al foco y el campo se
   alza un punto. Suficiente para saber dónde se está escribiendo sin mirar
   el cursor. */
.gt-campo{transition:color var(--gt-rapido) ease;}
.gt-campo:focus-within{color:var(--teal-texto);}
.gt-input{transition:border-color var(--gt-rapido) ease,box-shadow var(--gt-rapido) ease,
                     background var(--gt-rapido) ease,transform var(--gt-rapido) var(--gt-ease);}
.gt-input:focus{transform:translateY(-1px);}

/* --- j · Galería de la ficha de proyecto: acercamiento lento al pasar, el
   mismo de las tarjetas del portafolio, para que la fotografía responda
   aunque no sea un enlace. */
.gt-galeria .gt-hueco img.foto{transition:transform .9s cubic-bezier(.2,.7,.3,1);}
html.gt-js .gt-galeria .gt-hueco img.foto{transition:opacity .55s ease,transform .9s cubic-bezier(.2,.7,.3,1);}
@media (hover:hover){
  .gt-galeria .gt-hueco:hover img.foto{transform:scale(1.045);}
}

/* --- k · Tarjeta informativa que se alza al pasar (calidad, etapas). Es la
   elevación de .gt-press, sin el hundido de :active porque no se pulsa. */
.gt-alza{transition:transform .3s var(--gt-ease),box-shadow .3s ease,border-color .3s ease;}
@media (hover:hover){
  .gt-alza:hover{transform:translateY(-4px);box-shadow:0 18px 38px rgba(31,55,25,.13);}
}

/* ==========================================================================
   12 · Movimiento reducido
   Última palabra: quien lo pide ve el sitio completo y quieto.
   ========================================================================== */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;scroll-behavior:auto!important;
  }
  html.gt-js [data-gt-anim]{opacity:1!important;transform:none!important;}
  html.gt-js [data-gt-anim="hijos"] > *{opacity:1!important;animation:none!important;}
  [data-gt-secuencia] > *{animation:none!important;}
  html.gt-js .gt-traza-circulo circle{stroke-dashoffset:0!important;}
  html.gt-js .gt-ctaband .gt-ctaband-marca{transform:none!important;}
  .gt-input:focus{transform:none!important;}
  /* Sin fundido de entrada: la fotografía aparece cuando llega, sin
     esperar a una transición que aquí no debe existir. */
  html.gt-js img.gt-fade{opacity:1!important;}
  .gt-skel::after,.gt-skel-linea::after{display:none;}
  .gt-carga-marca{animation:none;}
  /* Sin duración, un transform de :hover sería un salto seco. Aquí el realce
     de la tarjeta se reduce a la sombra y al velo, que no desplazan nada. */
  .gt-tarjeta-proyecto:hover,.gt-tarjeta-proyecto:focus-visible,
  .gt-tarjeta-proyecto:hover img.foto,.gt-tarjeta-proyecto:focus-visible img.foto,
  .gt-tarjeta-proyecto.gt-realce,.gt-tarjeta-proyecto.gt-realce img.foto,
  .gt-ver-ficha i{transform:none!important;}
  .campo-fondo img{animation:none!important;}
  /* El carrusel se queda en la primera fotografía. Los puntos siguen siendo
     botones: quien quiera ver las demás las pide, pero nada se mueve solo.
     La barra de progreso desaparece porque ya no mide nada. */
  [data-gt-diapo] img{animation:none!important;transform:none!important;}
  [data-gt-diapo]{transition:none!important;}
  .gt-punto-relleno{animation:none!important;transform:scaleX(1)!important;}
  /* Profundidad de portada apagada de raíz: el CSS de cada página lee esta
     variable, así que ponerla a cero desactiva el efecto entero. */
  [data-gt-parallax]{--gt-p:0!important;}
  /* El vídeo de la portada es la excepción de esta sección, por decisión
     expresa: no es un adorno de la página sino la obra que la página está
     enseñando, y tiene que verse en cualquier teléfono. Así que aquí no se
     apaga. Lo que sí se le quita es el fundido de entrada -aparece sin
     transición, ya sobre el póster que encuadra igual- y el acercamiento
     lento del campo, que ese sí era movimiento de la página y no del plano.
     Quien no quiera verlo en marcha tiene el mando de pausa de la portada,
     que con esta preferencia nace visible en lugar de esperar al puntero. */
  [data-gt-video] video{transition:none!important;}
}

/* ==========================================================================
   13 · Filtros del portafolio
   En móvil las pastillas se quedan dentro del ancho de la página: envuelven,
   no se arrastran en horizontal. Una tira que se desplaza deja las opciones
   cortadas contra el borde y se lee como un desbordamiento, no como un
   gesto. Para que envolver no cueste cuatro renglones, la pastilla se
   compacta —tipografía y relleno— y el rótulo se queda en la misma línea.
   ========================================================================== */
@media (max-width:760px){
  .gt-filtro{gap:8px!important;}
  .gt-filtro > :first-child{min-width:0!important;}
  .gt-filtro .gt-chip{padding:8px 15px;font-size:14px;}
}

/* ==========================================================================
   14 · Pie de las páginas interiores
   La navegación del pie llevaba el gap en línea y no envolvía: por debajo de
   360 px se salía del ancho del documento. Aquí solo se le permite envolver.
   ========================================================================== */
footer nav{flex-wrap:wrap;}
@media (max-width:520px){
  footer nav{gap:12px 18px!important;}
  footer .gt-pad{justify-content:flex-start!important;}
}

/* ==========================================================================
   15 · Red de seguridad responsive
   Dos reglas que no cambian ningún diseño y evitan la avería más común en
   pantallas estrechas: una palabra que no puede partirse -un correo, una
   URL, un NIT- ensancha su caja, la caja ensancha el documento y la página
   entera queda desplazada a la derecha.
   ========================================================================== */
/* Se declara en el <body> y se hereda: media pagina esta escrita en <div>
   con estilo en linea, asi que una lista de etiquetas dejaria huecos.
   break-word solo parte la palabra que no cabe entera en su renglon; donde
   ya cabia, no cambia nada. */
body{overflow-wrap:break-word;}

/* Último recinto. clip, no hidden: hidden convierte al <body> en contenedor
   de scroll y con eso deja de funcionar position:sticky, que el sitio usa en
   los rótulos de sección. Los navegadores sin overflow:clip ignoran la regla
   y se quedan como estaban. */
html,body{overflow-x:clip;}

/* ==========================================================================
   16 · Franja de logos de clientes
   Los catorce logos llegan con fondos distintos —unos con alfa, otros con
   blanco macizo— y con proporciones que van del cuadrado al panorámico. La
   tarjeta blanca de altura fija los iguala sin deformarlos: la caja manda el
   tamaño y la imagen se contiene dentro.
   ========================================================================== */
.gt-logos{display:flex;flex-wrap:wrap;gap:12px;}
.gt-logo{
  flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;
  width:172px;height:80px;padding:14px 20px;box-sizing:border-box;
  background:#FFFFFF;border:1px solid var(--logo);border-radius:18px;
  overflow:hidden;
}
/* El <picture> es inline por defecto y no da referencia de altura al
   max-height del img: los logos con fondo blanco macizo se salian de la
   tarjeta. Se convierte en caja de bloque que ocupa toda la tarjeta y la
   imagen se contiene dentro sin deformarse. */
.gt-logo picture{display:block;width:100%;height:100%;}
.gt-logo img{display:block;width:100%;height:100%;object-fit:contain;object-position:center;}
@media (max-width:760px){
  .gt-logos{gap:10px;}
  .gt-logo{width:calc(50% - 5px);height:72px;padding:12px 16px;}
}
