/**
 * main.css — Tema felipeonate
 *
 * Hoja de estilos principal del tema. Se carga después de Bootstrap 5
 * (dependencia declarada en functions.php) para que las sobrescrituras
 * de variables funcionen correctamente.
 *
 * Estructura del archivo:
 *   1. Variables CSS (:root)          → Tokens de diseño del proyecto
 *   2. Sobrescritura de Bootstrap     → Alinear --bs-* con los tokens
 *   3. Reset / Estilos globales       → body, headings, párrafos, links
 *   4. .site-header (BEM)             → Barra de navegación principal
 *   5. .site-contact (BEM)            → Formulario de contacto
 *   6. .site-footer (BEM)             → Pie de página
 *
 * Estilos de plantillas específicas en assets/css/templates/:
 *   - templates/home.css              → Hero, Clients, Services, Contact
 *
 * Convenciones:
 *   - Nunca valores hex directos — siempre var(--color-*)
 *   - Nunca nombres de fuente directos — siempre var(--font-*)
 *   - BEM solo para componentes custom; Bootstrap para layout y utilidades
 *   - No modificar archivos fuente de Bootstrap ni Font Awesome
 *
 * @package felipeonate
 * @version 1.0.0
 */


/* ============================================================
   1. VARIABLES CSS — TOKENS DE DISEÑO
   ============================================================
   Declarados en :root para estar disponibles en cualquier selector
   del documento, incluyendo plantillas PHP y componentes futuros.

   Colores:
     --color-turquesa-500  → Color de marca, CTAs, links activos
     --color-menta-500     → Acentos secundarios, hover states
     --color-gris-500      → Texto secundario, bordes, metadatos
     --color-negro         → Texto principal, headings
     --color-blanco        → Fondos, superficies claras
     --color-*-soft        → Fondos de banners/alerts de cada estado
     --color-error         → Estados de error (texto/borde/ícono)
     --color-success       → Estados de éxito
     --color-warning       → Estados de advertencia
     --color-info          → Estados informativos

   Tipografías (cargadas via Google Fonts en functions.php):
     --font-display        → Comfortaa — usado en el nombre/logo del sitio
     --font-heading        → Montserrat — h1 a h4
     --font-body           → Montserrat — párrafos y UI

   Font weights:
     --fw-regular          → 400
     --fw-semibold         → 600
     --fw-bold             → 700
   ============================================================ */

:root {

  /* ----------------------------------------------------------
     Colores
     ---------------------------------------------------------- */
  --color-turquesa-50:  #E8F2F4;
  --color-turquesa-100: #D0E6EA;
  --color-turquesa-200: #A2CDD5;
  --color-turquesa-300: #73B3C0;
  --color-turquesa-400: #459AAB;
  --color-turquesa-500: #168196; /* Color de marca, CTAs, links activos */
  --color-turquesa-600: #126778;
  --color-turquesa-700: #0D4D5A;
  --color-turquesa-800: #09343C;
  --color-turquesa-900: #041A1E;

  --color-menta-50: #F0F8F6;
  --color-menta-100:#E1F0ED;
  --color-menta-200:#C3E2DB;
  --color-menta-300:#A4D3C8;
  --color-menta-400:#86C5B6;
  --color-menta-500:#68B6A4; /* Acentos secundarios, hover states */
  --color-menta-600:#539283;
  --color-menta-700:#3E6D62;
  --color-menta-800:#2A4942;
  --color-menta-900:#152421;

  --color-gris-50: #E6E6E7;
  --color-gris-100:#CCCECE;
  --color-gris-200:#B3B5B6;
  --color-gris-300:#9A9D9D;
  --color-gris-400:#808484;
  --color-gris-500:#676B6C; /* Texto secundario, bordes, metadatos */
  --color-gris-600:#4E5354;
  --color-gris-700:#353A3B;
  --color-gris-800:#1A1D1D;
  --color-gris-900:#0D0E0E;

  --color-negro:#02090A; /* Texto principal, headings */
  --color-blanco:#FAFAFA; /* Fondos, superficies claras */

  /* Estados semánticos — valores del Design System (DESIGN.md).
     Patrón de uso (Alert del DS): el texto de banners va en gris-700 o
     negro sobre el fondo -soft; el color semántico se usa en bordes e
     íconos (umbral WCAG 3:1) y como texto solo donde pasa 4.5:1
     (p.ej. --color-error sobre --color-blanco: 4.78:1).
     warning ajustado #C98A2B → #B47318: el original daba 2.57:1 sobre
     su -soft y no alcanzaba ni el 3:1 de elementos no textuales. */

  --color-error:#C0473C;
  --color-success:#2E8E6A;
  --color-warning:#B47318;
  --color-info:#1A38B2;
  --color-error-soft:#F7E7E5;
  --color-success-soft:#E7F3EE;
  --color-warning-soft:#F8EFE0;
  --color-info-soft:#E8ECFB;

  /* ----------------------------------------------------------
     Tipografías
     ---------------------------------------------------------- */
  --font-display: 'Comfortaa', sans-serif;
  --font-heading: 'Montserrat', sans-serif;
  --font-body:    'Montserrat', sans-serif;

  /* ----------------------------------------------------------
     Pesos tipográficos
     ---------------------------------------------------------- */
  --fw-regular:  400;
  --fw-semibold: 600;
  --fw-bold:     700;

  /* ----------------------------------------------------------
     Espaciado base (escala 8px)
     Usados en componentes BEM para mantener ritmo vertical.
     ---------------------------------------------------------- */
  --space-xs:  0.5rem;    /*  8px */
  --space-sm:  1rem;      /* 16px */
  --space-md:  1.5rem;    /* 24px */
  --space-lg:  2.5rem;    /* 40px */
  --space-xl:  4rem;      /* 64px */
  --space-2xl: 6rem;      /* 96px */

  /* ----------------------------------------------------------
     Transiciones
     Valor único para mantener coherencia en hover states.
     ---------------------------------------------------------- */
  --transition-base: 0.2s ease-in-out;

  /* ----------------------------------------------------------
     Superficies oscuras — usadas en Contact section y UI dark
     ---------------------------------------------------------- */
  --color-dark-surface: var(--color-turquesa-900);
  --color-dark-card:    var(--color-menta-900);
}


/* ============================================================
   2. SOBRESCRITURA DE VARIABLES DE BOOTSTRAP
   ============================================================
 */

:root {

  /* Color primario → turquesa de marca.
     Afecta a: .btn-primary, .text-primary, .bg-primary, .border-primary,
     badges, progress bars y cualquier componente que use --bs-primary. */
  --bs-primary:       var(--color-turquesa-500);
  --bs-primary-rgb:   22, 129, 150; /* RGB de #168196 para transparencias (rgba). */

  /* Color de enlace → turquesa de marca (coherente con CTAs). */
  --bs-link-color:       var(--color-turquesa-500);
  --bs-link-hover-color: var(--color-menta-500);

  /* Tipografía del cuerpo. */
  --bs-body-font-family: var(--font-body);
  --bs-body-color:       var(--color-negro);
  --bs-body-bg:          var(--color-blanco);

  /* Tipografía de headings (usada por Bootstrap en algunos componentes). */
  --bs-heading-color:    var(--color-negro);

  /* Borde por defecto → gris del sistema. */
  --bs-border-color: var(--color-gris-500);
}


