/* ---- Reset & base ---- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* Capa de color del "Filtro" de una tarjeta "Formato de imagen (y video)" —
   ver applyMediaFilter() en site-settings.js. Compartida por todos los
   módulos que tienen esa tarjeta (Cuadros, Carrusel simple, Insights, Hero
   lateral, Texto libre, CTA final, Blog). */
.media-filter-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  display: none;
  /* El borde opcional (cuando el wrapper lo tiene) se dibuja como
     background-color + padding del MISMO wrapper que este overlay llena por
     completo (inset:0 cubre hasta el borde exterior del padding) — sin esto,
     el mix-blend-mode también teñiría el anillo del borde, no solo la
     imagen/video de adentro. padding:inherit copia el padding real del
     wrapper (0 si no hay borde) y background-clip recorta el color del
     overlay para que no pinte esa franja. */
  padding: inherit;
  background-clip: content-box;
  /* Cuando la forma no es Rectángulo, el wrapper recorta con clip-path
     (círculo/triángulo) y este overlay queda contenido ahí adentro porque el
     wrapper tiene overflow:hidden — pero ese recorte depende de que el
     navegador siga aplicando bien el overflow del wrapper mientras un
     HERMANO (la imagen/video) se anima con transform (rotar, flip — ver
     Efecto de la Imagen lateral del Hero). Algunos navegadores pierden ese
     recorte del padre en pleno medio de una animación de un hermano
     compuesto en su propia capa GPU. clip-path:inherit hace que este overlay
     copie SIEMPRE la forma real del wrapper (no depende de su overflow ni de
     lo que esté haciendo la imagen al lado) — así el color nunca se escapa a
     la caja cuadrada de atrás, ni siquiera en pleno giro. */
  clip-path: inherit;
}

:root {
  --black: #0b0f0d;
  --black-soft: #101512;
  --green: #16a34a;
  --green-dark: #0e7a37;
  --green-bright: #22c55e;
  --white: #ffffff;
  --gray-100: #f4f6f5;
  --gray-300: #d1d7d4;
  --gray-500: #8a938e;
  --gray-700: #4b544f;
  --text-heading: #0b0f0d;
  --text-body: #4b544f;
  --text-light: #d1d7d4;
  --text-eyebrow: #0e7a37;
  --header-bg: #0b0f0d;
  --header-text: #ffffff;
  --font-family: "Jost", "Segoe UI", Roboto, -apple-system, BlinkMacSystemFont, Arial, sans-serif;
  --font-weight-base: 400;
  --size-h1: 3.2rem;
  --weight-h1: 700;
  --size-h2: 2.1rem;
  --weight-h2: 700;
  --size-subtitle: 1.05rem;
  --weight-subtitle: 400;
  --size-body: .95rem;
  --weight-body: 400;
  --size-menu: .95rem;
  --weight-menu: 400;
  --size-small: .85rem;
  --weight-small: 700;
  --size-btn: .95rem;
  --weight-btn: 600;
  --header-h: 64px;
  --radius: 10px;
  --max-w: 1200px;
  font-size: 16px;
}

html { scroll-behavior: smooth; }

