/*
 * eal-ui.css — capa de UI compartida por TODAS las páginas (sep 2026, feedback del equipo).
 * Aplica el branding de EAL (skill apply-eal-branding) y el look de cards del portfolio
 * (eal-web-portfolio/src/app/globals.css: card-glow, eyebrow, grad-text) a la web pública.
 * Se carga desde BaseLayout después del CSS de Webflow, así que gana por orden.
 */
:root {
  --eal-blue: #0080ff;
  --eal-violet: #a100ff;
  --eal-grad: linear-gradient(135deg, #0080ff 0%, #a100ff 100%);
  --eal-grad-text: linear-gradient(135deg, #4da3ff 0%, #c15cff 100%);
  --eal-black: #090909;
  --eal-card-bg: rgba(255, 255, 255, .04);
  --eal-card-border: rgba(255, 255, 255, .10);
  --eal-card-border-hover: rgba(0, 128, 255, .45);
  --eal-radius: 24px;
  --eal-radius-sm: 14px;
  --eal-muted: #9b9b9b;
  --eal-ease: cubic-bezier(.2, .7, .3, 1);
}

/* ── Márgenes laterales del contenedor ──────────────────────────────────────────────────
   El .container-web de Webflow usa padding lateral de 2%, que en un teléfono de 320px son 6px
   por lado: todo termina pegado al borde y en pantallas chicas se pierde información. Se le pone
   un piso en píxeles (crece con el ancho, pero nunca baja de 18px). Sep 2026, pedido de Felipe. */
.container-web {
  padding-left: max(18px, 2%);
  padding-right: max(18px, 2%);
}
@media (max-width: 480px) {
  .container-web { padding-left: 20px; padding-right: 20px; }
}

/* ── Texto con gradiente (solo la frase clave, no el título entero) ─────────────────── */
.eal-grad-text {
  background: var(--eal-grad-text);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
}

/* ── Eyebrow (el "tag" del portfolio): mono-ish, mayúsculas, tracking ancho, gradiente ── */
.eal-eyebrow {
  display: inline-block;
  font-family: Barlow, Arial, sans-serif;
  font-size: .74rem; font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase;
  background: var(--eal-grad-text);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
  margin-bottom: .9rem;
}

/* 23/9 (Felipe: "unificar todos los títulos chiquitos de las secciones"). El home mezclaba dos
   rótulos: este (Launch Programs, Success Stories, Awards) y el chip de Webflow
   (.tag-text-wrapper > .tag-text, con borde en gradiente) en What We Do, Testimonials y Pricing. Los
   tres pasan a .eal-eyebrow; el wrapper se queda porque es el que animan las interacciones IX2 de
   Webflow (blur + opacidad), y acá se le saca la pastilla.
   El centrado va por margin y no por align-self: webflow.css pasa `.tag-text-wrapper.center` a
   flex-start bajo 991px, y por eso en mobile el chip de Testimonials quedaba a la izquierda de un
   título centrado. */
.tag-text-wrapper.is-eyebrow { background: none; padding: 0; border-radius: 0; }
.tag-text-wrapper.is-eyebrow .eal-eyebrow { margin-bottom: 0; }
.tag-text-wrapper.is-eyebrow.center { align-self: center; margin-left: auto; margin-right: auto; text-align: center; }

/* ── Card (mismos valores que .card-glow del portfolio) ───────────────────────────────── */
.eal-card {
  background: var(--eal-card-bg);
  border: 1px solid var(--eal-card-border);
  border-radius: var(--eal-radius);
  transition: border-color .2s var(--eal-ease), transform .2s var(--eal-ease), box-shadow .2s var(--eal-ease);
}
.eal-card-glow:hover {
  border-color: var(--eal-card-border-hover);
  transform: translateY(-2px);
  box-shadow: 0 24px 60px -30px rgba(0, 128, 255, .35);
}
.eal-card-focus {
  border-color: transparent;
  background:
    linear-gradient(var(--eal-black), var(--eal-black)) padding-box,
    var(--eal-grad) border-box;
}

/* ── Form de contacto en el teléfono ─────────────────────────────────────────────────────
   Webflow deja .text-field y .select en 15px; Safari iOS hace zoom a la página entera al enfocar
   cualquier control de menos de 16px, y el zoom queda pegado al salir del campo. */
@media (max-width: 767px) {
  .text-field, .select, textarea.text-field { font-size: 16px; }
}

/* ── Logo del header ──────────────────────────────────────────────────────────────────────
   El <a> global de Webflow es display:flex y el <img> de adentro se estiraba al alto del ancla
   (90x38 con un logo de 1920x706: ratio 2,37 en vez de 2,72; medido en prod el 19/9). Centrado y
   con su alto natural: el header no cambia de tamaño, el logo deja de estar aplastado. */
.brand-logo img { align-self: center; height: auto; }

/* ── Reveal on scroll (lo activa /js/eal-ui.js con IntersectionObserver) ──────────────── */
.eal-reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .6s var(--eal-ease), transform .6s var(--eal-ease);
  transition-delay: calc(var(--i, 0) * 90ms);
}
.eal-reveal.is-in { opacity: 1; transform: none; }
html.no-js .eal-reveal { opacity: 1; transform: none; }

/* ── Marquee (badges de awards, logos) ────────────────────────────────────────────────── */
/* El `overflow: hidden` hace falta para el eje X (el track es más ancho que la caja), pero
   recorta en los DOS ejes: pedir hidden en X y visible en Y no se puede — el navegador convierte
   ese visible en auto. Las cards de adentro suben 2px al hover (.eal-card-glow, .cs-story), así
   que su borde superior se salía de la caja y quedaba comido justo arriba, con los otros tres
   lados intactos. Medido antes del arreglo: card y caja arrancaban en el MISMO píxel, 0px de
   aire, o sea que los 2px del hover se perdían enteros.

   El colchón (--eal-marquee-bleed) le da ese lugar. Va SOLO arriba, que es para donde se mueven
   las cards, y el margen negativo del mismo lado lo descuenta: la CAJA del marquee queda donde
   estaba (medido: mismo píxel exacto antes y después), así que no se corre nada de lo que la
   rodea. Adentro, las cards bajan los 4px del colchón — es el aire que necesitan para no quedar
   recortadas, y a ese tamaño no se nota. El margen de arriba que quiera cada página va por
   --eal-marquee-mt en vez de `margin-top`, porque esa regla es más específica y pisaría el
   descuento. */
.eal-marquee {
  --eal-marquee-bleed: 4px;
  overflow: hidden;
  padding-top: var(--eal-marquee-bleed);
  margin-top: calc(var(--eal-marquee-mt, 0px) - var(--eal-marquee-bleed));
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.eal-marquee-track {
  display: flex; align-items: center;
  gap: var(--eal-marquee-gap, 3rem);
  width: max-content;
  padding-right: var(--eal-marquee-gap, 3rem);
  animation: eal-marquee var(--eal-marquee-dur, 38s) linear infinite;
}
.eal-marquee:hover .eal-marquee-track { animation-play-state: paused; }
/* Fuera del viewport el loop se frena (la clase la pone eal-ui.js con un IntersectionObserver;
   ver el comentario largo ahí). Además de no animar de fondo lo que no se está mirando, esto es
   lo que hace que la banda se vea EMPEZAR por su primera pieza cuando se llega a la sección: el
   track queda en su transform inicial hasta ese momento. */
.eal-marquee.is-paused .eal-marquee-track { animation-play-state: paused; }
/* Congelado hasta que el JS tome el control. `eal-ui.js` va con `defer`, así que entre que el
   navegador pinta la banda y que el script alcanza a marcarla, el loop ya corrió solo: medido a
   1440, el track aparecía desplazado 211px, o sea empezando por la segunda foto. Con esta regla
   arranca quieto y el primer movimiento que se ve es el del ciclo entero desde cero.
   El gate es `html.eal-js`, que pone el propio script: sin JS la clase nunca llega, la regla no
   aplica y el marquee anima como siempre — no queda una banda muerta. */
html.eal-js .eal-marquee:not(.is-live) .eal-marquee-track { animation-play-state: paused; }
@keyframes eal-marquee { to { transform: translate3d(-50%, 0, 0); } }

/* ── Botón de sonido (mismo look que el de Webflow; el toggle lo maneja eal-ui.js) ─────── */
.sound_button .unmute_icon, .sound_button .mute_icon { transition: opacity .3s; }
.sound_button .mute_icon { opacity: 0 !important; }
.sound_button.muted .mute_icon { opacity: 1 !important; }
.sound_button.muted .unmute_icon { opacity: 0 !important; }
.sound-button.is-hidden { display: none; }
.sound-button { display: flex; align-items: center; gap: 10px; }
.sound-eq {
  height: 14px; padding: 7px 9px; box-sizing: content-box; border-radius: 999px;
  background: rgba(9, 9, 9, .55); border: 1px solid rgba(255, 255, 255, .06);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  transition: opacity .3s;
}
.sound_button.muted + .sound-eq { opacity: 0; }

/* ── Onda de marca (bundle de líneas SVG, generado por eal-ui.js en [data-eal-wave]) ──── */
.eal-wave { display: block; width: 100%; pointer-events: none; }
.eal-wave path { animation: eal-wave-float 10s ease-in-out infinite; transform-origin: center; }
@keyframes eal-wave-float {
  0%, 100% { transform: translateY(0) scaleY(1); }
  50% { transform: translateY(-6px) scaleY(1.06); }
}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   Capa "mix" (sep 2026, pedido de Felipe): estilos traídos del case study "Live Mixing System"
   del portfolio privado — kicker con punto luminoso, regla en gradiente, paneles tipo ventana
   con tres luces para enmarcar video/diagramas, chips, tabla de specs, bloque de testimonio con
   estrellas y avatar, y el fondo con glows. El gradiente de 4 paradas (cyan→azul→índigo→violeta)
   es el del portfolio; el de marca (azul→violeta) sigue siendo el default en todo lo demás.
   ═══════════════════════════════════════════════════════════════════════════════════════ */
:root {
  --eal-cyan: #19c6ff;
  --eal-indigo: #5424ec;
  --eal-grad-4: linear-gradient(100deg, #19c6ff 0%, #0080ff 40%, #5424ec 72%, #a100ff 100%);
  --eal-panel: #0a0d18;
  --eal-panel-2: #0d1120;
  --eal-ink-2: #c4cde0;
  --eal-dim: #737e9b;
}

/* Kicker: eyebrow con punto cyan que respira (el "● CASE STUDY · DSP · HARDWARE" del portfolio) */
.eal-kicker {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: Barlow, Arial, sans-serif; font-size: .74rem; font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase; color: #a3adc6;
  margin-bottom: .9rem;
}
/* 23/9 (Felipe: "mantener el estándar" de los títulos chicos): el kicker de los heros (How we work,
   Billing, servicios) era el mismo rótulo que .eal-eyebrow pero en gris. Toma su gradiente; el
   punto que titila se queda porque es lo que lo marca como rótulo de portada. El color de arriba
   queda de fallback donde no hay background-clip: text. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .eal-kicker {
    background: var(--eal-grad-text);
    -webkit-background-clip: text; background-clip: text;
    color: transparent; -webkit-text-fill-color: transparent;
  }
}
.eal-kicker::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: var(--eal-cyan); box-shadow: 0 0 10px 2px rgba(25, 198, 255, .6);
  animation: eal-blink 2.6s ease-in-out infinite;
}
@keyframes eal-blink { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

/* Glows de fondo (dos radiales azul/violeta) para heros y secciones.

   El fundido de ARRIBA (Felipe, 22/9: "el tope de la página se nota muy brusco, pasa de negro al
   color de la animación y se re nota"). Los dos radiales están centrados FUERA de la caja
   (`at 12% -5%` y `at 105% 3%`), así que en el borde superior ya entran a plena intensidad y se
   cortaban a cuchillo contra el negro del sitio: medido en /success-stories, el color saltaba de
   rgb(9,9,9) a rgb(7,22,36) entre dos píxeles, y eso dibujaba una línea horizontal nítida cruzando
   todo el ancho justo debajo del header.

   Se ve sobre todo donde el glow apoya en negro (success-stories, y el detalle de un caso). En las
   páginas con foto a sangre el corte estaba igual, pero lo tapaba la imagen.

   La máscara desvanece sólo la punta de arriba: 72px es el tramo, en px y no en %, porque esta
   clase la comparten heros de alturas muy distintas (387px en el índice de casos, 850px en una
   portada de servicios) y un porcentaje daría un fundido distinto en cada una. Abajo no hace
   falta: los radiales ya cierran solos antes del pie. */
.eal-glow { position: relative; }
.eal-glow::before {
  content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background:
    radial-gradient(85% 50% at 12% -5%, rgba(0, 128, 255, .15), transparent 60%),
    radial-gradient(80% 55% at 105% 3%, rgba(161, 0, 255, .14), transparent 60%);
  -webkit-mask-image: linear-gradient(180deg, transparent 0, rgba(0, 0, 0, .45) 32px, #000 72px);
  mask-image: linear-gradient(180deg, transparent 0, rgba(0, 0, 0, .45) 32px, #000 72px);
}
.eal-glow > * { position: relative; z-index: 1; }

/* Panel tipo ventana: cabecera con tres luces + título, cuerpo con video / imagen / SVG */
.eal-panel {
  border: 1px solid var(--eal-card-border); border-radius: 16px; overflow: hidden;
  background: linear-gradient(180deg, #090c16, #06080f);
  box-shadow: 0 30px 80px -46px rgba(0, 0, 0, .9);
}
.eal-panel-head {
  display: flex; align-items: center; gap: 12px; padding: 11px 16px;
  border-bottom: 1px solid var(--eal-card-border); background: rgba(255, 255, 255, .015);
}
.eal-panel-lights { display: flex; gap: 7px; }
.eal-panel-lights i { width: 10px; height: 10px; border-radius: 50%; display: block; opacity: .75; }
.eal-panel-lights i:nth-child(1) { background: var(--eal-blue); }
.eal-panel-lights i:nth-child(2) { background: var(--eal-indigo); }
.eal-panel-lights i:nth-child(3) { background: var(--eal-violet); }
.eal-panel-title { font-family: Barlow, Arial, sans-serif; font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; color: var(--eal-dim); font-weight: 600; }
.eal-panel-body > video, .eal-panel-body > img, .eal-panel-body > svg { display: block; width: 100%; height: auto; }
.eal-panel-caption { font-family: Barlow, Arial, sans-serif; font-size: .8rem; color: var(--eal-dim); margin-top: .7rem; text-align: center; }

/* Chip cuadrado (7px) del portfolio, distinto de las píldoras */
.eal-chip {
  display: inline-block; font-family: Barlow, Arial, sans-serif; font-size: .78rem; font-weight: 600;
  letter-spacing: .04em; color: #b9c3da; padding: 5px 11px; border-radius: 7px;
  border: 1px solid var(--eal-card-border); background: rgba(255, 255, 255, .02);
}

/* Tabla de specs (clave / valor) */
.eal-specs { border: 1px solid var(--eal-card-border); border-radius: 14px; overflow: hidden; }
.eal-specs-row { display: grid; grid-template-columns: 190px 1fr; border-top: 1px solid var(--eal-card-border); }
.eal-specs-row:first-child { border-top: 0; }
.eal-specs-k { padding: 13px 18px; font-family: Barlow, Arial, sans-serif; font-size: .7rem; letter-spacing: .13em; text-transform: uppercase; color: var(--eal-dim); font-weight: 700; background: rgba(255, 255, 255, .02); }
.eal-specs-v { padding: 13px 18px; font-family: Barlow, Arial, sans-serif; font-size: .95rem; color: #eef2fb; font-weight: 500; }
@media (max-width: 500px) {
  .eal-specs-row { grid-template-columns: 1fr; }
  .eal-specs-k { padding-bottom: 4px; }
  .eal-specs-v { padding-top: 4px; }
}

/* Testimonio: estrellas + puntaje + fuente, cita en itálica, avatar */
.eal-stars { display: inline-flex; gap: 3px; }
.eal-stars svg { width: 18px; height: 18px; fill: #ffb020; filter: drop-shadow(0 0 6px rgba(255, 176, 32, .35)); }
.is-in .eal-stars svg, .eal-stars.is-in svg { animation: eal-pop .5s ease both; }
.eal-stars svg:nth-child(2) { animation-delay: .08s; }
.eal-stars svg:nth-child(3) { animation-delay: .16s; }
.eal-stars svg:nth-child(4) { animation-delay: .24s; }
.eal-stars svg:nth-child(5) { animation-delay: .32s; }
@keyframes eal-pop { 0% { transform: scale(.4); opacity: 0; } 70% { transform: scale(1.15); } 100% { transform: scale(1); opacity: 1; } }
.eal-score { font-family: Neusharp, Impact, sans-serif; font-size: 1.25rem; font-weight: 700; color: #fff; line-height: 1; }
.eal-src { font-family: Barlow, Arial, sans-serif; font-size: .66rem; letter-spacing: .12em; text-transform: uppercase; color: var(--eal-muted); font-weight: 700; }
.eal-quote { font-family: Barlow, Arial, sans-serif; font-style: italic; color: #e8edf8; line-height: 1.5; }
.eal-avatar {
  width: 44px; height: 44px; border-radius: 50%; flex: none; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--eal-grad); color: #fff;
  font-family: Neusharp, Impact, sans-serif; font-weight: 600; font-size: .9rem; letter-spacing: .02em;
  border: 1px solid rgba(255, 255, 255, .12);
}
.eal-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ── Motivos de audio (sin exagerar: señal viva, medidor de nivel) ───────────────────── */
/* Ecualizador: barras en gradiente que laten como un visualizador (el .eq del portfolio) */
.eal-eq { display: inline-flex; align-items: flex-end; justify-content: center; gap: 3px; height: 18px; }
.eal-eq i {
  display: block; width: 3px; height: 100%; border-radius: 999px;
  background: var(--eal-grad); transform-origin: bottom;
  animation: eal-eq 1.15s ease-in-out infinite; box-shadow: 0 0 8px rgba(0, 128, 255, .35); opacity: .92;
}
.eal-eq.lg { height: 40px; gap: 5px; }
.eal-eq.lg i { width: 5px; }
.eal-eq i:nth-child(1) { animation-delay: -.9s;  animation-duration: 1.05s; }
.eal-eq i:nth-child(2) { animation-delay: -.4s;  animation-duration: 1.3s; }
.eal-eq i:nth-child(3) { animation-delay: -.7s;  animation-duration: .95s; }
.eal-eq i:nth-child(4) { animation-delay: -.15s; animation-duration: 1.2s; }
.eal-eq i:nth-child(5) { animation-delay: -.55s; animation-duration: 1.1s; }
.eal-eq i:nth-child(6) { animation-delay: -.25s; animation-duration: 1.35s; }
.eal-eq i:nth-child(7) { animation-delay: -.8s;  animation-duration: 1s; }
@keyframes eal-eq { 0%, 100% { transform: scaleY(.22); opacity: .6; } 50% { transform: scaleY(1); opacity: 1; } }

/* Medidor de nivel: barra que se llena hasta --v al entrar en pantalla; .seg la parte en LEDs */
.eal-meter { height: 6px; border-radius: 3px; background: rgba(255, 255, 255, .08); overflow: hidden; }
.eal-meter i { display: block; height: 100%; width: 0; border-radius: 3px; background: var(--eal-grad); transition: width 1s cubic-bezier(.2, .7, .2, 1); }
.eal-meter.is-in i, .is-in .eal-meter i { width: var(--v, 100%); }
.eal-meter.seg { border-radius: 2px; -webkit-mask: repeating-linear-gradient(90deg, #000 0 6px, transparent 6px 9px); mask: repeating-linear-gradient(90deg, #000 0 6px, transparent 6px 9px); }
.eal-meter.seg i { border-radius: 0; }

/* Ambient: canvas de nodos conectados (lo llena eal-ui.js en [data-eal-ambient]) */
.eal-ambient { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; opacity: .55; }
.eal-ambient canvas { display: block; width: 100%; height: 100%; }

@media (prefers-reduced-motion: reduce) {
  .eal-kicker::before, .eal-stars svg { animation: none; }
  .eal-eq i { animation: none; }
  .eal-eq i:nth-child(1) { transform: scaleY(.35); } .eal-eq i:nth-child(2) { transform: scaleY(.7); }
  .eal-eq i:nth-child(3) { transform: scaleY(.5); }  .eal-eq i:nth-child(4) { transform: scaleY(.9); }
  .eal-eq i:nth-child(5) { transform: scaleY(.55); } .eal-eq i:nth-child(6) { transform: scaleY(.75); }
  .eal-eq i:nth-child(7) { transform: scaleY(.4); }
  .eal-meter i { transition: none; }
  .eal-reveal { opacity: 1; transform: none; transition: none; }
  .eal-marquee-track { animation: none; }
  .eal-wave path { animation: none; }
  .eal-card, .eal-card-glow:hover { transition: none; transform: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   SISTEMA DE ESCALA — títulos, subtítulos y espaciados (feedback del equipo, 11/9)
   ═══════════════════════════════════════════════════════════════════════════════════════

   "Definir un sistema único de tamaños de títulos, subtítulos y espaciados para todas las
   páginas." Hasta acá cada página resolvía su tipografía por su cuenta y el resultado, medido
   en el navegador a 1600px, era éste:

     /                        h1 64px (.hero-display)   ·  h2 48px (.display-h2)
     /about-us                h1 66.4px (.au-cover-h1)  ·  h2 48px
     /blog                    h1 64px                   ·  —
     /case-studies            h1 64px                   ·  h2 48px
     /services/[slug]         h1 64px                   ·  —
     /how-we-work             h1 48px  ← usaba .display-h2 COMO h1
     /plugin-launch-programs  h1 48px  ← idem

   O sea: tres tamaños distintos de H1 (48 / 64 / 66.4) y dos páginas cuyo titular principal
   era del tamaño de un subtítulo. Nada de eso era una decisión, era deriva.

   El sistema son estas variables. Una sola escala, en `clamp()` para que baje sola en pantallas
   chicas, y tres clases que la aplican. Las páginas que ya tenían el tamaño correcto no cambian
   (64px sigue siendo el H1 de página); las que se habían desviado se alinean.

   Cómo usarlo en una página nueva:
     · el titular de la página            → .eal-h1  (o .hero-display, que ahora toma la misma var)
     · el título de una sección           → .eal-h2  (o .display-h2)
     · el título de una card o sub-bloque → .eal-h3
     · el rótulo arriba del título        → .eal-eyebrow (ya existía)
   Y para los espaciados, --eal-space-section / --eal-space-block, más abajo. */
:root {
  /* Tipografía. El tope de cada escalón es el valor que YA usaba la mayoría de las páginas:
     el sistema documenta y unifica lo que había, no reinventa la escala. */
  --eal-fs-h1: clamp(2.2rem, 5vw, 4rem);      /* 35.2 → 64px  · titular de página */
  --eal-fs-h2: clamp(1.9rem, 3.6vw, 3rem);    /* 30.4 → 48px  · título de sección */
  --eal-fs-h3: clamp(1.3rem, 2.1vw, 1.75rem); /* 20.8 → 28px  · título de card / sub-bloque */
  --eal-fs-lede: clamp(1.05rem, 1.6vw, 1.25rem); /* bajada bajo un titular */
  /* Cuerpo. Dos escalones, no cinco: el texto de lectura larga (párrafos de un caso, de un
     servicio, de una card con prosa) y el secundario (pies, metadatos, texto de apoyo).
     Las páginas venían resolviendo el primero con 1rem, 1.02, 1.05, 1.08 y 1.12rem indistintas
     —diferencias de uno o dos píxeles que no comunican jerarquía, sólo ruido— así que el
     escalón de lectura toma 1.05rem, que era el valor más repetido de esos cinco. */
  --eal-fs-body: 1.05rem;     /* texto de lectura */
  --eal-fs-body-sm: .95rem;   /* texto secundario: pies, metadatos, apoyo */

  /* Espaciados verticales. Dos valores, no diez: el aire ENTRE secciones y el aire DENTRO de
     una sección (entre su encabezado y su contenido). El feedback pide "dar más aire entre
     secciones", así que --eal-space-section es deliberadamente generoso. */
  --eal-space-section: clamp(4.5rem, 8vw, 7.5rem);
  --eal-space-block: clamp(1.6rem, 2.6vw, 2.4rem);
}

.eal-h1, .eal-h2, .eal-h3 {
  font-family: Neusharp, Impact, sans-serif;
  font-weight: 600; line-height: 1.1; color: var(--_colors---white, #fff);
  margin-top: 0; margin-bottom: 0;
}
.eal-h1 { font-size: var(--eal-fs-h1); letter-spacing: -.02em; }
.eal-h2 { font-size: var(--eal-fs-h2); letter-spacing: -.015em; }
.eal-h3 { font-size: var(--eal-fs-h3); letter-spacing: -.01em; line-height: 1.15; }
.eal-lede {
  font-family: Barlow, Arial, sans-serif; font-size: var(--eal-fs-lede);
  line-height: 1.55; margin: 0;
}

/* Las clases HEREDADAS de Webflow pasan a leer las mismas variables. Es lo que hace que el
   sistema aplique al sitio entero sin reescribir el markup de cada página: `.hero-display` y
   `.display-h2` están en todas, y ahora las dos toman su tamaño de un solo lugar.
   Los 4rem/3rem fijos que tenían quedan como el TOPE del clamp, así en desktop no cambia nada
   de lo que ya estaba bien — lo que cambia es que en pantallas chicas bajan solas, y que ya no
   pueden desalinearse entre páginas. */
.hero-display { font-size: var(--eal-fs-h1); }
.display-h2 { font-size: var(--eal-fs-h2); }
/* `.display-h3` era el tercer escalón heredado y estaba en 1.35rem (21.6px), pegado a `.display-h4`
   (1.5rem) y a `.display-h5` (1.25rem): tres clases distintas para tres tamaños casi iguales, y
   ninguno en relación con el H1/H2 de arriba. Las tres pasan a leer --eal-fs-h3 (28px): un solo
   escalón de "título de card / sub-bloque", que es el papel que cumplen las tres. Las variantes
   `.project` (3.5rem, el titular de una portada de caso) NO entran acá — esas son H1 de su página
   y se quedan como están, por eso la regla apunta a la clase sola y no a sus modificadores. */
.display-h3:not(.project), .display-h4, .display-h5:not(.project) { font-size: var(--eal-fs-h3); }

/* ── Encabezado de Launch Programs (home + how-we-work/billing) ────────────────────────
   La sección de Launch Programs se repite igual en el home (`.section-lp`) y en billing
   (`.bill-lp-section`), con el mismo markup. Sus estilos de encabezado vivían DUPLICADOS en los
   dos `<style>`, comentario incluido, y el de billing ya había divergido en el padding. Un
   estilo que dos páginas comparten va acá: es la única forma de que no se desincronicen.

   El clamp NO es el de --eal-fs-h2 a propósito: su piso baja a 1.6rem porque el título va con
   `nowrap` en dos renglones, y con los 3rem fijos de `.display-h2` el renglón largo no entra a
   ningún ancho entre 992 y 480px — se partía dejando una palabra huérfana. El tope son los
   mismos 3rem/48px del sistema, así que en desktop es idéntico a cualquier otro título de
   sección; lo que cambia es cómo baja.

   1080px: el que manda sobre el ancho del título es ESTE contenedor. Tiene que dar para que el
   renglón 1 ("Your plugin, shipped at a fixed price,") entre entero. El párrafo no acompaña ese
   ancho: se lee mejor angosto, de ahí los 60ch.

   Dos renglones exactos (Felipe, 9/9), partiendo después de "fixed price,":
     Your plugin, shipped at a fixed price,
     on a date agreed up front
   El corte lo manda el MARKUP: cada renglón es un span en block + nowrap, así que no depende de
   que el ancho disponible alcance. El intento anterior (un <br> + max-width en ch) fallaba en el
   rango 768-700px: el <br> se ocultaba, el texto fluía y "front" quedaba colgado solo en un
   tercer renglón, partiendo "on a date agreed up front" al medio. Verificado renderizando a
   1440/1200/1024/991/950/900/860/820/768/700/600/480/390. */
.lp-home-head { position: relative; text-align: center; max-width: 1080px; margin: 0 auto 1.75rem; }
.lp-home-head .display-h2 { margin: 0 0 1rem; max-width: none; font-size: clamp(1.6rem, 4.55vw, 3rem); }
.lp-home-head .display-h2 .lp-home-line { display: block; white-space: nowrap; }
.lp-home-head .paragraph-title { margin: 0 auto; max-width: 60ch; }
/* Muy angosto (~400px) el renglón largo se vuelve ilegible de tan chico: ahí se libera el nowrap
   y el título fluye, que es preferible a un texto de 16px de alto. */
@media (max-width: 400px) {
  .lp-home-head .display-h2 .lp-home-line { display: inline; white-space: normal; }
}

/* ── Aire entre secciones ──────────────────────────────────────────────────────────────
   Feedback 11/9: "dar más aire entre secciones y usar menos cards y bordes distintos", y
   "cada sección tiene que entrar en una pantalla estándar" — que según aclaró Felipe significa
   que cada sección se lea como una unidad en su propio scroll, sin mezclarse con la siguiente.
   Las dos cosas piden lo mismo: separación clara y consistente.

   `.eal-section` es la clase para aplicarlo. No se fuerza sobre `section` a secas porque el CSS
   heredado de Webflow ya trae paddings propios por sección y pisarlos todos de una rompería
   páginas que hoy están bien. */
.eal-section { padding-top: var(--eal-space-section); padding-bottom: var(--eal-space-section); }
.eal-section-top { padding-top: var(--eal-space-section); }
.eal-section-bottom { padding-bottom: var(--eal-space-section); }

/* Las secciones COMPARTIDAS (las que repiten en varias páginas: pricing, contacto, testimonios,
   awards) traían del export de Webflow paddings sueltos en píxeles —100/100, 100/125, 100/25—
   que no bajan en pantallas chicas y no se relacionan entre sí. Pasan a la variable: mismo aire
   en desktop (el tope del clamp son 7.5rem = 120px, del orden de lo que ya tenían) y, a
   diferencia de antes, se achica solo en mobile en vez de comerse la pantalla.
   El footer NO entra: su aire de arriba (10px) es deliberado, va pegado a la sección anterior. */
.section-pricing, .section-contact, .section-testimonials, .section-awards {
  padding-top: var(--eal-space-section);
  padding-bottom: var(--eal-space-section);
}
/* Contacto cierra contra el footer: mantiene el remate corto que ya tenía. */
.section-contact { padding-bottom: 25px; }

/* Pricing y el piano son las DOS bandas de cierre y van pegadas una atrás de la otra: el
   formulario lo monta cada página al final y `<ContactPiano />` lo agrega BaseLayout justo
   después. Con 120px de cierre en pricing + 120px de apertura en el piano quedaban 240px de negro
   vacío entre el formulario y el teclado — el corte más grande del sitio, repetido en las 8
   páginas que usan el layout (el home no: trae su piano inline y apaga éste con `hidePiano`).
   Son dos partes del mismo remate, no dos secciones distintas, así que el aire va una sola vez:
   lo pone pricing al cerrar y el piano no lo duplica al abrir. Va con `~` y no con `+` porque
   entre las dos secciones quedan los <script> que cada página inyecta al final: con el
   adyacente la regla no matcheaba nunca (verificado midiendo en /case-studies/cantai, donde el
   piano seguía abriendo con 115.2px). Una `.section-contact` sin pricing antes —el blog, que lo
   monta solo— conserva su aire de apertura. */
.section-pricing ~ .section-contact { padding-top: 0; }

/* ── Bordes y superficies: UNA sola card ───────────────────────────────────────────────
   "usar menos cards y bordes distintos". `.eal-card` ya era la card canónica; el problema es
   que conviven con ella los bordes sueltos del CSS de Webflow, cada uno con su radio y su
   color. Estas variables son la única fuente de esos valores, así que una card nueva que use
   `.eal-card` no puede inventar un borde distinto. */
:root {
  --eal-border: 1px solid var(--eal-card-border);
  --eal-radius-lg: var(--eal-radius);
  /* Escalón intermedio: el de las cards de contenido (story-card, paneles de caso). Existía de
     hecho —18px repetido a mano en home y en case-studies para la MISMA card— pero no como
     valor del sistema, así que nada impedía que la próxima naciera con 16 o 20. */
  --eal-radius-md: 18px;
}

/* ── El header fijo no puede tapar lo que se ancla ──────────────────────────────────────
   La navbar es fija y mide ~96px con su aire. Sin `scroll-padding`, cualquier salto a un ancla
   (`/#Contact-Form`, el índice de un post, un `focus()` del teclado) deja el destino DEBAJO del
   header: verificado en /about-us, donde el encabezado "The team" quedaba tapado a medias.
   Va en el elemento raíz, que es lo que el navegador usa como viewport de scroll, así aplica a
   todos los anclajes del sitio de una sola vez. */
html { scroll-padding-top: 120px; }