/* ============================================================
   3. RESET / ESTILOS GLOBALES
   ============================================================
   Estilos base aplicados a los elementos HTML fundamentales.
   Se construyen sobre el reset de Bootstrap (Reboot) añadiendo
   los tokens de tipografía y color del proyecto.
   ============================================================ */

/* ----------------------------------------------------------
   Body
   ---------------------------------------------------------- */
body {
  font-family:    var(--font-body);
  font-weight:    var(--fw-regular);
  font-size:      1rem;          /* 16px — base Bootstrap. */
  line-height:    1.6;           /* Más generoso que el 1.5 de Bootstrap para legibilidad. */
  color:          var(--color-negro);
  background-color: var(--color-blanco);
  /* -webkit-font-smoothing:  antialiased;
  -moz-osx-font-smoothing: grayscale; */
}

/* ----------------------------------------------------------
   Headings — h1 a h4
   Montserrat Bold para jerarquía visual clara.
   h5 y h6 heredan Montserrat del body; no requieren override.
   ---------------------------------------------------------- */
h1,
h2,
h3,
h4 {
  font-family: var(--font-heading);
  font-weight: var(--fw-bold);
  color:       var(--color-negro);
  line-height: 1.2;
  margin-top:  0;
}

h1 { font-size: clamp(2rem, 5vw, 3rem);     } /* 32px → 48px */
h2 { font-size: clamp(1.5rem, 3vw, 2.25rem); } /* 24px → 36px */
h3 { font-size: clamp(1.25rem, 2.5vw, 1.75rem); } /* 20px → 28px */
h4 { font-size: clamp(1.125rem, 2vw, 1.375rem); } /* 18px → 22px */

/* ----------------------------------------------------------
   Párrafos
   ---------------------------------------------------------- */
p {
  margin-bottom: var(--space-sm);
  max-width:     72ch; /* Longitud de línea óptima para lectura. */
}

/* Párrafos dentro de contenedores de texto largo (editor WP / casos de estudio). */
.entry-content p,
.case-study__text p {
  max-width: none; /* El contenedor ya controla el ancho. */
}

/* ----------------------------------------------------------
   Links
   ---------------------------------------------------------- */
a {
  color:           var(--color-turquesa-500);
  text-decoration: none;
  transition:      color var(--transition-base);
}

/* Iconos inline dentro de links (Lucide) */
a svg {
  width:          14px;
  height:         14px;
  vertical-align: -2px;
  margin-left:    2px;
}

a:hover,
a:focus-visible {
  color:           var(--color-menta-500);
  text-decoration: underline;
}

/* Eliminar outline por defecto en favor de focus-visible accesible. */
a:focus {
  outline: none;
}

a:focus-visible {
  outline:        2px solid var(--color-turquesa-500);
  outline-offset: 3px;
  border-radius:  2px;
}


/* ============================================================
   4. SITE HEADER — BEM
   ============================================================
   Bloque: .site-header
   Elementos:
     .site-header__navbar  → <nav> Bootstrap dentro del header
     .site-header__brand   → Logotipo / nombre del sitio (navbar-brand)
   Modificadores: (ninguno en esta versión base)
   ============================================================ */

/* ----------------------------------------------------------
   .site-header — Bloque raíz
   ---------------------------------------------------------- */
.site-header {
  position:         sticky;
  top:              0;
  z-index:          1030; /* Mismo z-index que .sticky-top de Bootstrap. */
  background-color: var(--color-blanco);
  border-bottom:    1px solid rgba(2, 9, 10, 0.08); /* --color-negro al 8%. */
  box-shadow:       0 1px 4px rgba(2, 9, 10, 0.06);
  transition:       box-shadow 0.3s ease;
}

.site-header.scrolled {
  box-shadow: 0 2px 20px rgba(2, 9, 10, 0.08);
}

/* ----------------------------------------------------------
   .site-header__navbar — Elemento nav
   Hereda las clases de Bootstrap .navbar y .navbar-expand-xl (BL-33:
   migrado desde .navbar-expand-lg — 992px no alcanzaba para el logo +
   4 ítems de nav + selector de idioma + botón Contacto sin desbordar
   entre 992–1199px).
   Solo se añade padding vertical custom.
   ---------------------------------------------------------- */
.site-header__navbar {
  padding-top:    var(--space-sm);
  padding-bottom: var(--space-sm);
}

/* ----------------------------------------------------------
   .site-header__brand — Logotipo / nombre del sitio
   Sobrescribe los estilos de .navbar-brand de Bootstrap.
   ---------------------------------------------------------- */
.site-header__brand {
  font-family:    var(--font-display); /* Comfortaa SemiBold para el nombre. */
  font-weight:    var(--fw-semibold);
  font-size:      1.375rem;            /* 22px. */
  color:          var(--color-turquesa-500);
  letter-spacing: -0.01em;
  transition:     color var(--transition-base);
}

.site-header__brand img {
    height: 44px;
    width: auto;
}

.site-header__brand:hover,
.site-header__brand:focus-visible {
  color:           var(--color-menta-500);
  text-decoration: none;
}

/* ----------------------------------------------------------
   Menú de navegación principal (links generados por wp_nav_menu)
   Bootstrap renderiza los items con .nav-link; se ajusta color y hover.
   ---------------------------------------------------------- 
*/

#navMenu a:hover { 
  text-decoration: none;
} 

#navMenu ul li a {
  font-family: 'Montserrat', sans-serif;
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--color-negro);
  padding: 0.5rem 0.85rem;
  letter-spacing: 0.01em;
  transition: color 0.2s;
  position: relative;
}

#navMenu ul li a::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0.85rem;
  right: 0.85rem;
  height: 2px;
  background: var(--color-turquesa-500);
  transform: scaleX(0);
  transition: transform 0.25s ease;
}

/* Combinador directo (>) entre li.current-menu-item y a — sin él, la
   regla también alcanzaba a los links del submenú anidado dentro del
   mismo <li> (el <ul class="sub-menu"> vive dentro del li que
   WordPress marca como current-menu-item cuando la página activa es
   el padre, ej. "Consultoría"). Sus hijos ("Sub-menu test 01/02/03")
   quedaban pintados como activos aunque no lo fueran. Reportado
   sesión 4 de agosto. */
#navMenu ul li.current-menu-item > a { 
  color: var(--color-turquesa-500) !important; 
}

#navMenu ul li a:hover::after, 
#navMenu ul li.current-menu-item > a::after { 
  transform: scaleX(1); 
}

#navMenu ul li a:hover { 
  color: var(--color-turquesa-500) !important; 
  text-decoration: none;
} 