body {
  font-family: var(--font-family);
  font-weight: var(--font-weight-base);
  color: var(--black);
  background: var(--white);
  line-height: 1.5;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

/* Home/Páginas arman el contenido de #main enteramente por JS (clona
   plantillas de bloque — ver applyPageBlocks en site-settings.js), así que
   #main llega vacío del servidor. Sin esto, mientras cargan/ejecutan los
   scripts se ve un instante header+footer con nada en el medio — muy
   parecido a la pantalla de "Página no encontrada". Se oculta hasta que JS
   confirma que terminó (clase .is-ready, ver el mismo archivo), con un
   fallback por si JS tarda o falla, para no dejar la página en blanco para
   siempre. No aplica al Blog (blog-index.php/blog-post.php): ese contenido
   ya viene armado desde PHP, sin esta espera.
   El opacity:0 por sí solo dejaba ver el blanco liso de <body> detrás —
   igual de "fantasma" que antes, solo que en blanco en vez de sin estilo.
   Por eso <body> también arranca con el mismo fondo oscuro del header
   (--header-bg) mientras carga, y recién vuelve a su blanco normal cuando
   todo está listo — el hueco se mezcla con el header en vez de resaltar. */
body:not(.site-ready) { background: var(--header-bg, #0b0f0d); }
#main { opacity: 0; transition: opacity .2s ease; }
#main.is-ready { opacity: 1; }
ul { list-style: none; }
button { font: inherit; background: none; border: none; cursor: pointer; color: inherit; }

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--green);
  color: var(--white);
  padding: 10px 16px;
  z-index: 1000;
}
.skip-link:focus { left: 8px; top: 8px; }

/* ---- Header ---- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 500;
  background: var(--header-bg);
  height: var(--header-h);
  border-bottom: 1px solid rgba(255,255,255,.08);
}
.site-header.is-not-sticky { position: relative; }

.header-inner {
  max-width: var(--max-w);
  margin: 0 auto;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
}
.site-header.menu-align-left .header-inner { flex-direction: row-reverse; }

.logo { display: flex; align-items: center; gap: 10px; color: var(--text-light); }
.logo-default { display: flex; align-items: center; gap: 10px; }
.logo-mark {
  width: 26px; height: 26px;
  border-radius: 6px;
  background: linear-gradient(135deg, var(--green-bright), var(--green-dark));
  display: inline-block;
}
.logo-text { font-weight: 700; font-size: 1.15rem; letter-spacing: .3px; }
.logo-img { height: 32px; width: auto; display: block; }

.nav-toggle {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  z-index: 600;
}
.nav-toggle span {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--header-text);
  transition: transform .25s ease, opacity .25s ease;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.main-nav {
  position: fixed;
  top: var(--header-h);
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--header-bg);
  transform: translateX(100%);
  transition: transform .3s ease;
  overflow-y: auto;
  padding: 10px 20px 40px;
}
.main-nav.open { transform: translateX(0); }

.nav-list { display: flex; flex-direction: column; }
.nav-item { border-bottom: 1px solid rgba(255,255,255,.08); }
.nav-link {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 16px 4px;
  color: var(--text-light);
  font-size: var(--size-nav_link, var(--size-menu));
  font-weight: var(--weight-nav_link, var(--weight-menu));
  text-align: left;
}
.nav-link .chev { margin-left: auto; }

.nav-icon { flex-shrink: 0; display: none; }
.main-nav.show-icons .nav-icon { display: inline-flex; }

.chev {
  width: 9px; height: 9px;
  border-right: 2px solid var(--gray-300);
  border-bottom: 2px solid var(--gray-300);
  transform: rotate(45deg);
  transition: transform .25s ease;
  flex-shrink: 0;
}
.submenu-toggle[aria-expanded="true"] .chev { transform: rotate(-135deg); }

.submenu {
  max-height: 0;
  overflow: hidden;
  transition: max-height .3s ease;
}
.has-submenu.open .submenu { max-height: 400px; }
.submenu ul { padding: 0 4px 12px 12px; }
.submenu a {
  display: block;
  padding: 10px 0;
  color: var(--gray-300);
  font-size: .95rem;
  border-left: 2px solid var(--green);
  padding-left: 12px;
}
.submenu a:hover { color: var(--green-bright); }

.nav-cta { margin-top: 20px; display: flex; align-items: center; gap: 10px; }
.nav-cta .btn { font-size: var(--size-header_action_btn_text, var(--size-btn)); font-weight: var(--weight-header_action_btn_text, var(--weight-btn)); }

.btn-admin-access {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,.3);
  color: var(--gray-300);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color .2s ease, color .2s ease;
}
.btn-admin-access:hover { border-color: var(--green-bright); color: var(--green-bright); }

/* ---- Buttons ---- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 22px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-weight: var(--weight-btn);
  font-size: var(--size-btn);
  transition: background .2s ease, color .2s ease, border-color .2s ease;
  white-space: nowrap;
}
.btn-primary { background: var(--green); color: var(--white); }
.btn-primary:hover { background: var(--green-dark); }
.btn-ghost { border: 1px solid var(--black); color: var(--black); }
.btn-ghost:hover { background: var(--black); color: var(--white); }
.btn-text-only { padding: 0; border: none; background: transparent; }
.btn-text-only:hover { text-decoration: underline; }
.btn-icon { display: inline-flex; }
.btn-icon svg { display: block; }
.btn-icon img { display: block; }
.btn-outline-light { border: 1px solid rgba(255,255,255,.4); color: var(--white); width: 100%; }
.btn-outline-light:hover { background: var(--white); color: var(--black); }

/* ---- Hero ---- */
.hero {
  position: relative;
  overflow: hidden;
  background: radial-gradient(120% 100% at 100% 0%, #123321 0%, var(--black) 55%);
  color: var(--hero-text, var(--white));
  padding: 32px 20px;
  display: flex;
  align-items: center;
}

.hero.is-sticky {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1;
}
.hero.is-sticky ~ .hero,
.hero.is-sticky ~ .stats,
.hero.is-sticky ~ .section,
.hero.is-sticky ~ .cta-banner,
.site-footer {
  /* .site-footer va siempre acá (sin el prefijo ~.hero.is-sticky): vive
     afuera de <main>, así que ningún selector de hermanos que arranque en
     .hero puede alcanzarlo — sin esto, un Hero "fijo" queda tapando el
     footer para siempre, sin importar cuánto scrolleés. */
  position: relative;
  z-index: 2;
}

.hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.hero-media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.hero-media iframe {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 177.77vh;   /* 16:9 cover trick */
  height: 56.25vw;
  min-width: 100%;
  min-height: 100%;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

.hero-inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--max-w);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 32px;
}
.hero-inner.has-side-image { align-items: center; }

.hero-text {
  min-width: 0;
  /* Siempre delante de la imagen lateral (ver .hero-side-image más abajo) —
     si el texto es muy largo y se desborda de su columna, tiene que
     superponerse ARRIBA de la imagen, no quedar tapado detrás. */
  position: relative;
  z-index: 2;
  /* Una palabra sin espacios (o un texto excesivamente largo) se corta
     dentro de su propia columna en vez de desbordar hacia el resto del
     Hero — antes de esto, un texto así se salía por completo de .hero-text
     y quedaba pintado detrás de la imagen lateral por orden del DOM. */
  overflow-wrap: break-word;
  word-break: break-word;
}

.hero-side-image { display: none; order: 1; position: relative; z-index: 1; perspective: 800px; }
.hero-side-image.is-visible { display: block; width: 100%; max-width: var(--hero-side-image-size-mobile, 60%); margin: 0 auto; }
.hero-inner.image-mobile-above .hero-side-image { order: -1; }

/* Contenedor de la forma (mismo sistema que .cta-media-shape): Rectángulo
   (default) mantiene el % de ancho de siempre (desktop/móvil, ver media
   query más abajo); Cuadrado/Círculo/Triángulo fuerzan lados iguales según
   --hero-side-media-size ("Tamaño") — reemplazan el % por un tamaño chico
   fijo, así que el contenedor EXTERIOR (.hero-side-image) también se
   achica a su contenido (fit-content) en vez de seguir ocupando el 45%/60%
   de siempre, para no dejar un hueco vacío al lado de una insignia chica.
   El borde es background-color + padding acá, recorte replicado en la
   imagen/video de adentro = anillo de borde, mismo criterio que CTA. */
.hero-side-media-shape {
  /* isolation:isolate = frontera de mezcla del filtro de color, para que
     solo tiña la imagen/video de adentro — mismo criterio en los 6 wrappers
     de forma del sitio (Cuadros/Carrusel simple/Insights/Texto libre/CTA). */
  display: block; position: relative; isolation: isolate; box-sizing: border-box; overflow: hidden; width: 100%;
  border-radius: var(--hero-side-media-radius, var(--radius));
  background-color: var(--hero-side-media-border-color, transparent);
  padding: var(--hero-side-media-border-width, 0);
}
.hero-side-media-shape img, .hero-side-media-shape video {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
#heroSideVideoEmbedEl {
  width: 100%; height: auto; aspect-ratio: 16 / 9; border: none; display: block;
  border-radius: var(--hero-side-media-radius, var(--radius));
}
.hero-side-image:not([data-media-shape="rectangle"]).is-visible { max-width: fit-content !important; }
.hero-side-image:not([data-media-shape="rectangle"]) .hero-side-media-shape {
  width: var(--hero-side-media-size, 220px);
  max-width: min(var(--hero-side-media-size, 220px), 100%);
  aspect-ratio: 1 / 1;
  margin: 0 auto;
}
.hero-side-image[data-media-shape="triangle-up"] .hero-side-media-shape,
.hero-side-image[data-media-shape="triangle-down"] .hero-side-media-shape { aspect-ratio: 1 / 0.866; }
.hero-side-image[data-media-shape="circle"] .hero-side-media-shape,
.hero-side-image[data-media-shape="circle"] .hero-side-media-shape img,
.hero-side-image[data-media-shape="circle"] .hero-side-media-shape video {
  border-radius: 50%; clip-path: circle(50% at 50% 50%);
}
.hero-side-image[data-media-shape="triangle-up"] .hero-side-media-shape,
.hero-side-image[data-media-shape="triangle-up"] .hero-side-media-shape img,
.hero-side-image[data-media-shape="triangle-up"] .hero-side-media-shape video {
  border-radius: 0; clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
.hero-side-image[data-media-shape="triangle-down"] .hero-side-media-shape,
.hero-side-image[data-media-shape="triangle-down"] .hero-side-media-shape img,
.hero-side-image[data-media-shape="triangle-down"] .hero-side-media-shape video {
  border-radius: 0; clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
}
/* Con borde activo, la imagen/video queda en una caja más chica que el
   wrapper (achicada por el padding del borde) y su proporción real deja de
   ser 1/0.866 — el triángulo de adentro queda desalineado del de afuera y el
   borde se ve disparejo entre los 3 lados (mismo bug que .cta-media-shape,
   ver ahí el detalle completo). Forzar el mismo aspect-ratio acá lo evita. */
.hero-side-image[data-media-shape="triangle-up"] .hero-side-media-shape img,
.hero-side-image[data-media-shape="triangle-up"] .hero-side-media-shape video,
.hero-side-image[data-media-shape="triangle-down"] .hero-side-media-shape img,
.hero-side-image[data-media-shape="triangle-down"] .hero-side-media-shape video {
  aspect-ratio: 1 / 0.866; height: auto;
}

/* Efecto de Entrada/Movimiento de la imagen lateral (menú Portada > Imagen
   lateral > Efecto) — animation se arma en JS (ver heroSideEffectAnimation
   en site-settings.js, duplicada en admin.js para la previsualización) según
   los dos selects; acá solo viven los keyframes que consume. */
@keyframes heroSideFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes heroSideSlideIn { from { opacity: 0; transform: translateX(var(--hero-slide-x, 40px)); } to { opacity: 1; transform: translateX(0); } }
@keyframes heroSideZoomIn { from { opacity: 0; transform: scale(.7); } to { opacity: 1; transform: scale(1); } }
@keyframes heroSideBounceIn {
  0% { opacity: 0; transform: scale(.3); }
  50% { opacity: 1; transform: scale(1.05); }
  70% { transform: scale(.95); }
  100% { transform: scale(1); }
}
@keyframes heroSidePulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.06); } }
@keyframes heroSideSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes heroSideWobble { 0%, 100% { transform: rotate(-4deg); } 50% { transform: rotate(4deg); } }
@keyframes heroSideBlink { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
@keyframes heroSideFlip { from { transform: rotateX(0deg); } to { transform: rotateX(360deg); } }

.eyebrow {
  color: var(--text-eyebrow);
  font-weight: var(--weight-eyebrow, var(--weight-body));
  font-size: var(--size-eyebrow, var(--size-body));
  text-transform: uppercase;
  letter-spacing: 1.2px;
  margin-bottom: 14px;
}
.hero-title {
  font-size: min(var(--size-hero_title, var(--size-h1)), 14vw);
  line-height: 1.15;
  font-weight: var(--weight-hero_title, var(--weight-h1));
  max-width: 16ch;
  margin-bottom: 18px;
  color: var(--hero-text, var(--text-heading));
}
.hero-sub {
  color: var(--hero-text, var(--text-body));
  opacity: .85;
  font-size: var(--size-hero_subtitle, var(--size-subtitle));
  font-weight: var(--weight-hero_subtitle, var(--weight-subtitle));
  max-width: 46ch;
  margin-bottom: 28px;
}
.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.hero-actions .btn { font-size: var(--size-hero_btn_text, var(--size-btn)); font-weight: var(--weight-hero_btn_text, var(--weight-btn)); }
.hero-actions .btn-ghost { border-color: rgba(255,255,255,.5); color: inherit; }
.hero-actions .btn-ghost:hover { background: var(--white); color: var(--black); }

/* ---- Stats ---- */
.stats { background: var(--black-soft); padding: 32px 20px; }
.stats-grid {
  max-width: var(--max-w);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
}
.stat { text-align: center; color: var(--white); }
.stat-number {
  display: block;
  font-size: clamp(1.6rem, 5vw, 2.4rem);
  font-weight: 700;
  color: var(--green-bright);
}
.stat-label { font-size: var(--size-stat_label, var(--size-small)); font-weight: var(--weight-stat_label, var(--weight-small)); color: var(--text-light); }

/* ---- Sections ---- */
.section { background: var(--white); padding: 56px 20px; }
.section > * { max-width: var(--max-w); margin-left: auto; margin-right: auto; }
.section-head { margin-bottom: 28px; }
.section-head h2 { font-size: min(var(--size-section_title, var(--size-h2)), 10vw); font-weight: var(--weight-section_title, var(--weight-h2)); color: var(--text-heading); }
.section-head .section-sub { margin-top: 10px; font-size: var(--size-section_subtitle, var(--size-subtitle)); font-weight: var(--weight-section_subtitle, var(--weight-subtitle)); color: var(--text-body); }
.section .eyebrow { color: var(--text-eyebrow); }

/* ---- Bloque "Separador" — una o dos líneas paralelas; color/espesor/
   separación son inline por instancia (ver populateSeparadorBlock en
   site-settings.js), acá solo el ancho/redondez comunes a todas. La línea
   (.separador-box) puede ser full-bleed ("Completo"), pero el texto/ícono
   (.separador-content) SIEMPRE se alinea contra el ancho de contenido
   estándar del sitio (var(--max-w)) — igual que cualquier botón — sin
   importar cuán ancha sea la línea de abajo. ---- */
/* z-index: con margen negativo (ver populateSeparadorBlock) la sección se
   superpone al módulo vecino — esto garantiza que la línea/texto/ícono
   queden siempre visibles por encima, nunca tapados. */
.section.separador { position: relative; z-index: 2; }
.separador-box { box-sizing: border-box; position: relative; }
.separador-line { width: 100%; }
.separador-content {
  /* Mismo modelo de caja que ".section > *" (ver arriba): insets de 20px a
     cada lado + max-width + auto-centrado, en vez de left:50%/width:100%/
     padding propio — ese padding sumaba 20px extra de indentación contra el
     título/eyebrow de cualquier otro módulo, que solo tienen el padding de
     ".section" (nunca uno propio adicional). */
  position: absolute; top: 50%;
  left: 20px; right: 20px;
  max-width: var(--max-w); box-sizing: border-box;
  margin-left: auto; margin-right: auto;
  transform: translateY(-50%);
  display: flex; align-items: center; pointer-events: none;
}
.separador-text-wrap { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; pointer-events: auto; }
.separador-text { font-size: var(--size-separador_text, var(--size-body)); color: var(--text-body); }
.clave-gate-text { font-size: var(--size-clave_gate_text, var(--size-body)); font-weight: var(--weight-clave_gate_text, var(--weight-body)); }
.clave-code-input {
  border: none;
  border-bottom: 2px solid var(--gray-300);
  border-radius: 0;
  background: transparent;
  text-align: center;
  font-size: 1.4rem;
  letter-spacing: .15em;
  padding: 10px 4px;
  transition: border-color .2s;
}
.clave-code-input:focus { outline: none; border-bottom-color: var(--black); }
.clave-submit-btn {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border: none;
  background: var(--black);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 8px auto 0;
  cursor: pointer;
  transition: background .2s, transform .2s;
}
.clave-submit-btn:hover { background: var(--green-dark); transform: scale(1.05); }
.separador-icon { width: 20px; height: 20px; object-fit: contain; }
.separador-icon-svg { width: 20px; height: 20px; }
.separador-icon-svg svg { width: 100%; height: 100%; }

/* ---- Bloque "Texto libre" — contenido armado con el editor enriquecido del
   admin (ver sanitize_rich_text_html, includes/site-data.php). ---- */
.page-text-block-box { box-sizing: border-box; }
/* Contenedor de la forma (mismo sistema que .cta-media-shape/.cuadro-media-
   shape): Rectángulo (default) mantiene el 45% de ancho en escritorio + alto
   libre de siempre; Cuadrado/Círculo/Triángulo fuerzan lados iguales según
   --text-block-media-size ("Tamaño"), reemplazando el 45%. El borde opcional
   es background-color + padding (recorte replicado en la imagen/video de
   adentro = anillo de borde, ver CTA). El video de YouTube/Vimeo queda
   afuera de este sistema, igual que en CTA/Cuadros. */
.page-text-block-media-shape {
  /* isolation:isolate = frontera de mezcla del filtro de color — ver detalle
     en .cuadro-media-shape (mismo criterio en los 6 wrappers de forma). */
  display: block; position: relative; isolation: isolate; box-sizing: border-box; overflow: hidden; width: 100%;
  border-radius: var(--text-block-media-radius, 12px);
  background-color: var(--text-block-media-border-color, transparent);
  padding: var(--text-block-media-border-width, 0);
}
.page-text-block-media-shape .page-text-block-image,
.page-text-block-media-shape .page-text-block-video {
  display: block; width: 100%; height: 100%; object-fit: cover;
}
.page-text-block-video-embed { width: 100%; height: auto; border-radius: var(--text-block-media-radius, 12px); object-fit: cover; aspect-ratio: 16 / 9; border: none; }
.page-text-block-box[data-media-shape="rectangle"] .page-text-block-media-shape { height: var(--text-block-media-height, auto); }
.page-text-block-box:not([data-media-shape="rectangle"]) .page-text-block-media-shape {
  width: var(--text-block-media-size, 220px);
  max-width: min(var(--text-block-media-size, 220px), 100%);
  aspect-ratio: 1 / 1;
  margin: 0 auto;
}
.page-text-block-box[data-media-shape="triangle-up"] .page-text-block-media-shape,
.page-text-block-box[data-media-shape="triangle-down"] .page-text-block-media-shape { aspect-ratio: 1 / 0.866; }
.page-text-block-box[data-media-shape="circle"] .page-text-block-media-shape,
.page-text-block-box[data-media-shape="circle"] .page-text-block-media-shape .page-text-block-image,
.page-text-block-box[data-media-shape="circle"] .page-text-block-media-shape .page-text-block-video {
  border-radius: 50%; clip-path: circle(50% at 50% 50%);
}
.page-text-block-box[data-media-shape="triangle-up"] .page-text-block-media-shape,
.page-text-block-box[data-media-shape="triangle-up"] .page-text-block-media-shape .page-text-block-image,
.page-text-block-box[data-media-shape="triangle-up"] .page-text-block-media-shape .page-text-block-video {
  border-radius: 0; clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
.page-text-block-box[data-media-shape="triangle-down"] .page-text-block-media-shape,
.page-text-block-box[data-media-shape="triangle-down"] .page-text-block-media-shape .page-text-block-image,
.page-text-block-box[data-media-shape="triangle-down"] .page-text-block-media-shape .page-text-block-video {
  border-radius: 0; clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
}
/* Mismo bug que .cta-media-shape con borde activo — ver ahí el detalle. */
.page-text-block-box[data-media-shape="triangle-up"] .page-text-block-media-shape .page-text-block-image,
.page-text-block-box[data-media-shape="triangle-up"] .page-text-block-media-shape .page-text-block-video,
.page-text-block-box[data-media-shape="triangle-down"] .page-text-block-media-shape .page-text-block-image,
.page-text-block-box[data-media-shape="triangle-down"] .page-text-block-media-shape .page-text-block-video {
  aspect-ratio: 1 / 0.866; height: auto;
}
.page-text-block-box.has-image { display: flex; flex-direction: column; gap: 24px; }
.page-text-block-box.has-image .page-text-block-media-shape,
.page-text-block-box.has-image .page-text-block-video-embed { order: -1; }
.page-text-block-box.has-image[data-img-pos-mobile="below"] .page-text-block-media-shape,
.page-text-block-box.has-image[data-img-pos-mobile="below"] .page-text-block-video-embed { order: 1; }
.page-text-block-inner { color: var(--text-body); font-size: var(--size-text_block_content, var(--size-body)); line-height: 1.6; }
.page-text-block-inner h3 { font-size: var(--size-text_block_h3, var(--size-h2)); font-weight: var(--weight-text_block_h3, var(--weight-h2)); color: var(--text-heading); margin: 0 0 .5em; }
.page-text-block-inner h4 { font-size: var(--size-text_block_h4, var(--size-subtitle)); font-weight: var(--weight-text_block_h4, 700); color: var(--text-heading); margin: 0 0 .5em; }
.page-text-block-inner p { margin: 0 0 1em; }
.page-text-block-inner p:last-child { margin-bottom: 0; }
.page-text-block-inner ul, .page-text-block-inner ol { margin: 0 0 1em; padding-left: 1.4em; }
.page-text-block-inner a { color: var(--green-bright); text-decoration: underline; }
@media (min-width: 641px) {
  .page-text-block-box.has-image { flex-direction: row; align-items: center; gap: 40px; }
  .page-text-block-box.has-image .page-text-block-media-shape,
  .page-text-block-box.has-image .page-text-block-video-embed { flex-shrink: 0; order: -1; }
  .page-text-block-box.has-image .page-text-block-video-embed { width: 45%; }
  .page-text-block-box[data-media-shape="rectangle"].has-image .page-text-block-media-shape { width: 45%; }
  .page-text-block-box.has-image[data-img-pos-mobile="below"] .page-text-block-media-shape,
  .page-text-block-box.has-image[data-img-pos-mobile="below"] .page-text-block-video-embed { order: -1; }
  .page-text-block-box.has-image[data-img-pos-desktop="right"] .page-text-block-media-shape,
  .page-text-block-box.has-image[data-img-pos-desktop="right"] .page-text-block-video-embed { order: 1; }
  .page-text-block-box.has-image .page-text-block-inner { flex: 1; min-width: 0; }
}

/* ---- Cards / Services ---- */
.card-grid {
  display: grid;
  /* minmax(0, 1fr), no 1fr solo: 1fr solo es minmax(auto, 1fr) — con una
     imagen alta, el ancho "preferido" (min-content) de la tarjeta puede
     superar el ancho real de su columna, y el grid la agranda en vez de
     respetar el reparto en partes iguales ("grid blowout"). El 0 en el
     mínimo le saca ese piso. */
  grid-template-columns: minmax(0, 1fr);
  gap: 18px;
}
.card {
  display: flex;
  flex-direction: column;
  background: var(--cuadro-card-bg, var(--white));
  border: var(--cuadro-card-border-width, 1px) solid var(--cuadro-card-border-color, var(--gray-300));
  border-radius: var(--cuadro-card-radius, 18px);
  padding: 28px;
  transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.card:hover {
  border-color: var(--green);
  transform: translateY(-3px);
  box-shadow: 0 16px 32px rgba(11, 15, 13, .08);
}
.card-icon {
  width: 42px; height: 42px;
  border-radius: 8px;
  background: linear-gradient(135deg, var(--green-bright), var(--green-dark));
  margin-bottom: 16px;
}
.card h3 { font-size: var(--size-card_title, var(--size-h2)); font-weight: var(--weight-card_title, var(--weight-h2)); line-height: 1.3; margin-bottom: 10px; color: var(--text-heading); }
.card p { color: var(--text-body); font-size: var(--size-card_description, var(--size-body)); font-weight: var(--weight-card_description, var(--weight-body)); line-height: 1.65; margin-bottom: 18px; }
.card-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--green-dark);
  font-weight: 600;
  font-size: .9rem;
  margin-top: auto;
  transition: gap .2s ease;
}
.card .card-link { font-size: var(--size-cuadro_btn_text, .9rem); }
.card-link:hover { gap: 10px; }

.cuadro-title-row { display: flex; align-items: center; gap: 10px; order: -3; margin-bottom: 10px; }
.cuadro-title-row h3 { margin-bottom: 0; }
.cuadro-icon, .cuadro-icon-svg { width: var(--cuadro-icon-size, 28px); height: var(--cuadro-icon-size, 28px); object-fit: contain; order: -1; flex-shrink: 0; color: var(--cuadro-icon-color, var(--green-dark)); }
.cuadro-icon-svg svg { width: 100%; height: 100%; stroke-width: var(--cuadro-icon-weight, 2); }
.cuadro-title-row.icon-after .cuadro-icon,
.cuadro-title-row.icon-after .cuadro-icon-svg { order: 1; }

/* Contenedor de la forma (mismo sistema que .cta-media-shape en el CTA):
   Rectángulo (default) mantiene la franja 16:11 + sangrado de siempre;
   Cuadrado/Círculo/Triángulo fuerzan lados iguales según --cuadro-image-size
   ("Tamaño"). El borde opcional es background-color + padding acá (el
   recorte — clip-path/border-radius — se aplica tanto al wrapper como a la
   imagen/video de adentro, dando 2 formas concéntricas = anillo de borde).
   overflow:hidden es lo que recorta la imagen a las esquinas redondeadas
   (border-radius solo no alcanza para recortar hijos). El video de YouTube/
   Vimeo (.cuadro-video-embed) queda AFUERA de este sistema — nunca toma
   forma ni sangra, igual que en CTA. */
.cuadro-media-shape {
  display: block;
  position: relative;
  /* Frontera de mezcla: el mix-blend-mode del filtro de color (adentro, ver
     .media-filter-overlay) solo puede "ver" lo que hay DENTRO de esta caja
     (la imagen/video) para mezclarse — sin esto, en teoría podría filtrar
     hacia capas de pintura de más afuera (fondo de la tarjeta, etc.),
     aunque el recorte por padding ya evitaba el caso visible del anillo del
     borde. Cinturón y tirantes: la garantía real de "solo la imagen" la da
     esto, no el recorte. */
  isolation: isolate;
  box-sizing: border-box;
  overflow: hidden;
  border-radius: var(--cuadro-image-radius, 14px);
  background-color: var(--cuadro-image-border-color, transparent);
  padding: var(--cuadro-image-border-width, 0);
}
.cuadro-media-shape .cuadro-image,
.cuadro-media-shape .cuadro-video {
  display: block; width: 100%; height: 100%; object-fit: cover; border: 0;
}
section.services[data-media-shape="rectangle"] .cuadro-media-shape {
  /* "Ancho hasta el borde": con width fijo (no auto), un margin negativo NO
     agranda la caja — solo la corre para un lado. Por eso el crecimiento va
     directo en el width (2 * 28px del padding de la tarjeta, según
     --cuadro-image-bleed, fracción 0-1 desde applyServiceGroups en
     site-settings.js) y el margin-left negativo solo repone el desplazamiento
     para que crezca pareja hacia los dos lados, no hacia uno solo. */
  width: calc(100% + 56px * var(--cuadro-image-bleed, 0));
  max-width: calc(100% + 56px * var(--cuadro-image-bleed, 0));
  margin-left: calc(-28px * var(--cuadro-image-bleed, 0));
  aspect-ratio: 16 / 11;
  height: var(--cuadro-image-height, auto);
}
section.services:not([data-media-shape="rectangle"]) .cuadro-media-shape {
  /* Mismo "Ancho hasta el borde" aplicado al tamaño en vez del ancho (acá no
     hay franja completa que crecer) — crece parejo hacia los 2 lados con el
     sangrado. El tope real no es 100% (eso es el ancho de CONTENIDO de la
     tarjeta, sin el padding de 28px por lado) sino 100% + 56px — recién ahí
     toca el borde exterior real de la tarjeta, mismo margen que usa
     Rectángulo para su propio sangrado.
     Centrado con left:50%+translateX(-50%) en vez de margin:auto a propósito:
     margin:auto NO centra de forma pareja apenas el ancho supera al de la
     tarjeta (los navegadores resuelven el margen automático como 0 en vez de
     negativo ahí), y quedaba pegada a la izquierda en cuanto crecía más de
     la cuenta. left/transform sí reparte el sobrante siempre parejo a los 2
     lados, sea cual sea el ancho. */
  /* "Tamaño" manda siempre (incluso en bleed 1/0%) — el sangrado solo agrega
     hasta 56px por encima de ese tamaño, topeado a 100%+56px (el borde real
     de la tarjeta). A propósito NO garantiza tocar el borde en 0% si el
     Tamaño configurado es chico (decisión explícita: "Tamaño" siempre debe
     tener efecto visible, incluso en el extremo 0%, aunque eso signifique
     resignar la garantía absoluta de tocar el borde para tamaños chicos). */
  width: calc(var(--cuadro-image-size, 220px) + 56px * var(--cuadro-image-bleed, 0));
  max-width: min(calc(var(--cuadro-image-size, 220px) + 56px * var(--cuadro-image-bleed, 0)), calc(100% + 56px));
  aspect-ratio: 1 / 1;
  left: 50%;
  transform: translateX(-50%);
}
/* Equilátero real (ver misma fórmula en CTA, css/styles.css original):
   alto = ancho × √3/2 para que los 2 lados inclinados midan lo mismo que la
   base. */
section.services[data-media-shape="triangle-up"] .cuadro-media-shape,
section.services[data-media-shape="triangle-down"] .cuadro-media-shape {
  aspect-ratio: 1 / 0.866;
}
section.services[data-media-shape="circle"] .cuadro-media-shape,
section.services[data-media-shape="circle"] .cuadro-media-shape .cuadro-image,
section.services[data-media-shape="circle"] .cuadro-media-shape .cuadro-video {
  border-radius: 50%; clip-path: circle(50% at 50% 50%);
}
section.services[data-media-shape="triangle-up"] .cuadro-media-shape,
section.services[data-media-shape="triangle-up"] .cuadro-media-shape .cuadro-image,
section.services[data-media-shape="triangle-up"] .cuadro-media-shape .cuadro-video {
  border-radius: 0; clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
section.services[data-media-shape="triangle-down"] .cuadro-media-shape,
section.services[data-media-shape="triangle-down"] .cuadro-media-shape .cuadro-image,
section.services[data-media-shape="triangle-down"] .cuadro-media-shape .cuadro-video {
  border-radius: 0; clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
}
/* Mismo bug que .cta-media-shape con borde activo — ver ahí el detalle. */
section.services[data-media-shape="triangle-up"] .cuadro-media-shape .cuadro-image,
section.services[data-media-shape="triangle-up"] .cuadro-media-shape .cuadro-video,
section.services[data-media-shape="triangle-down"] .cuadro-media-shape .cuadro-image,
section.services[data-media-shape="triangle-down"] .cuadro-media-shape .cuadro-video {
  aspect-ratio: 1 / 0.866; height: auto;
}
.card:not(.image-below) .cuadro-media-shape {
  /* Antes del título (order -3 en .cuadro-title-row), así el borde de
     arriba es el borde real de la tarjeta y el sangrado tiene sentido —
     antes iba en -2 (después del título) y nunca llegaba a ningún borde. */
  order: -4;
  margin-bottom: var(--cuadro-image-margin, 18px);
  /* Mismo sangrado vertical que el horizontal (cancela los 28px de padding
     de la tarjeta) — antes esto solo aplicaba a Rectángulo, así que las
     otras formas nunca llegaban a tocar el borde de arriba/abajo aunque el
     de los costados sí. */
  margin-top: calc(-28px * var(--cuadro-image-bleed, 0));
}
.card.image-below .cuadro-media-shape {
  order: 2;
  margin-top: var(--cuadro-image-margin, 18px);
  margin-bottom: calc(-28px * var(--cuadro-image-bleed, 0));
}
/* La redondez de esquina que imita el radio real de la tarjeta al sangrar
   solo tiene sentido en Rectángulo (Cuadrado/Círculo/Triángulo ya resuelven
   su propia esquina con su border-radius/clip-path de forma). */
section.services[data-media-shape="rectangle"] .card:not(.image-below) .cuadro-media-shape {
  /* Al sangrar, la esquina que toca el marco de la tarjeta adopta la
     redondez REAL de la tarjeta (--cuadro-card-radius, configurable en
     "Color de la tarjeta") en vez de la propia, para no asomar cuadrada por
     fuera del borde — interpola entre ambas según el mismo --cuadro-image-bleed. */
  border-top-left-radius: calc(var(--cuadro-image-radius, 14px) + (var(--cuadro-card-radius, 18px) - var(--cuadro-image-radius, 14px)) * var(--cuadro-image-bleed, 0));
  border-top-right-radius: calc(var(--cuadro-image-radius, 14px) + (var(--cuadro-card-radius, 18px) - var(--cuadro-image-radius, 14px)) * var(--cuadro-image-bleed, 0));
}
section.services[data-media-shape="rectangle"] .card.image-below .cuadro-media-shape {
  border-bottom-left-radius: calc(var(--cuadro-image-radius, 14px) + (var(--cuadro-card-radius, 18px) - var(--cuadro-image-radius, 14px)) * var(--cuadro-image-bleed, 0));
  border-bottom-right-radius: calc(var(--cuadro-image-radius, 14px) + (var(--cuadro-card-radius, 18px) - var(--cuadro-image-radius, 14px)) * var(--cuadro-image-bleed, 0));
}
/* YouTube/Vimeo: queda afuera del sistema de formas, mantiene el look de
   siempre (franja 16:11, redondez, separación) sin sangrado ni forma. */
.cuadro-video-embed {
  display: block; width: 100%; max-width: 100%; aspect-ratio: 16 / 11;
  border-radius: var(--cuadro-image-radius, 14px); object-fit: cover; border: 0;
}
.card:not(.image-below) .cuadro-video-embed { order: -4; margin-bottom: var(--cuadro-image-margin, 18px); }
.card.image-below .cuadro-video-embed { order: 2; margin-top: var(--cuadro-image-margin, 18px); }

/* ---- Cuadros: modo "Orden" opcional (fila horizontal scrolleable en vez de
   grilla) — mismo tamaño de tarjeta que la grilla normal, sin campos propios
   de ancho/separación (ver .card-grid.is-cards-carousel en populateService
   GroupElement, js/site-settings.js). Aplica en todas las pantallas. ---- */
.card-grid.is-cards-carousel {
  display: flex;
  grid-template-columns: none;
  gap: 18px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 8px;
}
.card-grid.is-cards-carousel::-webkit-scrollbar { display: none; }
.card-grid.is-cards-carousel.is-motion { scroll-behavior: auto; }
.card-grid.is-cards-carousel .card {
  flex: 0 0 auto;
  width: min(85vw, 340px);
  scroll-snap-align: start;
}
.card-grid-wrap { position: relative; }
.card-carousel-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--gray-300);
  background: var(--white);
  color: var(--green-dark);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 8px 20px rgba(11, 15, 13, .12);
  transition: border-color .2s ease, transform .2s ease;
}
.card-carousel-arrow:hover { border-color: var(--green); transform: translateY(-50%) scale(1.06); }
.card-carousel-arrow--prev { left: -20px; }
.card-carousel-arrow--next { right: -20px; }
@media (max-width: 640px) {
  .card-carousel-arrow--prev { left: -8px; }
  .card-carousel-arrow--next { right: -8px; }
}
.card-carousel-dots {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 8px;
  margin-top: 18px;
}
.card-carousel-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--gray-300);
  border: 0;
  padding: 0;
  cursor: default;
  transition: background .2s ease, transform .2s ease;
}
.card-carousel-dot.is-active {
  background: var(--green);
  transform: scale(1.25);
}