/* Botón hamburguesa — eliminar el borde por defecto de Bootstrap. */
/* Botón hamburguesa — sin borde por defecto. En mobile SÍ lleva borde
   (ver .site-header__mobile-controls más abajo): la clase border-0 de
   Bootstrap se sacó del markup en header.php porque aplica
   border:0 !important y ganaba siempre, dejando el botón visualmente
   más chico que el de idioma al lado (sesión 4 de agosto). */
.site-header__navbar .navbar-toggler {
  padding: var(--space-xs);
  color:   var(--color-negro);
}

.site-header__navbar .navbar-toggler:focus {
  box-shadow: 0 0 0 2px var(--color-turquesa-500);
}

/* Divisor vertical entre los links de navegación y los controles de la
   derecha. align-self:stretch en vez de un alto fijo: iguala la altura
   real de los botones vecinos (idioma y Contacto) aunque cambie su
   padding o su font-size. */
.navbar-divider {
  width: 1px;
  background: var(--color-gris-200);
  margin: 0 0.5rem;
  align-self: stretch;
}

/* Language dropdown button */
.btn-lang {
  font-family: var(--font-body);
  font-weight: var(--fw-semibold);
  font-size: 0.8125rem;
  color: var(--color-negro);
  background: transparent;
  border: 1px solid rgba(2, 9, 10, 0.15);
  border-radius: 6px;
  padding: 0.438rem 0.85rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  transition: border-color var(--transition-base), color var(--transition-base);
  text-decoration: none !important;
}
.btn-lang:hover { 
  border-color: var(--color-turquesa-500); 
  color: var(--color-turquesa-500); 
}
/* i[data-lucide] Y svg con la misma regla: antes de que Lucide corra
   (en DOMContentLoaded), el ícono es un <i> vacío sin tamaño — sin
   esto, el botón se ve angosto y salta cuando Lucide lo reemplaza por
   el <svg> real. Reservando el tamaño para ambos casos, el espacio ya
   está ahí desde el primer render, sin esperar al JS (CLS, sesión 4 de
   agosto — mismo criterio que el caret del submenú, más arriba). */
.btn-lang svg,
.btn-lang i[data-lucide] {
  width: 1rem;
  height: 1rem;
}
.btn-lang i[data-lucide] {
  display: inline-block;
}
.btn-lang::after { 
  display: none; 
}
ul.dropdown-menu {
    margin-top: 0 !important;
    padding: 0.2rem 0 !important;
}
/* Alineación a la derecha sin depender de Popper: el selector de idioma
   usa un controlador propio (main.js), no data-bs-toggle="dropdown" —
   así que el mecanismo de Bootstrap que activa .dropdown-menu-end vía
   [data-bs-popper] nunca corre. Fallback explícito y predecible. */
.dropdown-menu-end {
  left: auto;
  right: 0;
}
ul.dropdown-menu li a.dropdown-item {
  padding: 0.5rem 0.85rem 0.5rem 2.32rem !important;
  font-size: 0.8125rem !important;
}
ul.dropdown-menu li a.dropdown-item::after {
  display: none;
}
ul.dropdown-menu li a.dropdown-item.active {
  padding: 0.5rem 0.85rem !important;
}
.btn-lang + ul.dropdown-menu li a.dropdown-item.active {
  background-color: var(--color-turquesa-100);
}
.btn-lang + ul.dropdown-menu li a.dropdown-item.active svg {
  color: var(--color-turquesa-500);
  width: 0.75rem;
  height: 0.75rem;
}
ul.dropdown-menu li a.dropdown-item:active {
  background-color: var(--color-menta-500);
  color: var(--color-blanco) !important;
}

/* ----------------------------------------------------------
   BL-19 — Header direccional (oculta al bajar, revela al subir)
   Vanilla JS, sin GSAP/ScrollTrigger — ver main.js. Solo transform,
   no top/margin, para no disparar reflow en cada frame de scroll.
   ---------------------------------------------------------- */
.site-header {
  transition: transform 0.28s ease, box-shadow 0.3s ease;
}
.site-header--hidden {
  transform: translateY(-100%);
}

/* ----------------------------------------------------------
   BL-02 — Controles mobile (selector de idioma + toggler)
   Viven FUERA de .navbar-collapse a propósito — deben verse siempre,
   como en el wireframe de referencia (idioma primero, luego X/hamburguesa).
   ---------------------------------------------------------- */
.site-header__mobile-controls .btn-lang,
.site-header__mobile-controls .navbar-toggler {
  width: 2.25rem;
  height: 2.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  box-sizing: border-box;
  /* El toggler no traía borde propio (.btn-lang sí, desde su regla
     base) — con el mismo width/height pero uno bordeado y el otro no,
     se veían de tamaño distinto. Ambos cuadrados iguales, como en el
     wireframe. */
  border: 1px solid rgba(2, 9, 10, 0.15);
  border-radius: 6px;
}
/* Icon-only en mobile: sin el nombre del idioma, solo globo + chevron
   (el texto reaparece en desktop vía .btn-lang__current.d-lg-inline). */
.site-header__mobile-controls .btn-lang {
  gap: 0.15rem;
  padding: 0 7px !important;
  width: fit-content;
}
.site-header__mobile-controls .btn-lang svg,
.site-header__mobile-controls .btn-lang i[data-lucide],
.site-header__navbar .navbar-toggler svg,
.site-header__navbar .navbar-toggler i[data-lucide] {
  width: 1.1rem;
  height: 1.1rem;
  color: var(--color-negro);
}

/* Hamburguesa ↔ X — animado con transición CSS (opacidad + rotación),
   no con el atributo [hidden] (display:none no se puede animar). Los
   dos íconos quedan superpuestos en .c-nav-toggle-icon-wrap; main.js
   togglea la clase .is-open en el botón vía show.bs.collapse /
   hide.bs.collapse. */
.c-nav-toggle-icon-wrap {
  position: relative;
  display: inline-block;
  width: 1.1rem;
  height: 1.1rem;
}
.c-nav-toggle-icon {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  transition: opacity 0.22s ease, transform 0.22s ease;
}
.c-nav-toggle-icon--open {
  opacity: 1;
  transform: rotate(0deg);
}
.c-nav-toggle-icon--close {
  opacity: 0;
  transform: rotate(-90deg);
}
[data-nav-toggle].is-open .c-nav-toggle-icon--open {
  opacity: 0;
  transform: rotate(90deg);
}
[data-nav-toggle].is-open .c-nav-toggle-icon--close {
  opacity: 1;
  transform: rotate(0deg);
}

/* ----------------------------------------------------------
   BL-20/BL-21 — Estado abierto del botón de idioma
   Blanco/outline cerrado (heredado de .btn-lang de arriba) → relleno
   turquesa-500 abierto. No existe token "navy" en el Design System —
   se usa el color de marca en vez de introducir uno nuevo sin decisión
   explícita (ver sesión 4 de agosto). Mismo tratamiento en mobile y
   desktop porque ambos usan el mismo componente (pf_render_lang_switcher).
   ---------------------------------------------------------- */
.btn-lang.show,
.btn-lang[aria-expanded="true"] {
  background-color: var(--color-turquesa-500);
  border-color: var(--color-turquesa-500);
  color: var(--color-blanco);
}
.btn-lang.show svg,
.btn-lang[aria-expanded="true"] svg {
  color: var(--color-blanco);
}
.btn-lang.show .btn-lang__chevron,
.btn-lang[aria-expanded="true"] .btn-lang__chevron {
  transform: rotate(180deg);
}
.btn-lang__chevron {
  transition: transform var(--transition-base);
}

/* Lista del dropdown — layout código + nombre (BL-20, ref. open-design.ai).
   Reemplaza el ícono de check anterior por fondo resaltado en la fila activa. */
.c-lang-option {
  display: flex !important;
  align-items: baseline;
  gap: 0.75rem;
  /* Cubre todos los estados explícitamente — un reset genérico de
     enlaces en algún otro lado del sitio probablemente aplica
     text-decoration en :hover/:active, y se filtra acá igual que pasó
     con el subrayado del submenú (misma familia de bug, sesión 4 de
     agosto). */
  text-decoration: none !important;
}
.c-lang-option:hover,
.c-lang-option:focus,
.c-lang-option:active {
  text-decoration: none !important;
}
.c-lang-option__code {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: 0.75rem;
  color: var(--color-gris-500);
  min-width: 1.5rem;
}
.c-lang-option__name {
  font-weight: var(--fw-semibold);
  color: var(--color-negro);
}
ul.dropdown-menu li a.dropdown-item.c-lang-option {
  padding: 0.5rem 0.85rem !important; /* sin el padding-left extra del check viejo */
}
.c-lang-option {
  transition: background-color var(--transition-base);
}

/* Hover: fondo suave en toda la fila. El idioma activo mantiene su
   resalte más fuerte y no cambia en hover — ya está seleccionado. */
.c-lang-option:hover:not(.active) {
  background-color: var(--color-turquesa-50);
}
.c-lang-option:hover:not(.active) .c-lang-option__name {
  color: var(--color-turquesa-500);
}

/* Feedback de clic. Sobrescribe el :active heredado de
   ul.dropdown-menu li a.dropdown-item:active (fondo menta) para
   mantener la escala turquesa del componente. */
.c-lang-option:active {
  background-color: var(--color-turquesa-100) !important;
}
.c-lang-option:active .c-lang-option__code,
.c-lang-option:active .c-lang-option__name {
  color: var(--color-turquesa-700) !important;
}

.c-lang-option.active {
  background-color: var(--color-turquesa-100);
}
.c-lang-option.active .c-lang-option__code,
.c-lang-option.active .c-lang-option__name {
  color: var(--color-turquesa-700);
}

/* ----------------------------------------------------------
   BL-02 (desktop) — Fix: dropdown de submenús para ítems con hijos
   HOY (antes de este fix) el <ul class="sub-menu"> de WordPress se
   renderiza permanentemente visible, sin tratamiento — se ve roto en
   producción apenas un ítem tiene hijos (confirmado con "Test de
   sub-menú 01/02/03" en Consultoría). Este bloque lo convierte en un
   dropdown real, mismo mecanismo que el selector de idioma: clic para
   abrir, GSAP easeReverse para animar (ver main.js).
   ---------------------------------------------------------- */
/* El <a> con hijos reserva espacio para el caret con CSS puro, desde
   el primer render — sin esto, cuando el JS inserta el botón real
   (recién en DOMContentLoaded, después de que el HTML crudo ya se
   pintó), el link empuja a los ítems vecinos y todo "salta" (CLS,
   reportado sesión 4 de agosto). Reservando el espacio de antemano,
   el botón real solo ocupa un lugar que ya estaba libre. */
#navMenu .menu-item-has-children > a {
  padding-right: 2.1rem !important;
}

/* El subrayado animado (#navMenu ul li a::after) se extiende de borde a
   borde del <a>, incluido el padding-right que reserva el espacio del
   caret — por eso quedaba subrayado también el caret. Se retrae el
   borde derecho hasta donde termina el texto real del rótulo. Si
   cambia el padding-right de arriba, este valor tiene que cambiar
   junto con él. */
#navMenu .menu-item-has-children > a::after {
  right: 2.1rem;
}

/* El caret es position:absolute — NUNCA empuja layout, sin importar
   cuándo lo crea el JS (elimina el CLS de raíz, no solo lo mitiga con
   el padding de arriba). Mismo right:0.25rem resuelve los dos
   breakpoints sin reglas separadas: en desktop el <li> mide lo que su
   contenido (queda pegado al rótulo); en mobile el <li> es ancho
   completo (cae al borde derecho de la pantalla, como en el
   wireframe) — el ancho distinto del <li> en cada caso hace todo el
   trabajo.

   top:0 + padding, NO top:50%+translateY: el <li> es el contenedor de
   posicionamiento, y en mobile CRECE cuando el acordeón abre (el
   submenú es contenido normal, no absoluto). Con top:50% el caret
   flotaba al medio de TODO el bloque expandido en vez de quedarse
   pegado a la fila de arriba (reportado sesión 4 de agosto). El
   padding-top/bottom tiene que coincidir con el del <a> en cada
   breakpoint para que ambos queden alineados — ver los valores
   mobile-only más abajo. */
#navMenu .menu-item-has-children {
  position: relative;
}
.c-submenu-toggle {
  position: absolute;
  top: -2px;
  right: 0.25rem;
  padding: 0.5rem 0.4rem; /* Coincide con el padding vertical base del <a> (desktop). */
  background: transparent;
  border: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  cursor: pointer;
  color: var(--color-negro);
}
.c-submenu-toggle svg,
.c-submenu-toggle i[data-lucide] {
  width: 0.9rem;
  height: 0.9rem;
  display: block;
  transition: transform var(--transition-base);
}
.c-submenu-toggle[aria-expanded="true"] svg {
  transform: rotate(180deg);
}
.c-submenu-toggle:hover {
  color: var(--color-turquesa-500);
}

/* Estado base del submenú: cerrado e inaccesible al puntero.
   visibility:hidden (no solo opacity:0) para que un panel cerrado no
   capture clics invisibles. GSAP escribe estilos inline al animar, que
   ganan por especificidad sobre estas reglas.

   IMPORTANTE — se apunta también a "ul.sub-menu" (la clase que
   WordPress ya renderiza en el servidor), no solo a ".c-submenu" (la
   agrega main.js recién en DOMContentLoaded). Sin esto, el HTML crudo
   se pinta sin ninguna regla aplicada — el submenú se ve expandido y
   sin estilo por un instante hasta que el JS lo alcanza a ocultar
   (FOUC, reportado sesión 4 de agosto). Con ambos selectores, queda
   oculto desde el primer paint, con o sin JS.

   OJO: height:0 vive SOLO en el bloque mobile de abajo — en desktop el
   timeline anima transforms, no height, y un height:0 acá clipearía el
   panel de forma permanente. */