/* ---- Carrusel simple (horizontal scroll on mobile) ---- */
/* Flechas a los costados + puntitos abajo — mismas clases .card-carousel-*
   que ya usa Cuadros en su modo "Orden" carrusel (ver setupCardCarouselNav
   en site-settings.js), reutilizadas tal cual acá. */
.carrusel-simple-wrap { position: relative; }
.carrusel-simple-scroll {
  display: flex;
  gap: var(--carrusel-simple-gap, 14px);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}
.carrusel-simple-scroll::-webkit-scrollbar { display: none; }
.carrusel-simple-scroll.is-motion { scroll-behavior: auto; }
/* "Pantalla completa": la tarjeta ignora el ancho en px y ocupa el ancho
   real del navegador (100vw) — hace falta ADEMÁS sacar a la fila de
   tarjetas de su contenedor centrado/acotado (.section > * la deja en
   max-width:var(--max-w) normalmente), si no la tarjeta se ve entera igual
   pero encerrada en ese ancho angosto, no llega a los bordes de la pantalla
   de verdad. */
.carrusel-simple-scroll.is-full-width {
  max-width: 100vw;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}
.carrusel-simple-scroll.is-full-width .carrusel-simple-card { width: 100vw; }
/* "Ancho de caja": a diferencia de "Pantalla completa", NO rompe el
   contenedor centrado/acotado (.section > * sigue en max-width:var(--max-w))
   — la tarjeta simplemente pasa a ocupar el 100% de ese ancho normal. */