.c-submenu,
#navMenu .menu-item-has-children > ul.sub-menu {
  overflow: hidden;
  opacity: 0;
  visibility: hidden;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Fallback sin GSAP o con prefers-reduced-motion: el JS solo agrega
   .show y esta regla hace todo el trabajo, sin animación. */
.c-submenu.show {
  opacity: 1;
  visibility: visible;
  height: auto;
}
.c-submenu a {
  display: block;
  font-size: 0.8125rem;
  color: var(--color-gris-600);
  padding: 0.5rem 0.85rem;
  text-decoration: none;
  transition: background-color var(--transition-base), color var(--transition-base);
}

/* La regla global #navMenu ul li a::after (subrayado animado de los
   links de primer nivel) alcanzaba también a los items del submenú —
   de ahí el borde inferior pegado al texto en hover. Los items del
   submenú usan fondo, no subrayado. */
.c-submenu a::after {
  display: none !important;
}

.c-submenu a:hover {
  background-color: var(--color-turquesa-50);
  color: var(--color-turquesa-500) !important;
}

/* Mobile (<1200px): acordeón in-place. height:0 solo acá — es el único
   breakpoint donde el timeline anima height (el submenú tiene que
   empujar el contenido de abajo; no hay equivalente en transform).
   BL-33: migrado de 991px a 1199px junto con navbar-expand-lg→xl —
   este breakpoint tiene que coincidir siempre con el de Bootstrap,
   si no el acordeón mobile y el dropdown desktop compiten a la vez
   en la franja 992–1199px. */
@media (max-width: 1199px) {
  /* BL-33: al migrar el breakpoint de 991 a 1199, el acordeón mobile
     (pensado para ~375-575px) empezó a mostrarse también en tablet,
     donde .navbar-collapse hereda el ancho de .container de Bootstrap
     (960px en el rango lg) sin ningún tope propio — el menú se veía
     "pegado" edge-to-edge, demasiado ancho para una lista vertical.
     Opción A (decisión de Felipe, sesión BL-33): panel tipo drawer,
     angosto y alineado a la derecha, en vez de ocupar todo el
     .container.

     IMPORTANTE: este max-width va en .c-nav-drawer (wrapper interno,
     ver header.php), NUNCA directo en #navMenu.navbar-collapse.
     #navMenu depende de flex-basis:100% para que Bootstrap lo fuerce
     a su propia fila debajo del logo/toggler — ponerle max-width ahí
     clampea su tamaño hipotético por debajo del ancho de esa primera
     fila y Bootstrap deja de mandarlo a la fila de abajo (bug real,
     visto en sesión: el menú se mezclaba con el logo en el mismo row).

     En phones (<480px de contenido disponible) esto no cambia nada —
     el max-width nunca llega a limitar, el panel ya ocupa el 100% del
     espacio real disponible. */
  .c-nav-drawer {
    max-width: 480px;
    margin-left: auto;
  }

  .c-submenu,
  #navMenu .menu-item-has-children > ul.sub-menu {
    height: 0;
    padding-left: 0.85rem;
  }

  /* Separadores horizontales entre ítems de primer nivel + más aire
     vertical — el selector > apunta solo a los <li> de primer nivel,
     nunca a los del submenú anidado (mismo criterio que el wireframe:
     ahí tampoco hay línea entre "Sub-menú test 01/02/03"). */
  #navMenu ul.navbar-nav > li {
    border-bottom: 1px solid var(--color-gris-100);
    padding: 8px 0;
  }
  #navMenu ul.navbar-nav > li:last-child {
    border-bottom: none;
  }
  #navMenu ul.navbar-nav > li > a {
    padding-top: var(--space-md);    /* 1.5rem — subido desde 1rem. */
    padding-bottom: var(--space-md);
  }
  /* El subrayado animado (#navMenu ul li a::after) es un indicador de
     :hover pensado para desktop con mouse. En mobile no tiene sentido
     con tap, y encima con los separadores horizontales que ya agrega
     el punto anterior, queda una doble línea confusa bajo "Consulting"
     cuando es la página activa. Se oculta entero en este breakpoint. */
  #navMenu ul li a::after {
    display: none !important;
  }

  /* El caret más grande (punto pedido explícitamente para mobile,
     sesión 4 de agosto) es SOLO de este breakpoint — en desktop
     0.9rem ya estaba bien. Con el ícono más grande, el espacio
     reservado en el <a> y el corte del subrayado (arriba, fuera de
     este media query) también necesitan su propio valor mobile: si
     alguno de los tres cambia, los otros dos tienen que moverse junto
     con él. */
  #navMenu .menu-item-has-children > a {
    padding-right: 2.9rem !important;
  }
  #navMenu .menu-item-has-children > a::after {
    right: 2.9rem;
  }
  .c-submenu-toggle svg,
  .c-submenu-toggle i[data-lucide] {
    width: 1.25rem;
    height: 1.25rem;
  }

  /* El padding del caret tiene que coincidir con el nuevo padding
     vertical del <a> de arriba (var(--space-md)) — ver la nota junto a
     .c-submenu-toggle más arriba sobre por qué es top:0 + padding y no
     top:50%. Si cambia el padding del <a> en mobile, este valor tiene
     que cambiar junto con él.
     El padding lateral 0.75rem lleva el área tappeable a ~44px de
     ancho (20px de ícono + 24px de padding), el mínimo recomendado
     para targets táctiles. */
  .c-submenu-toggle {
    padding: 0.75rem;
  }

  /* Botón Contact — hoy hereda .c-btn--sm (compacto, pensado para
     desktop). El wireframe lo muestra como barra completa, mismo
     ancho que el resto del menú. Se mantiene el turquesa de marca
     (el navy del wireframe se descartó explícitamente como artefacto
     de la herramienta, sesión anterior) — este cambio es solo de
     estructura/tamaño, no de color. */
  #navMenu .site-header__controls .c-btn--primary {
    display: flex;
    width: 100%;
    justify-content: center;
    padding-top: 0.85rem;
    padding-bottom: 0.85rem;
  }
}

/* Tablet (992-1199px): el menú principal flota como un dropdown,
   anclado a la DERECHA, cerca de su propio trigger (el botón
   hamburguesa) — mismo patrón que ul.dropdown-menu del selector de
   idioma. Pedido explícito de Felipe (sesión BL-33): antes el menú
   estaba en flujo normal y empujaba el hero hacia abajo al abrirse; en
   tablet, con tanto espacio vertical de sobra, eso se sentía pesado.

   Historia de esta regla (por qué el contexto de anclaje NO va en
   #navMenu, a pesar de que sería lo más intuitivo):

   1ra versión: `#navMenu.navbar-collapse { position:relative }` con
   `.c-nav-drawer { position:absolute }` adentro. Visualmente andaba
   bien en el estado final (abierto/cerrado), pero generaba un glitch
   real durante la TRANSICIÓN: el header "crecía" empujando el hero
   hacia abajo mientras el menú se desplegaba, y al terminar la
   animación pegaba un salto de vuelta a su altura normal (reportado
   en sesión, con video).

   Causa: cuando el contenedor con position:relative (#navMenu) es
   también el contenedor con el que Bootstrap Collapse mide su propio
   scrollHeight para animar la apertura, el hijo absolute (.c-nav-drawer,
   ~500px de alto) cuenta como "overflow scrolleable" DE #navMenu —
   entonces Bootstrap ve un scrollHeight de ~500px en vez de ~0px, y
   anima la altura de #navMenu (que SÍ está en flujo normal, a
   diferencia de su hijo absolute) de 0 a 500px durante ~350ms. Eso es
   lo que empujaba el hero. Al terminar la transición, Bootstrap quita
   el height inline y #navMenu vuelve a su altura natural en flujo
   (~0, porque su único hijo es absolute y no cuenta para layout
   normal) — de ahí el salto de vuelta.

   Fix: el contexto de anclaje (position:relative) se mueve a
   .site-header__navbar (el <nav>, un ancestro estable que Bootstrap
   NUNCA mide para la animación — solo lee #navMenu.scrollHeight, no
   el de sus ancestros). #navMenu deja de ser positioned, así que su
   hijo absolute ya no cuenta en SU scrollHeight, y la animación de
   apertura vuelve a ser sobre un scrollHeight real de ~0px — sin
   empujar nada.

   (position:fixed se descartó como alternativa: .site-header tiene
   `transform` condicional vía .site-header--hidden — BL-19, header
   direccional — y cualquier transform en un ancestro rompe el
   contexto de position:fixed, haciéndolo errático según el estado de
   scroll.) */
@media (min-width: 992px) and (max-width: 1199px) {
  .site-header__navbar {
    position: relative; /* contexto de anclaje para .c-nav-drawer — NUNCA #navMenu, ver nota arriba. */
  }

  .c-nav-drawer {
    position: absolute;
    top: 100%;
    right: calc(var(--bs-gutter-x, 1.5rem) * 0.5); /* mismo padding que .container, para alinear con el borde derecho real del header */
    left: auto;
    margin-left: 0; /* anula el margin-left:auto (ancla izquierda) del bloque compartido de arriba */
    width: 480px;
    background: var(--color-blanco);
    border-radius: 6px;
    box-shadow: 0 4px 20px rgba(2, 9, 10, 0.12);
    padding: 0.75rem 1rem; /* padding horizontal nuevo — pedido explícito, antes el panel no tenía respiro lateral */
    z-index: 1031; /* mismo nivel que ul.dropdown-menu / .c-submenu — por sobre .site-header (1030). */
  }
}

/* Desktop (≥1200px): dropdown flotante, mismo tratamiento visual que
   ul.dropdown-menu (Bootstrap) aunque no usa su mismo mecanismo JS —
   ver nota en main.js sobre por qué esto NO reutiliza data-bs-toggle.
   BL-33: migrado de 992px a 1200px, a la par de navbar-expand-xl. */
@media (min-width: 1200px) {
  .c-submenu,
  #navMenu .menu-item-has-children > ul.sub-menu {
    position: absolute;
    top: 100%; /* Sin gap a propósito: con hover, un espacio vacío entre
                  el trigger y el panel es zona muerta — el mouse lo
                  cruza sin estar sobre ningún elemento y dispara
                  mouseleave antes de llegar al panel. El overlap con
                  el subrayado se resuelve con z-index (ver abajo), no
                  con separación física. */
    left: 0;
    min-width: 200px;
    background: var(--color-blanco);
    border-radius: 6px;
    box-shadow: 0 4px 20px rgba(2, 9, 10, 0.12);
    padding: 0.4rem 0;
    z-index: 1031; /* Por sobre .site-header (1030). */
  }

  /* El subrayado animado (#navMenu ul li a::after) vive en bottom:0
     del <a>, casi pegado al borde del <li> — justo donde arranca el
     dropdown. Como ul.sub-menu aparece después en el DOM, pintaba
     encima y lo tapaba. z-index más alto que el del panel (1031) para
     que el trigger completo, subrayado incluido, quede siempre visible
     por encima. */
  #navMenu .menu-item-has-children > a {
    z-index: 1032;
  }

  /* BL-33 — fix urgente: .c-nav-drawer (wrapper agregado para el drawer
     de tablet, ver bloque @media max-width:1199px más arriba) rompió
     desktop. Bootstrap pone #navMenu en display:flex a partir de este
     breakpoint (.navbar-expand-xl .navbar-collapse) para que ul.navbar-nav
     (mx-auto) y .site-header__controls queden lado a lado en una sola
     fila, repartidos en todo el ancho del header. Con el wrapper de por
     medio, #navMenu ahora tiene un solo hijo (.c-nav-drawer) sin ningún
     display:flex propio — sus dos hijos (ul, div) caían como bloques
     normales, uno debajo del otro, apretados a la izquierda (bug
     reportado en sesión: el header se veía partido en dos filas).
     flex-grow:1 acá replica el que #navMenu ya tenía de Bootstrap, para
     que el wrapper ocupe todo el ancho disponible — si no, mx-auto en
     el <ul> no tiene espacio real donde centrarse. */
  .c-nav-drawer {
    display: flex;
    align-items: center;
    flex-grow: 1;
  }
}

/* ============================================================
   5. COMPONENTE GLOBAL — .c-btn
   ============================================================
   Sistema de botones del tema felipeonate.

   Variantes: --primary · --secondary · --ghost
   Tamaños:   --sm · (md, default) · --lg
   Estado:    :disabled / .is-disabled
   ============================================================ */

/* ----------------------------------------------------------
   Base
   ---------------------------------------------------------- */
.c-btn {
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  gap:             0.5rem;
  height:          44px;
  padding:         0 20px;
  border-radius:   8px;
  border:          1.5px solid transparent;
  font-family:     var(--font-body);
  font-weight:     var(--fw-semibold);
  font-size:       14.5px;
  text-decoration: none;
  white-space:     nowrap;
  cursor:          pointer;
  transition:      background-color 0.2s ease,
                   color 0.2s ease,
                   border-color 0.2s ease,
                   box-shadow 0.2s ease,
                   transform 0.15s ease,
                   gap 0.2s ease;
}

/* i[data-lucide] reservado igual que svg — antes de que Lucide corra,
   el ícono es un <i> vacío sin tamaño, y el botón salta al agrandarse
   recién cuando el JS lo reemplaza (CLS, sesión 4 de agosto). Aplica a
   cualquier .c-btn del sitio, no solo al de Contacto del header. */
.c-btn svg,
.c-btn i[data-lucide] {
  width:       16px;
  height:      16px;
  flex-shrink: 0;
  display:     inline-block;
}

/* ----------------------------------------------------------
   Tamaños
   ---------------------------------------------------------- */
.c-btn--sm { height: 36px; padding: 0 14px; font-size: 13px; }
.c-btn--lg { height: 54px; padding: 0 28px; font-size: 16px; }