.carrusel-simple-scroll.is-box-width .carrusel-simple-card { width: 100%; }
.carrusel-simple-card {
  position: relative;
  flex: 0 0 auto;
  width: var(--carrusel-simple-card-width, 280px);
  scroll-snap-align: start;
  height: var(--carrusel-simple-card-height, 140px);
  border-radius: var(--carrusel-simple-card-radius, var(--radius));
  background: linear-gradient(160deg, var(--black-soft), var(--black));
  display: flex;
  flex-direction: column;
  align-items: var(--carrusel-simple-text-align, flex-start);
  justify-content: var(--carrusel-simple-text-justify, flex-end);
  gap: 10px;
  padding: 16px;
  overflow: hidden;
  text-decoration: none;
  cursor: default;
}
.carrusel-simple-card[href] { cursor: pointer; }
.carrusel-simple-content { position: relative; display: flex; align-items: center; gap: 10px; }
.carrusel-simple-card span.carrusel-simple-name { position: relative; order: 0; color: var(--white); font-weight: var(--carrusel-simple-text-weight, 600); font-size: var(--size-carrusel_item_name, 1.05rem); }
.carrusel-simple-action-btn { position: relative; font-size: var(--size-carrusel_btn_text, var(--size-btn)); font-weight: var(--weight-carrusel_btn_text, var(--weight-btn)); }
.carrusel-simple-card .carrusel-simple-icon { position: relative; width: var(--carrusel-simple-icon-size, 26px); height: var(--carrusel-simple-icon-size, 26px); object-fit: contain; order: -1; flex-shrink: 0; }
.carrusel-simple-card .carrusel-simple-icon-svg { position: relative; width: var(--carrusel-simple-icon-size, 26px); height: var(--carrusel-simple-icon-size, 26px); color: var(--carrusel-simple-icon-color, var(--white)); order: -1; flex-shrink: 0; }
.carrusel-simple-card .carrusel-simple-icon-svg svg { width: 100%; height: 100%; stroke-width: var(--carrusel-simple-icon-weight, 2); }
.carrusel-simple-content.icon-after .carrusel-simple-icon,
.carrusel-simple-content.icon-after .carrusel-simple-icon-svg { order: 1; }
/* isolation:isolate = frontera de mezcla del filtro de color — sin esto acá
   específicamente, el mix-blend-mode podría llegar a teñir el degradado
   propio de la tarjeta (card_bg_color_1/2) o el texto que queda encima, no
   solo la imagen/video de adentro. Ver detalle completo en .cuadro-media-
   shape (mismo criterio en los 6 wrappers de forma del sitio). */