/* ----------------------------------------------------------
   .c-btn--primary
   ---------------------------------------------------------- */
.c-btn--primary {
  background-color: var(--color-turquesa-500);
  border-color:     var(--color-turquesa-500);
  color:            var(--color-blanco);
}
.c-btn--primary:hover {
  background-color: var(--color-turquesa-600);
  border-color:     var(--color-turquesa-600);
  color:            var(--color-blanco);
  transform:        translateY(-1px);
  box-shadow:       0 8px 24px rgba(22, 129, 150, 0.3);
  text-decoration:  none;
}
.c-btn--primary:active {
  background-color: var(--color-turquesa-700);
  border-color:     var(--color-turquesa-700);
  color:            var(--color-blanco);
  transform:        none;
  box-shadow:       none;
}

/* ----------------------------------------------------------
   .c-btn--secondary
   ---------------------------------------------------------- */
.c-btn--secondary {
  background-color: transparent;
  border-color:     var(--color-turquesa-500);
  color:            var(--color-turquesa-500);
}
.c-btn--secondary:hover {
  background-color: var(--color-turquesa-50);
  color:            var(--color-turquesa-500);
  transform:        translateY(-1px);
  text-decoration:  none;
}
.c-btn--secondary:active {
  background-color: var(--color-turquesa-100);
  color:            var(--color-turquesa-500);
  transform:        none;
}

/* ----------------------------------------------------------
   .c-btn--secondary.c-btn--inverse (para fondos de color, ej. Hero)
   ---------------------------------------------------------- */
.c-btn--secondary.c-btn--inverse {
  border-color: var(--color-blanco);
  color:        var(--color-blanco);
}
.c-btn--secondary.c-btn--inverse:hover {
  background-color: rgba(250, 250, 250, 0.15);
  color:            var(--color-blanco);
}
.c-btn--secondary.c-btn--inverse:active {
  background-color: rgba(250, 250, 250, 0.25);
  color:            var(--color-blanco);
}

/* ----------------------------------------------------------
   .c-btn--ghost
   ---------------------------------------------------------- */
.c-btn--ghost {
  background-color: transparent;
  border-color:     transparent;
  color:            var(--color-turquesa-500);
  padding:          0;
  height:           auto;
  gap:              0.4rem;
  justify-content:  flex-start;
  align-self:       flex-start;
}
.c-btn--ghost:hover {
  color:           var(--color-turquesa-600);
  gap:             0.7rem;
  text-decoration: none;
}
.c-btn--ghost:active {
  color: var(--color-turquesa-700);
}

/* ----------------------------------------------------------
   Estado deshabilitado
   ---------------------------------------------------------- */
.c-btn:disabled,
.c-btn.is-disabled {
  opacity:        0.5;
  pointer-events: none;
  box-shadow:     none;
  transform:      none;
}


/* ============================================
   6. SITE CONTACT
   ============================================ */

.contact-section {
  padding: 5rem 0;
  background: linear-gradient(135deg, #09343C 0%, #0D4D5A 55%, #126778 100%);
  color: var(--color-blanco);
}
.contact-section h2 {
  font-size: clamp(1.8rem, 3vw, 2.5rem);
  color: var(--color-blanco);
  margin-bottom: 1rem;
}
.contact-section p {
  color: rgba(250,250,250,0.7);
  font-size: 0.9375rem;
}

.social-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 8px;
  border: 1.5px solid rgba(250,250,250,0.2);
  color: rgba(250,250,250,0.7);
  text-decoration: none !important;
  font-size: 1.2rem;
  transition: border-color 0.2s, color 0.2s, background-color 0.2s;
}
.social-btn:hover {
  border-color: var(--color-turquesa-500);
  color: var(--color-turquesa-500);
  background-color: rgba(22,129,150,0.08);
}

.form-control-dark {
  background: rgba(250,250,250,0.06);
  border: 1.5px solid rgba(250,250,250,0.12);
  border-radius: 8px;
  color: var(--color-blanco);
  padding: 0.85rem 1.1rem;
  font-family: 'Montserrat', sans-serif;
  font-size: 0.9rem;
  width: 100%;
  transition: border-color 0.2s, background 0.2s;
  outline: none;
}
.form-control-dark::placeholder { color: rgba(250,250,250,0.35); }
.form-control-dark:focus {
  border-color: var(--color-turquesa-500);
  background: rgba(22,129,150,0.06);
}


/* ============================================
   CF7 OVERRIDES
   ============================================ */

.wpcf7 form p { margin: 0; }

.wpcf7-form-control-wrap {
  display: block;
  width: 100%;
}

.wpcf7 input[type="text"],
.wpcf7 input[type="email"] {
  background: rgba(250,250,250,0.06);
  border: 1.5px solid rgba(250,250,250,0.12);
  border-radius: 8px;
  color: var(--color-blanco);
  padding: 0.85rem 1.1rem;
  font-family: 'Montserrat', sans-serif;
  font-size: 0.9rem;
  width: 100%;
  transition: border-color 0.2s, background 0.2s;
  outline: none;
  box-shadow: none;
}

.wpcf7 textarea {
  background: rgba(250,250,250,0.06);
  border: 1.5px solid rgba(250,250,250,0.12);
  border-radius: 8px;
  color: var(--color-blanco);
  padding: 0.85rem 1.1rem;
  font-family: 'Montserrat', sans-serif;
  font-size: 0.9rem;
  width: 100%;
  transition: border-color 0.2s, background 0.2s;
  outline: none;
  resize: vertical;
}

.wpcf7 input[type="text"]::placeholder,
.wpcf7 input[type="email"]::placeholder,
.wpcf7 textarea::placeholder {
  color: rgba(250,250,250,0.35);
}

.wpcf7 input[type="text"]:focus,
.wpcf7 input[type="email"]:focus,
.wpcf7 textarea:focus {
  border-color: var(--color-turquesa-500);
  background: rgba(22,129,150,0.06);
}

.wpcf7 input[type="submit"] {
  font-family: 'Montserrat', sans-serif;
  font-weight: 600;
  font-size: 0.9375rem;
  background: var(--color-turquesa-500);
  color: var(--color-blanco);
  border: none;
  border-radius: 8px;
  padding: 0.9rem 2rem;
  cursor: pointer;
  transition: background 0.2s, transform 0.15s, box-shadow 0.2s;
  width: auto;
}

.wpcf7 input[type="submit"]:hover {
  background: var(--color-turquesa-400);
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(22,129,150,0.35);
}

/* La familia se toma de --fa-font-solid (variable que expone Font Awesome)
   en vez de escribir "Font Awesome N Free" a mano: FA renombra esa familia
   en cada versión mayor, y hardcodearla hacía que el icono desapareciera en
   silencio al actualizar. El shorthand `font:` incluye el 1em de la propia
   variable, por eso el font-size va DESPUÉS (si no, lo pisaría). */
.wpcf7 input[type="submit"]::after {
  content: "\f061";
  font: var(--fa-font-solid);
  margin-left: 0.5rem;
  font-size: 0.875rem;
}

.wpcf7-not-valid-tip {
    background: var(--color-error-soft);
    color: var(--color-gris-700);
    border: 1px solid var(--color-error);
    border-radius: 8px;
    padding: 0.375rem 0.625rem;
    font-size: 0.75rem;
    margin-top: 0.5rem;
    display: block;
    /* !important: el CSS default del plugin CF7 también define este
       selector — si carga después o con más peso, pisa el relative de
       vuelta a absolute. Mismo motivo por el que .wpcf7-response-output
       más abajo en este archivo ya usa !important contra el plugin. */
    position: relative !important;
    width: fit-content;
    max-width: 100%;
  }

  /* Punta del tooltip: triángulo exterior (borde) + interior (fondo) */
  .wpcf7-not-valid-tip::before {
    content: "";
    position: absolute;
    top: -7px;
    left: 14px;
    border-left: 7px solid transparent;
    border-right: 7px solid transparent;
    border-bottom: 7px solid var(--color-error);
  }

  .wpcf7-not-valid-tip::after {
    content: "";
    position: absolute;
    top: -6px;
    left: 15px;
    border-left: 6px solid transparent;
    border-right: 6px solid transparent;
    border-bottom: 6px solid var(--color-error-soft);
  }

.wpcf7 input.wpcf7-not-valid,
.wpcf7 textarea.wpcf7-not-valid {
  border-color: var(--color-error) !important;
  /* !important porque .wpcf7 input[type="text"]:focus (más abajo… no,
     ARRIBA en este archivo) tiene más especificidad (2 clases/pseudo +
     1 tipo vs. 1 clase + 1 tipo acá) y le ganaba al rojo mientras el
     campo seguía enfocado — que es el estado típico justo después de
     un submit fallido con autofocus al primer campo inválido. Sin
     esto, el borde se veía teal (focus) en vez de rojo (error) en el
     momento exacto en que más importa mostrarlo. */
}

.wpcf7-response-output {
  border-radius: 8px !important;
  font-size: 0.875rem;
  border: none !important;
}

.wpcf7 form.sent .wpcf7-response-output {
  background: var(--color-success-soft);
  color: var(--color-gris-700);
  border: 1px solid var(--color-success) !important;
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  padding: 0.75rem 1rem !important;
  margin-top: 1rem !important;
  width: fit-content;
}

/* Ícono circle-check (Lucide) */
.wpcf7 form.sent .wpcf7-response-output::before {
  content: "";
  flex: 0 0 18px;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  background-color: var(--color-success);
  -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></svg>') center / contain no-repeat;
  mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></svg>') center / contain no-repeat;
}

.wpcf7 form.failed .wpcf7-response-output,
.wpcf7 form.invalid .wpcf7-response-output {
  /* Pedido explícito de Felipe (sesión BL-33): ocultar el banner de
     error de CF7. Ojo — esto NO toca form.sent .wpcf7-response-output
     (el mensaje de éxito, arriba en este archivo), que sigue visible.
     Acotado a invalid/failed a propósito: display:none en
     .wpcf7-response-output sin condición también habría tapado la
     confirmación de "enviado con éxito", que comparte la misma clase
     base. */
  display: none !important;
}

/* Ícono circle-alert (Lucide) vía máscara CSS: CF7 regenera este
   nodo por JS en cada envío, un <i data-lucide> no sobreviviría. */
.wpcf7 form.failed .wpcf7-response-output::before,
.wpcf7 form.invalid .wpcf7-response-output::before {
  content: "";
  flex: 0 0 18px;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  background-color: var(--color-error);
  -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>') center / contain no-repeat;
  mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>') center / contain no-repeat;
}

/* Ocultar el resumen de errores para lectores de pantalla */
.screen-reader-response {
  position: absolute;
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  border: 0;
}

/* ============================================================
   6. SITE FOOTER
   ============================================================ */

.site-footer {
  background-color: var(--color-turquesa-900);
  padding: 1.25rem 0;
}

/* ----------------------------------------------------------
   .site-footer__legal — Barra de copyright
   ---------------------------------------------------------- */
/*.site-footer__legal {
  border-top:  1px solid rgba(250, 250, 250, 0.1);
  margin-top:  var(--space-lg);
  padding-top: var(--space-md);
}*/

.site-footer__legal p {
  font-size:   0.8125rem;
  color:       rgba(250, 250, 250, 0.4);
  margin:      0;
  max-width:   none;
}

.site-footer__legal a {
  color: rgba(250, 250, 250, 0.5);
  text-decoration: none;
  transition: color 0.2s;
}

.site-footer__legal a:hover {
  color: var(--color-turquesa-500);
}

/* ----------------------------------------------------------
   .c-form__legal — Aviso legal reCAPTCHA bajo formularios
   Mismo tamaño que .site-footer__legal, color heredado del
   contexto (funciona igual en fondo oscuro o claro).
   ---------------------------------------------------------- */
.c-form__legal {
  font-size: 0.8125rem !important;
  color: currentColor !important;
  opacity: 0.6 !important;
  margin: 0 0 var(--space-sm) 0 !important;
}

.c-form__legal a {
  color: currentColor !important;
  text-decoration: underline !important;
  opacity: 0.85 !important;
  transition: opacity 0.2s !important;
}

.c-form__legal a:hover {
  opacity: 1 !important;
  color: var(--color-menta-500) !important;
}

.grecaptcha-badge {
  visibility: hidden;
}

/* ----------------------------------------------------------
   Responsive — Footer
   En mobile las 3 columnas se apilan verticalmente.
   Bootstrap .col-md-4 ya lo gestiona; solo ajustes visuales aquí.
   ---------------------------------------------------------- */
/*@media (max-width: 767px) {
  .site-footer {
    padding-top: var(--space-lg);
    text-align:  center;
  }

  .site-footer__brand .site-tagline {
    max-width: none;
  }

  .site-footer__social ul {
    justify-content: center;
  }

  .site-footer__legal {
    text-align: center;
  }
}*/


/* ============================================================
   7. UTILIDADES DE ANIMACIÓN
   ============================================================
   .fade-up          → Estado inicial: invisible + desplazado 24px hacia abajo.
   .fade-up.visible  → Estado final: visible en posición natural.
                       La clase .visible la agrega el IntersectionObserver
                       en main.js cuando el elemento entra al viewport.
   .delay-N          → Retrasa la transición para stagger en grids.
                       delay-1 a delay-3 → page-home.php (grids de 3 cols).
                       delay-4 y delay-5 → c-badges (5 items) y c-steps (4 items)
                       en template-consulting.php.
   ============================================================ */

.fade-up {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
.fade-up.visible {
  opacity: 1;
  transform: translateY(0);
}
.delay-1 { transition-delay: 0.1s; }
.delay-2 { transition-delay: 0.2s; }
.delay-3 { transition-delay: 0.3s; }
.delay-4 { transition-delay: 0.4s; }
.delay-5 { transition-delay: 0.5s; }