.carrusel-simple-media { position: absolute; inset: 0; isolation: isolate; }
.carrusel-simple-media video, .carrusel-simple-media iframe, .carrusel-simple-media img { width: 100%; height: 100%; object-fit: cover; border: 0; display: block; }
/* Forma (Cuadrado/Círculo/Triángulo): la imagen/video deja de ser fondo a
   sangre completa y pasa a ser una insignia chica centrada — mismo sistema
   que .cta-media-shape (el borde es background-color + padding, recorte
   replicado en el hijo = anillo de borde). --carrusel-simple-media-size ya
   viene capado en JS (populateCarruselSimpleGroup) al 100% de la MENOR de
   las 2 dimensiones de la tarjeta (llega a tocar ese par de bordes) —
   aspect-ratio + max-width/max-height acá no alcanzan solos porque cada uno
   resuelve su propio eje por separado y pueden terminar dando un rectángulo
   en vez de un cuadrado. */
section.carrusel_simple_items:not([data-media-shape="rectangle"]) .carrusel-simple-media {
  inset: auto; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: var(--carrusel-simple-media-size, 80px);
  aspect-ratio: 1 / 1;
  box-sizing: border-box;
  overflow: hidden;
  border-radius: var(--carrusel-simple-media-radius, 12px);
  background-color: var(--carrusel-simple-media-border-color, transparent);
  padding: var(--carrusel-simple-media-border-width, 0);
}
section.carrusel_simple_items[data-media-shape="triangle-up"] .carrusel-simple-media,
section.carrusel_simple_items[data-media-shape="triangle-down"] .carrusel-simple-media { aspect-ratio: 1 / 0.866; }
section.carrusel_simple_items[data-media-shape="circle"] .carrusel-simple-media,
section.carrusel_simple_items[data-media-shape="circle"] .carrusel-simple-media video,
section.carrusel_simple_items[data-media-shape="circle"] .carrusel-simple-media img {
  border-radius: 50%; clip-path: circle(50% at 50% 50%);
}
section.carrusel_simple_items[data-media-shape="triangle-up"] .carrusel-simple-media,
section.carrusel_simple_items[data-media-shape="triangle-up"] .carrusel-simple-media video,
section.carrusel_simple_items[data-media-shape="triangle-up"] .carrusel-simple-media img {
  border-radius: 0; clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
section.carrusel_simple_items[data-media-shape="triangle-down"] .carrusel-simple-media,
section.carrusel_simple_items[data-media-shape="triangle-down"] .carrusel-simple-media video,
section.carrusel_simple_items[data-media-shape="triangle-down"] .carrusel-simple-media img {
  border-radius: 0; clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
}
/* Mismo bug que .cta-media-shape con borde activo — ver ahí el detalle. */
section.carrusel_simple_items[data-media-shape="triangle-up"] .carrusel-simple-media video,
section.carrusel_simple_items[data-media-shape="triangle-up"] .carrusel-simple-media img,
section.carrusel_simple_items[data-media-shape="triangle-down"] .carrusel-simple-media video,
section.carrusel_simple_items[data-media-shape="triangle-down"] .carrusel-simple-media img {
  aspect-ratio: 1 / 0.866; height: auto;
}

/* ---- Insights ---- */
.insight-grid {
  display: grid;
  /* minmax(0, 1fr), no 1fr solo — mismo motivo que .card-grid: sin el 0 de
     mínimo, una imagen alta puede agrandar la tarjeta en vez de repartir el
     ancho en partes iguales ("grid blowout"). */
  grid-template-columns: minmax(0, 1fr);
  gap: 20px;
}
/* Rectángulo (default) = alto configurable (antes fijo 160px) con la
   redondez de siempre. Cuadrado/Círculo/Triángulo fuerzan lados iguales
   según --insight-media-height ("Tamaño") — mismo sistema que .cta-media-
   shape. El degradado es solo placeholder para cuando no hay imagen — JS
   (populateInsightGroup) lo saca (background-image:none) apenas hay una
   imagen real, si no el degradado se ve SIEMPRE encima del color de borde
   (mismo problema que .cta-banner, ver css/styles.css). */
.insight-thumb {
  /* isolation:isolate = frontera de mezcla del filtro de color — ver detalle
     en .cuadro-media-shape (mismo criterio en los 6 wrappers de forma). */
  position: relative;
  isolation: isolate;
  height: var(--insight-media-height, 160px);
  border-radius: var(--insight-media-radius, var(--radius));
  background: linear-gradient(135deg, #e8f5ec, #cdeeda);
  background-color: var(--insight-media-border-color, transparent);
  margin-bottom: 14px;
  box-sizing: border-box;
  overflow: hidden;
  padding: var(--insight-media-border-width, 0);
}
.insight-thumb-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.insight-grid:not([data-media-shape="rectangle"]) .insight-thumb {
  width: var(--insight-media-height, 220px);
  max-width: min(var(--insight-media-height, 220px), 100%);
  aspect-ratio: 1 / 1;
  height: auto;
  margin-left: auto; margin-right: auto;
}
.insight-grid[data-media-shape="triangle-up"] .insight-thumb,
.insight-grid[data-media-shape="triangle-down"] .insight-thumb { aspect-ratio: 1 / 0.866; }
.insight-grid[data-media-shape="circle"] .insight-thumb,
.insight-grid[data-media-shape="circle"] .insight-thumb-img {
  border-radius: 50%; clip-path: circle(50% at 50% 50%);
}
.insight-grid[data-media-shape="triangle-up"] .insight-thumb,
.insight-grid[data-media-shape="triangle-up"] .insight-thumb-img {
  border-radius: 0; clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
.insight-grid[data-media-shape="triangle-down"] .insight-thumb,
.insight-grid[data-media-shape="triangle-down"] .insight-thumb-img {
  border-radius: 0; clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
}
/* Mismo bug que .cta-media-shape con borde activo — ver ahí el detalle. */
.insight-grid[data-media-shape="triangle-up"] .insight-thumb-img,
.insight-grid[data-media-shape="triangle-down"] .insight-thumb-img {
  aspect-ratio: 1 / 0.866; height: auto;
}
.insight-tag {
  color: var(--green-dark);
  font-weight: 700;
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .6px;
  margin-bottom: 6px;
}
.insight-card h3 { font-size: var(--size-insight_title, var(--size-h2)); font-weight: var(--weight-insight_title, var(--weight-h2)); line-height: 1.4; color: var(--text-heading); }
.insight-card { display: flex; flex-direction: column; }
.insight-card .card-link { margin-top: 12px; font-size: var(--size-insight_btn_text, var(--size-btn)); font-weight: var(--weight-insight_btn_text, var(--weight-btn)); }

/* ---- Acordeón ---- */
/* Tarjetas separadas (no lista con líneas): cada pregunta es su propia
   tarjeta con sombra suave, más marcada mientras está abierta. */
.accordion-list { max-width: 760px; margin: 0 auto; display: flex; flex-direction: column; gap: 14px; }
.accordion-item {
  background: var(--white);
  border-radius: 14px;
  box-shadow: 0 2px 10px rgba(11, 15, 13, .07);
  transition: box-shadow .25s ease;
}
.accordion-item.is-open { box-shadow: 0 10px 28px rgba(11, 15, 13, .12); }
.accordion-question {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 22px;
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
  color: var(--text-heading);
  font-size: var(--size-accordion_question, var(--size-body));
  font-weight: 600;
}
/* Ícono opcional de la pregunta (patrón "c.it") — se oculta solo si no se
   eligió ninguno (ver populateAccordionGroup en site-settings.js). Tamaño/
   grosor/color/posición son config GLOBAL del grupo ("Íconos en el título"),
   no por pregunta — mismo patrón que Carrusel simple. */
.accordion-question-content { display: flex; align-items: center; gap: 12px; min-width: 0; }
.accordion-item-icon {
  width: var(--accordion-icon-size, 24px);
  height: var(--accordion-icon-size, 24px);
  object-fit: contain;
  flex-shrink: 0;
  order: -1;
}
.accordion-item-icon-svg {
  width: var(--accordion-icon-size, 24px);
  height: var(--accordion-icon-size, 24px);
  flex-shrink: 0;
  color: var(--accordion-icon-color, var(--green-dark));
  order: -1;
}
.accordion-item-icon-svg svg { width: 100%; height: 100%; stroke-width: var(--accordion-icon-weight, 2); }
.accordion-question-content.icon-after .accordion-item-icon,
.accordion-question-content.icon-after .accordion-item-icon-svg { order: 1; }
.accordion-question-content .accordion-question-text { order: 0; }
/* Círculo de acento con "+" que gira 45° y se convierte visualmente en "×"
   al abrir — mismo ícono, sin tener que cambiarlo por JS. */
.accordion-toggle-icon {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accordion-toggle-color, var(--green, #0e7a37));
  color: var(--white);
  transition: transform .3s ease;
}
.accordion-item.is-open .accordion-toggle-icon { transform: rotate(45deg); }
/* Alto animado preciso (grid-template-rows 0fr → 1fr) en vez de un max-
   height fijo: antes saltaba porque animaba contra un tope arbitrario de
   600px en vez del alto real de cada respuesta (y una respuesta más larga
   que eso quedaba directamente cortada). El texto además aparece con un
   fade corto, retrasado un poco para que no se note apretado contra el alto
   todavía creciendo. */
.accordion-answer {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .35s ease;
}
.accordion-item.is-open .accordion-answer { grid-template-rows: 1fr; }
.accordion-answer-inner { overflow: hidden; }
.accordion-answer p {
  padding: 0 22px 22px;
  color: var(--text-body);
  font-size: var(--size-accordion_answer, var(--size-body));
  line-height: 1.65;
  opacity: 0;
  transition: opacity .2s ease;
}
.accordion-item.is-open .accordion-answer p { opacity: 1; transition-delay: .1s; }
/* Introducción opcional (ver render_accordion_item, admin-render.php): mismo
   estilo de párrafo que la Respuesta (comparte .accordion-answer p de
   arriba), solo con su propio tamaño reasignable (T) y menos aire abajo,
   porque ahí sigue el divisor sutil en vez del borde de la tarjeta. Oculta
   por completo (junto con el divisor) cuando no tiene texto cargado — ver
   populateAccordionGroup en site-settings.js. */
.accordion-introduction {
  padding-bottom: 14px;
  font-size: var(--size-accordion_introduction, var(--size-body));
  font-weight: var(--weight-accordion_introduction, var(--weight-body));
}
.accordion-intro-divider {
  margin: 0 22px 22px;
  border: none;
  border-top: 1px solid var(--gray-200);
  opacity: .6;
}
/* "Modo oscuro": paleta fija (negro + grises), pisa cualquier color propio
   del grupo/ítem — ver populateAccordionGroup en site-settings.js, que deja
   de fijar esos colores inline a propósito cuando está activo. El color del
   botón (--accordion-toggle-color) queda afuera, se sigue viendo el acento. */
.accordion-section.is-dark-mode { background: var(--black); }
.accordion-section.is-dark-mode .section-head .eyebrow,
.accordion-section.is-dark-mode .section-head .section-sub { color: var(--gray-300); }
.accordion-section.is-dark-mode .section-head h2 { color: var(--white); }
.accordion-section.is-dark-mode .accordion-item {
  background: var(--black-soft);
  border: 1px solid rgba(255, 255, 255, .07);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .4);
}
.accordion-section.is-dark-mode .accordion-item.is-open {
  border-color: rgba(255, 255, 255, .14);
  box-shadow: 0 10px 28px rgba(0, 0, 0, .55);
}
.accordion-section.is-dark-mode .accordion-question-text { color: var(--white); }
.accordion-section.is-dark-mode .accordion-answer p { color: var(--gray-300); }
.accordion-section.is-dark-mode .accordion-intro-divider { border-top-color: rgba(255, 255, 255, .15); }

/* ---- CTA banner ---- */
.cta-banner {
  background: linear-gradient(135deg, var(--green-dark), var(--black));
  color: var(--white);
  padding: 56px 20px;
  text-align: center;
}
.cta-inner { max-width: 560px; margin: 0 auto; }
/* Contenedor de la forma (cuadrado/círculo/triángulo, lados iguales): el
   ancho lo fija populateCtaBlock según "Tamaño" (con tope min(...,100%) para
   nunca desbordar en mobile), el alto lo resuelve solo aspect-ratio 1/1 a
   partir de ese ancho ya achicado — así la forma queda siempre centrada y
   proporcional. El borde opcional es background-color + padding en este
   contenedor (ver populateCtaBlock): el recorte (clip-path/border-radius) se
   aplica tanto acá como en la imagen/video de adentro, dando dos formas
   concéntricas — la de afuera hace de anillo de borde. */
.cta-media-shape {
  display: block; position: relative; width: 100%; max-width: 220px; aspect-ratio: 1 / 1;
  margin: 0 auto 24px; box-sizing: border-box; border-radius: 12px;
  /* overflow:hidden es lo que realmente recorta la imagen/video de adentro a
     las esquinas redondeadas — sin esto, border-radius solo se nota en el
     fondo (visible como aro del borde), no en la imagen misma. isolation:
     isolate = frontera de mezcla del filtro de color — ver detalle completo
     en .cuadro-media-shape (mismo criterio en los 6 wrappers de forma). */
  overflow: hidden;
  isolation: isolate;
}
.cta-media-shape .cta-media-image, .cta-media-shape .cta-media-video {
  display: block; width: 100%; height: 100%; object-fit: cover;
}
/* Rectángulo = banner ancho completo, alto libre (como fue siempre antes de
   que existieran las otras 3 formas de lados iguales) — sin forzar
   aspect-ratio, populateCtaBlock fija el alto en px según el slider, o lo
   deja "auto" (proporción natural de la imagen) si está en Automático. */
.cta-media-shape.shape-rectangle { aspect-ratio: auto; }
.cta-media-video-embed {
  display: block; width: 100%; max-width: 220px; height: auto;
  margin: 0 auto 24px; border-radius: 12px; object-fit: cover;
  aspect-ratio: 16 / 9; border: none;
}
.cta-media-shape.shape-circle { border-radius: 50%; clip-path: circle(50% at 50% 50%); }
.cta-media-shape .cta-media-image.shape-circle,
.cta-media-shape .cta-media-video.shape-circle { border-radius: 50%; clip-path: circle(50% at 50% 50%); }
/* Equilátero real (3 lados = "Tamaño"): con el clip-path centrado al 50% de
   ancho, la altura tiene que ser √3/2 del ancho (≈0.866) para que los 2
   lados inclinados midan lo mismo que la base — por eso el wrapper cambia de
   aspect-ratio acá (los otros 2 shapes son 1/1, este es más bajo). */
.cta-media-shape.shape-triangle-up,
.cta-media-shape.shape-triangle-down { aspect-ratio: 1 / 0.866; }
.cta-media-shape.shape-triangle-up,
.cta-media-shape .cta-media-image.shape-triangle-up,
.cta-media-shape .cta-media-video.shape-triangle-up {
  border-radius: 0; clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
.cta-media-shape.shape-triangle-down,
.cta-media-shape .cta-media-image.shape-triangle-down,
.cta-media-shape .cta-media-video.shape-triangle-down {
  border-radius: 0; clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
}
/* Con borde activo, la imagen/video queda en una caja MÁS CHICA que el
   wrapper (achicada por el padding del borde) — si esa caja adentro sigue en
   width:100%/height:100% (arriba), su proporción real deja de ser 1/0.866
   apenas el padding no reduce ancho y alto en la misma proporción (siempre
   que el borde tenga grosor, porque el padding resta los mismos px a un
   ancho y un alto que arrancan siendo distintos). Clip-path usa % relativo a
   CADA caja por separado, así que el triángulo de adentro queda desalineado
   del de afuera — el borde se ve grueso/rojo en la base y desaparece o se
   ve mal en los 2 lados inclinados. Forzar el mismo aspect-ratio acá
   (con height:auto en vez de 100%) mantiene ambos triángulos con la MISMA
   proporción real, así el borde queda parejo en los 3 lados.
   object-fit:cover ya recorta el contenido igual si sobra un pelo de alto. */
.cta-media-shape .cta-media-image.shape-triangle-up,
.cta-media-shape .cta-media-video.shape-triangle-up,
.cta-media-shape .cta-media-image.shape-triangle-down,
.cta-media-shape .cta-media-video.shape-triangle-down {
  aspect-ratio: 1 / 0.866; height: auto;
}
.cta-inner h2 { font-size: min(var(--size-cta_title, var(--size-h2)), 10vw); font-weight: var(--weight-cta_title, var(--weight-h2)); margin-bottom: 12px; }
.cta-inner p { font-size: var(--size-cta_subtitle, var(--size-subtitle)); font-weight: var(--weight-cta_subtitle, var(--weight-subtitle)); color: var(--text-light); margin-bottom: 24px; }
.cta-inner .btn { font-size: var(--size-cta_btn_text, var(--size-btn)); font-weight: var(--weight-cta_btn_text, var(--weight-btn)); }

/* ---- Footer (estilo minimal, tipo Apple: mucho aire, jerarquía por
   tamaño/opacidad en vez de color, divisores finos) ---- */
.site-footer {
  background: var(--footer-bg, var(--black));
  color: var(--footer-text, var(--white));
  padding: 72px 20px 28px;
}
.footer-top {
  max-width: var(--max-w);
  margin: 0 auto 48px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.footer-brand { display: flex; align-items: center; gap: 10px; }
.footer-logo-img { height: 32px; width: auto; display: block; }
.footer-tagline {
  color: color-mix(in srgb, currentColor 55%, transparent);
  font-size: var(--size-footer_description, var(--size-body));
  font-weight: var(--weight-footer_description, var(--weight-body));
  max-width: 380px;
  line-height: 1.6;
}

.footer-columns { max-width: var(--max-w); margin: 0 auto; }
.footer-col { border-top: 1px solid color-mix(in srgb, currentColor 10%, transparent); }
.footer-col-toggle {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 0;
  color: currentColor;
  font-weight: var(--weight-footer_column_title, var(--weight-small));
  font-size: var(--size-footer_column_title, var(--size-small));
  text-transform: uppercase;
  letter-spacing: .07em;
}
.footer-col-toggle::after {
  content: "+";
  font-size: 1.2rem;
  font-weight: 400;
  color: color-mix(in srgb, currentColor 45%, transparent);
}
.footer-col-toggle[aria-expanded="true"]::after { content: "–"; }
.footer-col ul {
  max-height: 0;
  overflow: hidden;
  transition: max-height .3s ease;
}
.footer-col.open ul { max-height: 300px; padding-bottom: 14px; }
.footer-col ul li a {
  display: block;
  padding: 9px 0;
  color: color-mix(in srgb, currentColor 58%, transparent);
  font-size: var(--size-footer_link, var(--size-menu));
  font-weight: var(--weight-footer_link, var(--weight-menu));
  transition: color .15s ease;
}
.footer-col ul li a:hover { color: currentColor; }

.footer-bottom {
  max-width: var(--max-w);
  margin: 56px auto 0;
  padding-top: 22px;
  border-top: 1px solid color-mix(in srgb, currentColor 10%, transparent);
  display: flex;
  flex-direction: column;
  gap: 18px;
  color: color-mix(in srgb, currentColor 40%, transparent);
  font-size: var(--size-footer_copyright, var(--size-small));
  font-weight: var(--weight-footer_copyright, var(--weight-small));
}
.footer-social { display: flex; gap: 10px; }
.footer-social a {
  width: 34px; height: 34px;
  border: 1px solid color-mix(in srgb, currentColor 14%, transparent);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: .78rem;
  color: color-mix(in srgb, currentColor 65%, transparent);
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.footer-social a:hover { background: currentColor; border-color: currentColor; color: var(--footer-bg, var(--black)); }

/* =========================================================
   Tablet / Desktop (mobile-first breakpoints)
   ========================================================= */
@media (min-width: 640px) {
  .stats-grid { grid-template-columns: repeat(4, 1fr); }
  .card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .insight-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .hero-inner.has-side-image {
    flex-direction: row;
    align-items: center;
    gap: 56px;
    text-align: left;
  }
  .hero-inner.has-side-image .hero-text { flex: 1; min-width: 0; }
  .hero-inner.has-side-image .hero-side-image.is-visible { flex: 0 0 auto; max-width: var(--hero-side-image-size-desktop, 45%); }
  .hero-inner.image-desktop-left .hero-side-image { order: -1; }
}

@media (min-width: 960px) {
  :root { --header-h: 76px; }

  .header-inner { padding: 0 40px; }
  .nav-toggle { display: none; }

  .main-nav {
    position: static;
    transform: none;
    background: transparent;
    padding: 0;
    overflow: visible;
    display: flex;
    align-items: center;
    gap: 28px;
    flex: 1;
    justify-content: flex-end;
  }

  .nav-list {
    flex-direction: row;
    align-items: center;
    gap: 4px;
  }
  .nav-item { border-bottom: none; position: relative; }
  .nav-link { padding: 10px 14px; font-size: var(--size-nav_link, var(--size-menu)); font-weight: var(--weight-nav_link, var(--weight-menu)); white-space: nowrap; }
  .nav-link:hover { color: var(--green-bright); }

  .submenu {
    position: absolute;
    top: 100%;
    left: 0;
    max-height: none;
    height: 0;
    opacity: 0;
    visibility: hidden;
    background: var(--black-soft);
    border-radius: var(--radius);
    min-width: 240px;
    padding: 8px 0;
    box-shadow: 0 12px 24px rgba(0,0,0,.35);
    transition: opacity .2s ease;
  }
  .has-submenu:hover .submenu,
  .has-submenu.open .submenu {
    height: auto;
    opacity: 1;
    visibility: visible;
  }
  .submenu ul { padding: 4px 8px; }
  .submenu a { border-left: none; padding-left: 12px; }

  .nav-cta { margin-top: 0; }
  .btn-outline-light { width: auto; }

  .hero { padding: 48px 40px; }
  .hero-inner { display: flex; flex-direction: column; }
  .hero-title { max-width: 20ch; }

  .section { padding: 80px 40px; }
  .card-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .insight-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  .footer-columns { display: grid; grid-template-columns: repeat(4, 1fr); gap: 32px; }
  .footer-col { border-top: none; }
  .footer-col-toggle { pointer-events: none; padding: 0 0 18px; }
  .footer-col-toggle::after { display: none; }
  .footer-col ul { max-height: none; overflow: visible; }
  .footer-col ul li a { padding: 7px 0; }
  .footer-bottom { flex-direction: row; justify-content: space-between; align-items: center; }
}

/* ---- Menú "Contacto": link del footer, botón flotante y modal del
   formulario. Se arman por JS (site-settings.js), este CSS es la parte
   estática de esos elementos. ---- */
.footer-contact-link {
  color: inherit;
  font-weight: 600;
  text-decoration: underline;
}

.contact-floating-btn {
  position: fixed;
  bottom: 24px;
  z-index: 999;
  font-size: var(--size-contact_floating_text, var(--size-btn));
  font-weight: var(--weight-contact_floating_text, var(--weight-btn));
  box-shadow:
    0 1px 2px rgba(0,0,0,.14),
    0 2px 4px rgba(0,0,0,.14),
    0 4px 8px rgba(0,0,0,.16);
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform .18s ease, box-shadow .18s ease;
}
.contact-floating-btn:hover {
  transform: translateY(-3px);
  box-shadow:
    0 1px 3px rgba(0,0,0,.16),
    0 3px 6px rgba(0,0,0,.16),
    0 6px 12px rgba(0,0,0,.2);
}
.contact-floating-btn:active {
  transform: translateY(-1px);
}
.contact-floating-btn--right { right: 24px; }
.contact-floating-btn--left { left: 24px; }

.contact-modal-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(11,15,13,.6);
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.contact-modal-overlay.is-open { display: flex; }
body.contact-modal-open { overflow: hidden; }

.contact-modal {
  position: relative;
  width: 100%;
  max-width: 460px;
  max-height: 90vh;
  overflow-y: auto;
  background: var(--white);
  color: var(--text-body, #4b544f);
  border-radius: 20px;
  padding: 26px 30px;
  box-shadow: 0 24px 60px rgba(0,0,0,.25);
}
.contact-modal-title {
  margin-bottom: 14px;
  padding-right: 24px;
  font-size: var(--size-modal_title, 1.17em);
  color: var(--text-heading, #0b0f0d);
}
.contact-modal-close {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: none;
  background: color-mix(in srgb, currentColor 6%, transparent);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  color: inherit;
  transition: background .15s ease;
}
.contact-modal-close:hover { background: color-mix(in srgb, currentColor 12%, transparent); }

/* Modal genérico (menú admin "Modal"): mismo criterio que .contact-modal-*
   de arriba, pero más ancho — el contenido son bloques reales (Portada,
   Cuadros, etc.), no un formulario chico. */
.generic-modal-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(11,15,13,.6);
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.generic-modal-overlay.is-open { display: flex; }
.generic-modal-overlay, .generic-modal-overlay .generic-modal {
  transition: opacity .28s ease, transform .28s ease;
}
.generic-modal-overlay.is-open { opacity: 0; }
.generic-modal-overlay.is-open.is-visible { opacity: 1; }
body.generic-modal-open { overflow: hidden; }

/* Estado inicial de la tarjeta (recién agregada la clase "is-open", todavía
   sin "is-visible") según de qué borde entra — ver initGenericModal en
   site-settings.js, que agrega "is-visible" un frame después para que esto
   SÍ se anime en vez de aparecer ya en su lugar. */
.generic-modal-overlay.is-open:not(.is-visible):not([data-open-style="bottom"]):not([data-open-style="top"]) .generic-modal { transform: scale(.96); opacity: 0; }
.generic-modal-overlay.is-open:not(.is-visible)[data-open-style="bottom"] .generic-modal { transform: translateY(40px); opacity: 0; }
.generic-modal-overlay.is-open:not(.is-visible)[data-open-style="top"] .generic-modal { transform: translateY(-40px); opacity: 0; }

.generic-modal {
  position: relative;
  width: 100%;
  /* Ancho de la ventana en web (menú admin "Modal" > gear): en pantallas
     angostas esto no tiene efecto visual — el 100% de arriba ya da un ancho
     menor que cualquier valor razonable de este slider (mín. 360px), así que
     "en móvil toma el ancho completo" sale solo, sin necesidad de un
     @media aparte. */
  max-width: var(--generic-modal-desktop-width, 900px);
  max-height: 90vh;
  overflow-y: auto;
  background: var(--generic-modal-bg, var(--white));
  color: var(--text-body, #4b544f);
  border-radius: var(--generic-modal-radius, 20px);
  box-shadow: 0 24px 60px rgba(0,0,0,.25);
}
.generic-modal-close {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: none;
  background: color-mix(in srgb, currentColor 6%, transparent);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  color: inherit;
  transition: background .15s ease;
  z-index: 1;
}
.generic-modal-close:hover { background: color-mix(in srgb, currentColor 12%, transparent); }
.generic-modal-body > * { border-radius: var(--generic-modal-radius, 20px) var(--generic-modal-radius, 20px) 0 0; }
.generic-modal-body > *:last-child { border-radius: 0 0 var(--generic-modal-radius, 20px) var(--generic-modal-radius, 20px); }
.generic-modal-empty {
  padding: 60px 30px;
  text-align: center;
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--text-heading, #0b0f0d);
}

/* "Cómo se abre" (menú admin "Modal" > gear): además de flotante/centrado
   (default de arriba), puede pegarse a un borde de la pantalla como una hoja. */
.generic-modal-overlay[data-open-style="bottom"],
.generic-modal-overlay[data-open-style="top"] {
  padding: 0;
}
.generic-modal-overlay[data-open-style="bottom"] { align-items: flex-end; }
.generic-modal-overlay[data-open-style="top"] { align-items: flex-start; }
.generic-modal-overlay[data-open-style="bottom"] .generic-modal,
.generic-modal-overlay[data-open-style="top"] .generic-modal {
  /* Mismo ancho configurable que el flotante (ver .generic-modal más arriba)
     — en pantallas angostas el width:100% ya gana solo, así que en móvil
     esto también sale "ancho completo" sin nada aparte. */
  max-width: var(--generic-modal-desktop-width, 900px);
  width: 100%;
  max-height: 85vh;
}
.generic-modal-overlay[data-open-style="bottom"] .generic-modal { border-radius: var(--generic-modal-radius, 20px) var(--generic-modal-radius, 20px) 0 0; }
.generic-modal-overlay[data-open-style="top"] .generic-modal { border-radius: 0 0 var(--generic-modal-radius, 20px) var(--generic-modal-radius, 20px); }

.contact-modal-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.contact-modal-field span {
  display: block;
  margin-bottom: 4px;
  font-size: var(--size-contact_field_label, .85rem);
  font-weight: 600;
  letter-spacing: .2px;
}
.contact-modal-field input,
.contact-modal-field textarea {
  width: 100%;
  padding: 9px 12px;
  border: 1.5px solid color-mix(in srgb, currentColor 15%, transparent);
  border-radius: 12px;
  font: inherit;
  font-size: var(--size-contact_field_default, 1rem);
  color: inherit;
  background: color-mix(in srgb, currentColor 3%, transparent);
  transition: border-color .15s ease;
}
.contact-modal-field input:focus,
.contact-modal-field textarea:focus {
  outline: none;
  border-color: var(--green, #16a34a);
}

/* ---- Campo "Teléfono" (código país fijo "+" + número editable) — mismo
   patrón que usa el admin para el número de WhatsApp, ver .phone-field-*
   en admin/css/admin.css. Acá con currentColor/color-mix como el resto del
   modal, para heredar el tema (claro/oscuro) de donde se abra. ---- */
.phone-field-split {
  display: flex;
  gap: 8px;
}
.phone-field-code {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  gap: 2px;
  padding: 9px 10px;
  border: 1.5px solid color-mix(in srgb, currentColor 15%, transparent);
  border-radius: 12px;
  background: color-mix(in srgb, currentColor 3%, transparent);
}
.phone-field-plus { opacity: .7; }
/* Selector reforzado a propósito: .contact-modal-field input (más específico
   que una sola clase) pisa el width acá si no. */
.phone-field-code input.phone-field-code-input {
  width: 2.2em;
  border: none;
  background: transparent;
  font: inherit;
  color: inherit;
  padding: 0;
}
.phone-field-code-input:focus { outline: none; }
.phone-field-split input.phone-field-number-input { flex: 1; width: auto; min-width: 0; }
.contact-modal-channels {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 2px;
}
.contact-channel-btn {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, currentColor 18%, transparent);
  background: transparent;
  color: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform .15s ease, border-color .15s ease, background .15s ease, color .15s ease;
}
.contact-channel-btn:hover { transform: translateY(-2px); }
.contact-channel-btn.is-active { border-color: currentColor; background: color-mix(in srgb, currentColor 10%, transparent); }
.contact-channel-btn--whatsapp.is-active { color: #25D366; border-color: #25D366; background: color-mix(in srgb, #25D366 12%, transparent); }
.contact-channel-btn--telegram.is-active { color: #0088cc; border-color: #0088cc; background: color-mix(in srgb, #0088cc 12%, transparent); }

.contact-modal-submit {
  margin-top: 4px;
  border: none;
  cursor: pointer;
}
.contact-modal-status {
  margin-top: 6px;
  font-size: var(--size-contact_success_message, .85rem);
}
.contact-modal-status.is-error { font-size: var(--size-contact_error_message, .85rem); }
.contact-modal-status.is-success { color: var(--green-dark, #0e7a37); }

/* Barra superior mínima cuando una Página (o /blog / una entrada de Blog)
   tiene el header real apagado — mismo bloque que antes vivía inline en
   pagina.php, movido acá para poder reutilizarlo también desde blog-index.php
   y blog-post.php sin duplicar un <style> a mano en cada uno. */
.page-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 22px 6%;
  border-bottom: 1px solid #e4e7e5;
}
.page-topbar a { font-weight: 700; color: var(--black); text-decoration: none; }

/* ---- Blog: listado (/blog) y entrada individual (/<slug>) ---- */
.blog-listing-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 32px;
}
.blog-search-form { display: flex; gap: 8px; }
.blog-search-form input {
  padding: 10px 14px;
  border-radius: 999px;
  border: 1px solid var(--gray-300);
  font-size: .92rem;
  min-width: 220px;
}
.blog-search-form button {
  padding: 10px 18px;
  border-radius: 999px;
  border: none;
  background: var(--green);
  color: #fff;
  font-weight: 700;
  cursor: pointer;
}
.blog-search-form button:hover { background: var(--green-dark); }
.blog-category-filters { display: flex; flex-wrap: wrap; gap: 8px; }
.blog-category-filter {
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid var(--gray-300);
  color: var(--text-body);
  font-size: .85rem;
  text-decoration: none;
}
.blog-category-filter:hover { border-color: var(--green); color: var(--green-dark); }
.blog-category-filter.is-active { background: var(--green); border-color: var(--green); color: #fff; }

.blog-empty-hint { color: var(--text-body); }

.blog-card-grid {
  display: grid;
  /* minmax(0, 1fr), no 1fr solo — mismo motivo que .card-grid/.insight-grid:
     sin el 0 de mínimo, una imagen destacada alta puede agrandar la tarjeta
     en vez de repartir el ancho en partes iguales ("grid blowout"). */
  grid-template-columns: minmax(0, 1fr);
  gap: 24px;
}
@media (min-width: 641px) {
  .blog-card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 981px) {
  .blog-card-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.blog-card {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--gray-300);
  border-radius: 18px;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.blog-card:hover { border-color: var(--green); transform: translateY(-3px); box-shadow: 0 16px 32px rgba(11, 15, 13, .08); }
.blog-card-media { aspect-ratio: 16/10; background: var(--gray-100); overflow: hidden; }
.blog-card-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.blog-card-body { padding: 20px; display: flex; flex-direction: column; gap: 8px; }
.blog-card-category {
  align-self: flex-start;
  padding: 3px 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--green) 14%, transparent);
  color: var(--green-dark);
  font-size: .72rem;
  font-weight: 700;
  text-decoration: none;
}
.blog-card-body h3 { font-size: var(--size-blog_card_title, var(--size-h2)); line-height: 1.35; color: var(--text-heading); }
.blog-card-body p { font-size: var(--size-blog_post_excerpt, var(--size-body)); color: var(--text-body); line-height: 1.5; }
.blog-card-date { font-size: .78rem; color: var(--gray-500, #9aa39e); margin-top: auto; }

.blog-pagination { display: flex; justify-content: center; gap: 8px; margin-top: 40px; }
.blog-pagination-link {
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--gray-300);
  color: var(--text-body);
  text-decoration: none;
  font-size: .88rem;
}
.blog-pagination-link:hover { border-color: var(--green); }
.blog-pagination-link.is-active { background: var(--green); border-color: var(--green); color: #fff; }

/* ---- Entrada individual — diseño tipo blog editorial moderno ---- */
.blog-post { background: var(--white); padding: 64px 20px 96px; }
.blog-post > * { max-width: var(--max-w); margin-left: auto; margin-right: auto; }

.blog-post-header { max-width: 720px; margin: 0 auto 40px; text-align: center; }
.blog-post-category {
  display: inline-flex;
  margin-bottom: 18px;
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: .72rem;
  font-weight: 800;
}
.blog-post-header h1 {
  font-size: var(--size-blog_post_title, var(--size-h1));
  line-height: 1.15;
  color: var(--text-heading);
  letter-spacing: -.01em;
}
.blog-post-meta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--gray-500, #8a938e);
  font-size: .88rem;
  font-weight: 600;
  margin-top: 18px;
}
.blog-post-meta span:not(:last-child)::after { content: '•'; margin-left: 8px; color: var(--gray-300); font-weight: 400; }

.blog-post-featured-image { max-width: 980px; margin: 0 auto 48px; }
.blog-post-featured-image img {
  width: 100%;
  border-radius: 22px;
  display: block;
  box-shadow: 0 24px 60px -20px rgba(11, 15, 13, .25);
}
/* Imagen destacada web/móvil (panel Blog → entrada → "Imagen destacada") —
   se renderizan las dos, CSS decide cuál mostrar según el ancho, mismo
   breakpoint (640px) que el resto del sitio. */
.blog-post-featured-image .blog-post-featured-image-mobile { display: none; }
@media (max-width: 640px) {
  .blog-post-featured-image .blog-post-featured-image-desktop { display: none; }
  .blog-post-featured-image .blog-post-featured-image-mobile { display: block; }
}

.blog-post-content {
  max-width: 700px;
  margin: 0 auto;
  color: var(--text-body);
  font-size: var(--size-blog_post_content, var(--size-body));
  line-height: 1.85;
}
.blog-post-content h3 { font-size: var(--size-blog_post_h3, var(--size-h2)); font-weight: var(--weight-blog_post_h3, var(--weight-h2)); color: var(--text-heading); margin: 1.5em 0 .6em; line-height: 1.3; }
.blog-post-content h4 { font-size: var(--size-blog_post_h4, var(--size-subtitle)); font-weight: var(--weight-blog_post_h4, 700); color: var(--text-heading); margin: 1.2em 0 .5em; }
.blog-post-content p { margin: 0 0 1.2em; }
.blog-post-content ul, .blog-post-content ol { margin: 0 0 1.2em; padding-left: 1.4em; }
.blog-post-content li { margin-bottom: .4em; }
.blog-post-content a { color: var(--green-bright); text-decoration: underline; text-underline-offset: 2px; }
.blog-post-content img { max-width: 100%; border-radius: 14px; margin: .5em 0; }
.blog-post-content blockquote {
  margin: 1.6em 0;
  padding: 4px 0 4px 22px;
  border-left: 3px solid var(--green);
  color: var(--text-heading);
  font-size: 1.08em;
  font-style: italic;
}

.blog-post-tags { max-width: 700px; margin: 32px auto 0; display: flex; flex-wrap: wrap; gap: 8px; }
.blog-post-tag {
  font-size: .8rem;
  font-weight: 600;
  color: var(--green-dark);
  background: color-mix(in srgb, var(--green) 10%, transparent);
  padding: 5px 12px;
  border-radius: 999px;
  transition: background .15s ease;
}

.blog-post-share { max-width: 700px; margin: 36px auto 0; padding-top: 28px; border-top: 1px solid var(--gray-300); display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 14px; }
.blog-post-share-label { font-size: .82rem; font-weight: 700; color: var(--text-heading); text-transform: uppercase; letter-spacing: .05em; }
.blog-post-share-buttons { display: flex; align-items: center; gap: 10px; }
.blog-post-share-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid var(--gray-300);
  color: var(--text-body);
  background: var(--white);
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease, background .15s ease, transform .15s ease;
}
.blog-post-share-btn svg { flex-shrink: 0; margin: 0 auto; }
.blog-post-share-btn:hover { transform: translateY(-2px); }
.blog-post-share-btn--whatsapp:hover { border-color: #25d366; color: #25d366; background: color-mix(in srgb, #25d366 10%, transparent); }
.blog-post-share-btn--facebook:hover { border-color: #1877f2; color: #1877f2; background: color-mix(in srgb, #1877f2 10%, transparent); }
.blog-post-share-btn--twitter:hover { border-color: var(--text-heading); color: var(--text-heading); background: var(--gray-100); }
.blog-post-share-btn--copy { width: auto; padding: 0 16px; border-radius: 999px; font-size: .82rem; font-weight: 600; }
.blog-post-share-btn--copy:hover { border-color: var(--green); color: var(--green-dark); background: color-mix(in srgb, var(--green) 8%, transparent); }

.blog-section-eyebrow { display: block; font-size: .78rem; font-weight: 800; text-transform: uppercase; letter-spacing: .08em; color: var(--text-eyebrow); margin-bottom: 8px; }

.blog-related { max-width: 980px; margin: 72px auto 0; }
.blog-related h2 { font-size: var(--size-h2); color: var(--text-heading); margin-bottom: 24px; }
.blog-related .blog-card-grid { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

.blog-comments { max-width: 700px; margin: 72px auto 0; }
.blog-comments h2 { font-size: var(--size-h2); color: var(--text-heading); margin-bottom: 24px; }
.blog-comments-list { display: flex; flex-direction: column; gap: 16px; margin-bottom: 36px; }
.blog-comment-item {
  display: flex;
  gap: 14px;
  padding: 18px 20px;
  border: 1px solid var(--gray-300);
  border-radius: 16px;
  background: var(--gray-100);
}
.blog-comment-avatar {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--green);
  color: #fff;
  font-weight: 800;
  font-size: .92rem;
}
.blog-comment-body { min-width: 0; }
.blog-comment-name { font-weight: 700; color: var(--text-heading); font-size: .92rem; }
.blog-comment-date { font-weight: 400; color: var(--gray-500, #9aa39e); font-size: .78rem; margin-left: 6px; }
.blog-comment-text { color: var(--text-body); margin-top: 6px; line-height: 1.6; }

.blog-comment-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 24px;
  border: 1px solid var(--gray-300);
  border-radius: 18px;
}
.blog-comment-form label { display: flex; flex-direction: column; gap: 6px; font-size: .88rem; color: var(--text-heading); font-weight: 600; }
.blog-comment-form input, .blog-comment-form textarea {
  padding: 11px 14px;
  border-radius: 10px;
  border: 1px solid var(--gray-300);
  font-size: .92rem;
  font-family: inherit;
  resize: vertical;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.blog-comment-form input:focus, .blog-comment-form textarea:focus {
  outline: none;
  border-color: var(--green);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--green) 18%, transparent);
}
.blog-comment-form button {
  align-self: flex-start;
  padding: 11px 24px;
  border-radius: 999px;
  border: none;
  background: var(--green);
  color: #fff;
  font-weight: 700;
  cursor: pointer;
  transition: background .15s ease;
}
.blog-comment-form button:hover { background: var(--green-dark); }
.blog-comment-form-status { font-size: .88rem; color: var(--green-dark); }
.blog-comment-form-status.is-error { color: #dc2626; }
.contact-modal-status.is-error { color: #b91c1c; }
