/* ==========================================================================
   GRAFS — Sistema de diseño (inspirado en Orb / withorb.com)
   Estilo: papel crema + serif editorial + etiquetas monoespaciadas + negro
   Todo el "look" se controla desde estos tokens. Cambiar aquí = cambiar toda la web.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Archivo:wght@600;700;800&family=Fraunces:ital,opsz,wght@0,9..144,400;0,9..144,500;0,9..144,600;1,9..144,500&family=Inter:wght@400;500;600;700&family=Poppins:wght@400;500;600;700&display=swap');

:root {
  /* --- Color (Brand Kit Grafs · regla 60/30/10) --- */
  --bg:        #FAFAFA;   /* secundario — fondo principal (off-white) */
  --bg-2:      #F0F0EE;   /* off-white un punto más oscuro (secciones/tarjetas) */
  --bg-3:      #F5F5F4;   /* a medio camino entre --bg y --bg-2: tiñe sin pesar */
  --ink:       #191A1E;   /* principal — casi negro (texto, botones, dark UI) */
  --ink-soft:  #54585F;   /* texto secundario */
  --ink-faint: #989CA3;   /* etiquetas, captions */
  --line:      rgba(25,26,30,.12); /* bordes finos */
  --white:     #ffffff;

  /* Acento (10%) + extras del brand kit */
  --accent:      #F7562B; /* naranja Grafs */
  --accent-700:  #DD441C; /* naranja oscuro (hover) */
  --accent-soft: #FDEAE1; /* naranja muy claro (fondos/pastillas) */
  --xtra-blue:   #d4ecff; /* azul claro extra (hoja de marca, 2026-08-28) */
  --xtra-coral:  #ff7651; /* coral extra (hoja de marca, 2026-08-28) */

  /* Degradado hero (sutil, neutro con tinte cálido + azul) */
  --grad-hero: linear-gradient(165deg,#FAFAFA 0%,#FCF1EC 45%,#F1F5FB 100%);
  --pix-orange: #F7562B;
  --pix-blue:   #4A90E2;
  --pix-coral:  #FF7D52;
  --pix-cyan:   #2BB6C2;
  --pix-amber:  #E8A33A;

  /* --- Tipografía (Brand Kit) ---
     DECIDIDO el 2026-08-28: estas tres son las tipografías de la web, no
     sustitutos provisionales. No se compran Uni Sans ni Recoleta.
       Títulos → Archivo · Serif editorial → Fraunces · Texto → Poppins
     (La hoja de marca pide Uni Sans / Recoleta / Tan Nimbus para OTROS
      soportes; para la web, manda esto.) */
  --font-serif: 'Fraunces', Georgia, serif;
  --fs-hero: clamp(34px, 4.6vw, 52px); --fs-section: clamp(28px, 3.4vw, 40px); --fs-eyebrow: 12.5px; --fs-body: clamp(16px, 1.15vw, 17px); --fs-h3: clamp(20px, 1.8vw, 24px); --sp-sec: clamp(70px, 9vw, 110px);  /* escala tipográfica por rol (2026-06-22) */
  --font-head:  'Archivo', 'Poppins', sans-serif;         /* títulos bold */
  --font-sans:  'Poppins', system-ui, sans-serif;         /* texto */
  --font-mono:  var(--font-sans);   /* mono retirado (decisión de marca): las etiquetas usan la sans (Poppins), como el H1. Reversible aquí. */
  --font-label: 'Inter', system-ui, sans-serif;          /* etiquetas grotescas (estilo Orb tagline) */

  /* --- Medidas --- */
  --r:      10px;   /* radio tarjetas */
  --r-btn:  8px;    /* radio botones */
  --maxw:   1600px; /* ancho máximo de contenido (era 1400 — 2026-08-28) */
  --gap:    32px;
  --nav-h:  88px;   /* alto aproximado del header (para extender el hero por detrás) */
}

/* Escala tipográfica en móvil: texto corriente más legible (18px)
   y títulos grandes un punto menos que el mínimo de escritorio. */
@media (max-width: 900px) {
  :root {
    --fs-hero: 32px;
    --fs-section: 26px;
    --fs-body: 18px;
  }
}

/* ==========================================================================
   MODO OSCURO — solo redefine tokens + algunas superficies
   ========================================================================== */
html[data-theme="dark"] {
  --bg:        #191A1E;   /* principal pasa a ser el fondo */
  --bg-2:      #232429;
  /* Faltaba, y era el unico token sin equivalente oscuro: se quedaba en el
     #F5F5F4 del tema claro. Lo usa `.page-home .faq-wrap`, asi que la FAQ de
     la home salia con banda CLARA en tema oscuro y su titular —que va en
     `--ink`, o sea casi blanco— era ilegible. Mismo criterio que en claro:
     a medio camino entre `--bg` y `--bg-2`. */
  --bg-3:      #1E1F24;
  --ink:       #FAFAFA;   /* texto claro */
  --ink-soft:  #AEB2B9;
  --ink-faint: #72767D;
  --line:      rgba(255,255,255,.13);
  --accent-soft: rgba(247,86,43,.16);
  --grad-hero: linear-gradient(165deg,#191A1E 0%,#241D1A 45%,#1A1E27 100%);
}
/* Superficies que no salen de un token directo */
html[data-theme="dark"] .nav {
  background: linear-gradient(180deg, rgba(44,46,53,.62), rgba(44,46,53,.34));
  border-color: rgba(255,255,255,.12);
  box-shadow: 0 1px 0 rgba(255,255,255,.08) inset, 0 10px 30px rgba(0,0,0,.4);
}
html[data-theme="dark"] .mega { background: #232429; border-color: rgba(255,255,255,.10); }
html[data-theme="dark"] .topbar { background: #0F1013; color: #FAFAFA; }
html[data-theme="dark"] .btn-ghost:hover { background: rgba(255,255,255,.08); }

/* Cambio de logo según tema */
.logo .logo-light { display: none; }
html[data-theme="dark"] .logo .logo-dark  { display: none; }
html[data-theme="dark"] .logo .logo-light { display: inline-block; }

/* Botón de cambio de tema */
.btn.theme-toggle {
  width: 44px; height: 44px;
  padding: 0;
  border-radius: var(--r-btn);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  line-height: 1;
}
.btn.theme-toggle svg { width: 20px; height: 20px; display: block; flex: 0 0 auto; }
.btn.theme-toggle .icon-sun { display: none; }
html[data-theme="dark"] .btn.theme-toggle .icon-moon { display: none; }
html[data-theme="dark"] .btn.theme-toggle .icon-sun  { display: block; }

/* --- Reset suave --- */
*,*::before,*::after { box-sizing: border-box; }
/* Red de seguridad móvil: nada puede provocar scroll horizontal (blobs del hero,
   elementos entrando con translateX, etc.). clip no crea contenedor de scroll,
   así que sticky sigue funcionando. */
html, body { overflow-x: clip; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  transition: background-color .3s ease, color .3s ease;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

/* --- Utilidades --- */
.container { max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-eyebrow);
  font-weight: 500;            /* peso uniforme NO-negrita (los kickers de hero van a 600 aparte) */
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 14px;
}
.serif { font-family: var(--font-serif); }

/* Titulares serif con el aire editorial de Orb */
h1,h2,h3 { font-family: var(--font-serif); font-weight: 500; line-height: 1.08; letter-spacing: -.01em; margin: 0; }
h1 { font-size: var(--fs-hero); }
h2 { font-size: var(--fs-section); }   /* todos los títulos de sección en la misma escala de rol */
h3 { font-size: var(--fs-h3); }
p  { margin: 0 0 1em; }
.lead { font-size: var(--fs-body); color: var(--ink-soft); max-width: 620px; }

/* --- Botones --- */
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-sans); font-weight: 600; font-size: 15px;
  padding: 13px 22px; border-radius: var(--r-btn);
  border: 1px solid var(--ink); cursor: pointer;
  transition: transform .15s ease, background .2s ease, color .2s ease;
}
.btn:hover { transform: translateY(-1px); }
.btn-dark  { background: var(--ink); color: var(--bg); }
.btn-dark:hover { background: #000; }
.btn-ghost { background: transparent; color: var(--ink); }
.btn-ghost:hover { background: rgba(25,26,30,.05); }
.btn-accent { background: var(--accent); color: #fff; border-color: var(--accent); }
.btn-accent:hover { background: var(--accent-700); border-color: var(--accent-700); }

/* ==========================================================================
   BARRA SUPERIOR (anuncio)
   ========================================================================== */
.topbar {
  position: relative; z-index: 70;   /* por encima del hero para tapar el sobrante del degradado */
  background: var(--ink); color: var(--bg);
  font-size: 13.5px; text-align: center; padding: 9px 16px;
}
.topbar a { text-decoration: underline; text-underline-offset: 3px; }

/* ==========================================================================
   HEADER / NAV — cristal líquido (liquid glass) + megamenú
   ========================================================================== */
.nav-wrap {
  position: sticky; top: 14px; z-index: 50;
  max-width: var(--maxw); margin: 0 auto;
  padding: 18px 24px 0;
}
.nav {
  position: relative;
  display: flex; align-items: center; justify-content: space-between;
  padding: 13px 14px 13px 22px;
  border-radius: 18px;
  /* --- Cristal líquido --- */
  background: linear-gradient(180deg, rgba(255,255,255,.50), rgba(255,255,255,.25));
  backdrop-filter: blur(18px) saturate(180%);
  -webkit-backdrop-filter: blur(18px) saturate(180%);
  /* Remate de cristal: brillo de borde, reflejo superior y profundidad.
     Estaba SOLO en .page-home y por eso la cabecera se veía plana en el resto
     del sitio. Subido aquí el 2026-09-04 por decisión de Iván, con los mismos
     valores exactos que tenía la home, así que la home no cambia.
     Efecto secundario buscado: la regla de modo oscuro fija `border-color`
     pero nunca fijó anchura ni estilo, así que en oscuro NO había borde en
     ninguna página salvo la home. Con esta anchura declarada aquí, ese
     border-color por fin se aplica y los dos temas quedan consistentes. */
  border: 1px solid rgba(255,255,255,.55);
  box-shadow:
    0 1px 0 rgba(255,255,255,.6) inset,             /* reflejo superior */
    0 10px 30px rgba(22,19,15,.08),                 /* sombra ambiente */
    0 2px 6px rgba(22,19,15,.04);
}
.page-home .nav {
  /* SOLO lo propio de la home: menos velo y menos desenfoque, porque es la
     única página con la retícula de puntos detrás y un blur de 18px se traga
     unos puntos separados 26px. El borde y la sombra ya vienen de .nav. */
  background: linear-gradient(180deg, rgba(255,255,255,.34), rgba(255,255,255,.14));
  backdrop-filter: blur(7px) saturate(150%);
  -webkit-backdrop-filter: blur(7px) saturate(150%);
}
.logo { display: inline-flex; align-items: center; }
.logo img {
  height: 24px; width: auto;   /* logo oscuro con fondo transparente */
}
.nav-links { display: flex; gap: 44px; list-style: none; margin: 0; padding: 0; font-size: 15px; font-weight: 500; }
.nav-links > li > a { display: inline-flex; align-items: center; gap: 5px; padding: 6px 0; transition: color .18s; }
.nav-links a:hover { color: var(--ink-soft); }
.caret { font-size: 10px; opacity: .55; transition: transform .2s; }
.menu-item.active .caret { transform: rotate(180deg); }
.nav-cta { display: flex; gap: 10px; align-items: center; }
.nav-cta .btn { padding: 10px 16px; }
.nav-toggle { display: none; }

/* --- Megamenú (panel de cristal que cuelga del nav) --- */
.menu-item { position: static; }
.mega {
  position: absolute; top: calc(100% + 10px); left: 0; right: 0;
  padding: 40px 48px;
  border-radius: 20px;
  background: #FBF8F1;            /* OPACO — el menú no es transparente */
  border: 1px solid var(--line);
  box-shadow: 0 28px 60px rgba(22,19,15,.18);
  opacity: 0; visibility: hidden; transform: translateY(8px) scale(.99);
  transition: opacity .26s cubic-bezier(.2,.7,.2,1), transform .26s cubic-bezier(.2,.7,.2,1), visibility .26s;
  z-index: 60;
}
.mega.open { opacity: 1; visibility: visible; transform: translateY(0) scale(1); }
.mega-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 36px; }
.mega-col h5 {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-faint); font-weight: 500; margin: 0 0 18px;
}
.mega-link { display: block; margin-bottom: 16px; }
.mega-link strong { display: block; font-family: var(--font-sans); font-weight: 600; font-size: 15px; transition: color .15s; }
.mega-link span { font-size: 13px; color: var(--ink-soft); line-height: 1.45; }
.mega-link:hover strong { color: var(--ink-soft); }

/* --- Overlay que oscurece/desenfoca el resto al abrir el menú --- */
.nav-overlay {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(22,19,15,.30);
  backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
  opacity: 0; visibility: hidden; transition: opacity .3s ease, visibility .3s;
}
.nav-overlay.open { opacity: 1; visibility: visible; }

/* --- MENÚ MÓVIL (panel tarjeta que cuelga de la píldora, ref. Orb) --- */
/* Hamburguesa: dos barras que se cruzan en X al abrir */
.nav-toggle { flex-direction: column; gap: 5px; width: 42px; height: 42px; padding: 0; align-items: center; justify-content: center; }
.nav-toggle span {
  display: block; width: 18px; height: 2px; border-radius: 2px;
  background: currentColor;
  transition: transform .28s cubic-bezier(.2,.7,.2,1);
}
.nav-toggle.open span:first-child { transform: translateY(3.5px) rotate(45deg); }
.nav-toggle.open span:last-child  { transform: translateY(-3.5px) rotate(-45deg); }

.nav-mobile {
  position: absolute; left: 24px; right: 24px; top: calc(100% + 10px);
  z-index: 60;
  display: flex; flex-direction: column;
  max-height: calc(100dvh - 190px);
  border-radius: 20px;
  background: rgba(251,248,241,.94);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  border: 1px solid rgba(255,255,255,.55);
  box-shadow: 0 28px 60px rgba(22,19,15,.18);
  opacity: 0; visibility: hidden; transform: translateY(8px) scale(.99);
  transition: opacity .26s cubic-bezier(.2,.7,.2,1), transform .26s cubic-bezier(.2,.7,.2,1), visibility .26s;
}
html[data-theme="dark"] .nav-mobile { background: rgba(35,36,41,.96); border-color: rgba(255,255,255,.10); }
.nav-mobile.open { opacity: 1; visibility: visible; transform: translateY(0) scale(1); }

.nm-list { list-style: none; margin: 0; padding: 10px 10px 4px; overflow-y: auto; flex: 1 1 auto; }
.nm-item > a, .nm-acc {
  display: flex; width: 100%; align-items: center; gap: 10px;
  padding: 15px 14px; margin: 0;
  background: none; border: 0; cursor: pointer; text-align: left;
  font-family: var(--font-sans); font-size: 18px; font-weight: 500; color: var(--ink);
}
.nm-acc .caret { font-size: 13px; transition: transform .25s; }
.nm-group.open .nm-acc .caret { transform: rotate(180deg); }
/* Despliegue del acordeón: truco de grid 0fr→1fr (animable sin JS de alturas) */
.nm-sub { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .3s cubic-bezier(.2,.7,.2,1); }
.nm-sub > div { overflow: hidden; }
.nm-group.open .nm-sub { grid-template-rows: 1fr; }
.nm-sub a {
  display: block; padding: 11px 14px 11px 30px;
  font-size: 16.5px; color: var(--ink);
}
.nm-sub a:active, .nm-item > a:active { color: var(--ink-soft); }
.nm-actions {
  flex: 0 0 auto;
  display: flex; flex-direction: column; gap: 10px;
  padding: 14px; margin-top: 4px;
  border-top: 1px solid var(--line);
}
.nm-actions .btn { width: 100%; justify-content: center; text-align: center; padding: 14px 16px; font-size: 15.5px; }
/* toggle de tema dentro del panel: de botón-icono cuadrado a fila completa con etiqueta */
.nm-theme { height: auto; gap: 10px; }

/* Con el menú abierto se bloquea el scroll de fondo. OJO: overflow:hidden en <html>
   desactiva el sticky del header, así que mientras el menú está abierto el nav-wrap
   pasa a fixed (el JS le clava el top donde estaba en pantalla al abrir). */
html.nav-locked, html.nav-locked body { overflow: hidden; }
html.nav-locked .nav-wrap { position: fixed; left: 0; right: 0; }

@media (max-width: 900px) {
  .mega { padding: 22px; }
  .mega-grid { grid-template-columns: 1fr 1fr; gap: 22px; }
  /* Móvil: en la píldora solo quedan logo + hamburguesa (el toggle de tema va en el panel) */
  .nav-links { display: none; }
  .nav-cta > a.btn { display: none; }
  .nav-cta > .theme-toggle { display: none; }
  .nav-toggle { display: inline-flex; }
}

/* ==========================================================================
   HERO
   ========================================================================== */
.hero {
  position: relative; text-align: center; overflow: hidden;
  margin-top: -120px;            /* sube generoso por detrás del header; la topbar tapa el sobrante */
  padding: 176px 24px 120px;     /* hueco para el header + aire abajo */
  /* 92vh sin tope daba 1.225px de hero en un monitor de 1440 de alto: el
     contenido quedaba perdido en mitad de un vacío. Topado arriba y abajo. */
  min-height: clamp(560px, 88vh, 900px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  background: var(--grad-hero);
  border-bottom: 1px solid var(--line);
}
.hero > .container { position: relative; z-index: 2; }
.hero h1 { max-width: 14ch; margin: 0 auto 24px; }
.hero .lead { margin: 0 auto 36px; }
.hero-actions { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }

/* --- Degradado interactivo: manchas de color que siguen el cursor --- */
.hero-fx {
  position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none;
  /* Las manchas se colocaban en % del viewport: en un monitor ancho se iban a
     los bordes y dejaban el texto solo en medio. Ahora se colocan dentro de una
     "escena" centrada y topada, así siguen envolviendo el contenido.
     Por debajo de ~1860px la escena ES el viewport y no cambia nada. */
  --escena:   min(100vw, calc(var(--maxw) + 260px));
  --escena-x: calc(50% - var(--escena) / 2);
}
.hero-blob {
  position: absolute; border-radius: 50%; filter: blur(70px);
  will-change: transform;
  transition: transform .3s cubic-bezier(.2,.7,.2,1);   /* más ágil */
}
.hero-blob.b1 {
  width: 540px; height: 540px; top: -120px; left: calc(var(--escena-x) + var(--escena) * .06);
  background: radial-gradient(circle, rgba(247,86,43,.66), transparent 70%);
  transform: translate3d(calc(var(--hx,0) * 130px), calc(var(--hy,0) * 130px), 0);
}
.hero-blob.b2 {
  width: 620px; height: 620px; bottom: -220px; right: calc(var(--escena-x) + var(--escena) * .04);
  background: radial-gradient(circle, rgba(74,144,226,.60), transparent 70%);
  transform: translate3d(calc(var(--hx,0) * -175px), calc(var(--hy,0) * -150px), 0);
}
.hero-blob.b3 {
  width: 420px; height: 420px; top: 28%; left: calc(var(--escena-x) + var(--escena) * .46);
  background: radial-gradient(circle, rgba(255,125,82,.54), transparent 70%);
  transform: translate3d(calc(var(--hx,0) * 115px), calc(var(--hy,0) * -135px), 0);
}
@media (prefers-reduced-motion: reduce) {
  .hero-blob { transition: none; transform: none !important; }
}

/* Logos de confianza */
.trust { padding: 48px 24px 56px; }
.trust-row { display: flex; flex-wrap: wrap; gap: 32px 64px; justify-content: center; align-items: center; }

/* Logos recoloreados con máscara CSS: la silueta da la forma, el color lo da background-color */
.trust-logo {
  display: inline-block;
  height: 34px;
  background-color: var(--accent);        /* naranja Grafs en modo claro */
  -webkit-mask: var(--logo) center / contain no-repeat;
          mask: var(--logo) center / contain no-repeat;
  -webkit-mask-mode: alpha; mask-mode: alpha;
  transition: opacity .25s ease, background-color .25s ease;
}
.trust-logo.attica     { --logo: url(../img/attica-mono.svg);     aspect-ratio: 560.17 / 137.72; height: 27px; } /* 5% más pequeño */
.trust-logo.aceitunero { --logo: url(../img/aceitunero-mono.png); aspect-ratio: 787 / 350; }
.trust-logo.carlin     { --logo: url(../img/carlin-mono.png);     aspect-ratio: 176 / 63; }
html[data-theme="dark"] .trust-logo { background-color: #FAFAFA; }   /* blancos en modo oscuro */

/* ==========================================================================
   TARJETAS DE SERVICIO (con "arte" pixel placeholder)
   ========================================================================== */
.cards { padding: 64px 0 80px; }
.cards-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: var(--gap); }
.card .eyebrow { display: flex; align-items: center; gap: 8px; }
/* Recuadro de servicio · PLACEHOLDER neutro y theme-aware, a la espera de FOTOGRAFÍAS EN B/N.
   (Se descartó toda la exploración de visuales generativos — irán fotos B/N adaptadas aquí.) */
.card-art {
  aspect-ratio: 1/1; border-radius: var(--r); margin: 6px 0 18px;
  position: relative; overflow: hidden;
  background: var(--bg-2); border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
}
/* símbolo placeholder muy simple (cuadro fino) — se quita al poner la imagen */
.card-art::after {
  content: ""; width: 26px; height: 26px;
  border: 1.6px solid var(--ink-faint); border-radius: 6px; opacity: .4;
}
/* Fotografías B/N de servicio: llenan el recuadro y anulan el placeholder */
.card-art img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; display: block;
}
.card-art:has(img)::after { display: none; }
.card-link { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; font-size: 14.5px; font-family: var(--font-mono); text-transform: uppercase; letter-spacing: .06em; }
.card p { color: var(--ink-soft); font-size: var(--fs-body); }

/* ==========================================================================
   SERVICIOS — SCROLL HORIZONTAL CON PINNING
   ========================================================================== */
.hservices {
  position: relative;
  /* Altura total = pin (100vh) + recorrido del scroll horizontal */
  /* Ajustada en JS si hace falta; 450vh para los 6 servicios del home.md */
  height: 450vh;
  background: var(--bg);
}
.hservices-inner {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  padding: 120px 0 40px;   /* solo separa del header; el viewport centra las cards en el espacio restante */
  overflow: hidden;
  box-sizing: border-box;
}
.hservices-head { flex: 0 0 auto; margin-bottom: 36px;
  /* baja el H2 hacia las cards (que se centran en el espacio restante) */
  margin-top: clamp(16px, 6vh, 56px);
  /* mismo offset lateral que el track → el H2 se alinea con la 1ª card y con el margen del sitio */
  padding-left:  max(24px, calc((100vw - var(--maxw)) / 2 + 24px));
  padding-right: max(24px, calc((100vw - var(--maxw)) / 2 + 24px));
}
.hservices-head-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 32px;
}
.hservices-head h2 {
  margin: 6px 0 0;
  font-size: var(--fs-section);
  line-height: 1.05;
  max-width: 18ch;
}
.hservices-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
  min-width: 260px;
}
.hservices-count {
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: .08em;
  color: var(--ink-soft);
}
.hservices-count .hs-current { color: var(--ink); font-weight: 700; }
.hservices-count .hs-sep { margin: 0 6px; color: var(--ink-faint); }
.hservices-progress {
  width: 220px;
  height: 4px;
  background: var(--bg-2);
  border-radius: 999px;
  overflow: hidden;
  position: relative;
}
.hservices-progress span {
  position: absolute;
  inset: 0 auto 0 0;
  width: 20%;
  background: var(--accent);
  border-radius: 999px;
  /* sin transition: el JS ya la anima frame a frame con el lerp del track */
}

.hservices-viewport {
  flex: 1 1 auto;
  min-height: 0;             /* permite que el flex item realmente encoja para no desbordar */
  overflow: hidden;
  display: flex;
  align-items: center;       /* centradas verticalmente en el espacio bajo el header */
}
.hservices-track {
  display: flex;
  align-items: flex-start;        /* todas las cards arrancan desde el mismo top */
  gap: 28px;
  will-change: transform;         /* el JS lo anima cada frame → capa propia en GPU */
  /* Padding lateral = mismo offset que el container, mantiene la primera card alineada */
  padding-left:  max(24px, calc((100vw - var(--maxw)) / 2 + 24px));
  padding-right: max(24px, calc((100vw - var(--maxw)) / 2 + 24px));
  will-change: transform;
  transform: translate3d(0,0,0);
}

.hcard {
  flex: 0 0 auto;
  /* El 50vh pretendía que la card cuadrada cupiera de alto, pero no descontaba
     los ~88px de etiqueta, enlace y huecos: a 620px de ventana la card pedía
     387px y sólo había 339, y el «Ver más →» quedaba cortado. El mínimo de
     300px además le impedía encoger. Ahora descuenta ese cromo y puede bajar. */
  width: clamp(220px, min(36vw, calc(50vh - 75px)), 480px);
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
  box-shadow: none;
  transition: transform .35s ease;
  text-decoration: none;           /* es un <a>, pero no queremos subrayados */
  color: inherit;
  cursor: pointer;
}
.hcard:hover .card-art { box-shadow: 0 30px 60px rgba(22,19,15,.14); }
.hcard:hover .card-link { color: var(--accent); }
.hcard .eyebrow {
  display: block;
  margin: 0;                       /* el gap del .hcard ya separa */
  line-height: 1.4;
  white-space: nowrap;             /* nunca wrap → todos misma altura */
  overflow: hidden;
  text-overflow: ellipsis;
  min-height: calc(1.4em);
}
.hcard .card-art {
  aspect-ratio: 1 / 1;
  margin: 4px 0 8px;
  border-radius: var(--r);
}
.hcard p { color: var(--ink-soft); font-size: var(--fs-body); line-height: 1.55; margin: 0; flex: 1; }
.hcard .card-link { margin-top: 8px; align-self: flex-start; }

/* En pantallas pequeñas el scroll horizontal se desactiva por JS: cae a un slider nativo */
.hservices.is-fallback { height: auto !important; }
.hservices.is-fallback .hservices-inner { position: static; height: auto; padding: 64px 0 56px; }
.hservices.is-fallback .hservices-head { margin-top: 0; }
.hservices.is-fallback .hservices-viewport { overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: 16px; scroll-padding: 0 24px; }
.hservices.is-fallback .hservices-track { padding-right: max(24px, calc((100vw - var(--maxw)) / 2 + 24px)); }
.hservices.is-fallback .hcard { scroll-snap-align: start; width: 84vw; max-width: 520px; }
.hservices.is-fallback .hservices-meta { display: none; }


/* ==========================================================================
   SERVICIOS (S2) — lista que rota con el scroll
   Sustituye al carrusel horizontal de tarjetas con fotos. Mismo mecanismo de
   anclaje: sección alta + hijo sticky. Tipografías: sólo las de la web.
   ========================================================================== */
.svc-scroll {
  position: relative;
  background: var(--bg);
  /* --pin gobierna lo ALTA que se ve la sección; --tramo, lo rápido que rota.
     Con el rótulo y el servicio en una sola línea no hace falta media pantalla
     de aire, así que ambos bajan bastante respecto a la primera versión. */
  --pin:   64vh;
  --tramo: 24vh;
  height: calc(var(--pin) + 6 * var(--tramo));
  /* Tipografía de la S2 = la del titular del hero. Lo pidió Aitor el
     2026-08-28 señalando el H1: el rótulo y los servicios tienen que verse
     del MISMO tamaño que "Que te encuentren y te elijan". Se hereda
     --fs-hero para que sigan atados: si un día cambia el hero, cambia esto. */
  --fs-svc: var(--fs-hero);
  /* Alto de cada renglón: gobierna ventana y desplazamiento. Se deriva del
     tamaño de letra (1,35 ≈ el interlineado que había antes: .74 invertido). */
  --alto: calc(var(--fs-svc) * 1.35);
}
.svc-pin {
  position: sticky;
  /* Centrada en la ventana, no pegada arriba: con un pin más bajo que la
     pantalla, top:0 dejaba la frase en el tercio superior y un vacío debajo. */
  top: calc((100vh - var(--pin)) / 2);
  height: var(--pin);
  overflow: hidden;
  display: flex; align-items: center;
}
.svc-stage {
  position: relative; z-index: 1; width: 100%;
  padding-left:  max(24px, calc((100vw - var(--maxw)) / 2 + 24px));
  padding-right: max(24px, calc((100vw - var(--maxw)) / 2 + 24px));
  text-align: center;
  /* En escritorio, rótulo y servicio en la MISMA línea: una sola frase que se
     completa sola al bajar. En móvil se apilan (ver la media query del final). */
  /* Centrado, no por línea base: la ventana es más alta que un renglón, así
     que alinear por base descolocaba el servicio respecto al rótulo. */
  display: flex; align-items: center; justify-content: center;
  /* El hueco se mide en píxeles, no en em: el .svc-stage hereda 16px y un
     .3em daba 5px, invisible al lado de un texto de 88px. */
  gap: clamp(10px, 1.2vw, 24px);
  flex-wrap: nowrap;
}
/* El rótulo va al MISMO tamaño que los servicios: forman una sola frase. */
.svc-lead {
  font-family: var(--font-serif);
  font-size: var(--fs-svc);
  font-weight: 500; line-height: 1;
  /* --ink, igual que el H1 del hero: el token ya se redefine en oscuro, así
     que los dos modos quedan atados sin regla aparte. (Era --ink-soft.) */
  color: var(--ink);
  /* Explícito porque el rótulo es un <h2>: la regla global `h1,h2,h3` mete
     -.01em y aquí no lo queremos —el rótulo se compone con el servicio de al
     lado y aquel va con su propio -.02em—. Sin esta línea, cambiar <p> por
     <h2> estrechaba «Te ayudamos con» unos píxeles. */
  letter-spacing: normal;
  margin: 0;
  white-space: nowrap;
  flex: 0 0 auto;
}

/* Ventana de tres renglones: el de en medio es el activo. El degradado de
   máscara difumina arriba y abajo en vez de cortar en seco. */
/* Una sola línea visible: los servicios entran y salen por ella. La máscara
   los difumina al asomar en vez de cortarlos en seco. */
.svc-window {
  /* Alta: se ven TODOS los servicios, muy tenues, y el activo destacado en el
     centro. Llena el espacio en vez de dejar la pantalla en blanco, y el que
     mira entiende de un vistazo cuántos servicios hay.
     La franja opaca de la máscara cubre justo el renglón central. */
  height: calc(var(--alto) * 5);
  min-width: 0; flex: 0 1 auto;
  align-self: center;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 26%, #000 74%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 26%, #000 74%, transparent 100%);
}
.svc-list {
  list-style: none; margin: 0; padding: 0;
  will-change: transform;
  transform: translate3d(0, 0, 0);
}
.svc-item {
  height: var(--alto);
  display: flex; align-items: center; justify-content: flex-start;
  white-space: nowrap;
}
.svc-item a {
  font-family: var(--font-head);
  font-size: var(--fs-svc);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ink);
  opacity: .16;
  text-decoration: none;
  /* Sin transition: el color y la opacidad los interpola el JS cuadro a cuadro
     siguiendo el scroll. Una transición aquí pelearía con eso y daría tirones. */
}
/* Cada servicio es un <h3> (los seis servicios de la casa: es la estructura
   que la home enseña a Google). El <h3> NO debe pintar nada: con
   `display: contents` desaparece de la maquetación y el <a> sigue siendo el
   hijo directo del flex de `.svc-item`, exactamente como antes. */
.svc-h { display: contents; }
.svc-item a:hover { opacity: 1 !important; }

/* Variante en MAYÚSCULAS (se activa añadiendo is-upper a la sección) */
.svc-scroll.is-upper .svc-item a {
  text-transform: uppercase;
  letter-spacing: -.01em;
  font-size: calc(var(--fs-svc) * .84);   /* las versales ocupan más: se compensa */
}

@media (max-width: 900px) {
  /* ---- Móvil y tablet · «lista viva», sin anclaje ------------------------
     Elegida entre tres el 2026-09-02.  La lista baja con la página y se
     enciende la que cruza el centro de la pantalla; los seis se leen siempre
     y el del centro sólo destaca.  Las otras dos anclaban como el escritorio
     y se descartaron por el mismo motivo: anclar en un teléfono se come una
     pantalla entera y depende de `100vh`, que en Safari de iOS cambia al
     esconderse la barra de direcciones —o sea, un salto justo al empezar a
     bajar, que es el peor momento posible—.  Sin anclaje no hay nada de eso.

     El rótulo vuelve arriba: «Te ayudamos con SEO y GEO» en una sola línea no
     cabe en una pantalla estrecha de ninguna manera.

     --fs-svc baja de 32 a 30px, y no es estética.  Medido a 390, «Email
     Marketing y SMS» ocupa 350px y la caja son 342: se salía por el borde y la
     ventana se lo comía.  A 30 mide 328.  Es el único de los seis que se pasa,
     y se pasa por 8px. */
  .svc-scroll { height: auto; padding: var(--sp-sec) 0; --fs-svc: 30px; }
  .svc-pin { position: static; height: auto; display: block; }
  /* Centrado, como en escritorio.  Lo pidió Aitor el 2-sep: el `left` venía de
     cuando la sección era una lista quieta y alineada al margen. */
  .svc-stage { display: block; text-align: center; }
  .svc-lead { margin: 0 0 14px; white-space: normal; }
  .svc-window { height: auto; -webkit-mask-image: none; mask-image: none; }
  /* Cada renglón gana aire: sin él el encendido no se aprecia, porque el de
     al lado está demasiado cerca del centro de la pantalla. */
  .svc-item { height: calc(var(--alto) * 1.3); justify-content: center; }

  /* OPACIDAD 1, no la .16 de escritorio, y el orden importa: es el respaldo
     por si el JS no arranca.  El módulo pinta con estilos EN LÍNEA, que ganan
     a esta regla sin necesidad de `!important`; si no llega a pintar, la lista
     se queda legible entera en vez de casi invisible. */
  .svc-item a { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .svc-item a { transition: none; }
}

/* ==========================================================================
   SECCIÓN DECLARACIÓN (serif grande + bullets)
   ========================================================================== */
.statement { padding: var(--sp-sec) 0; border-top: 1px solid var(--line); }
.statement-grid { display: grid; grid-template-columns: 1.1fr .9fr; gap: 60px; align-items: center; }
.statement h2 { max-width: 12ch; margin-bottom: 28px; }
.statement ul { list-style: none; padding: 0; margin: 0; }
.statement li { padding: 14px 0; border-top: 1px solid var(--line); color: var(--ink-soft); font-size: 16px; }
.statement-visual { background: var(--grad-hero); border: 1px solid var(--line); border-radius: var(--r); min-height: 360px; }

/* ==========================================================================
   DECLARACIÓN SCROLL (izquierda sticky, derecha que avanza)
   ========================================================================== */
.reveal { border-top: 1px solid var(--line); }
.reveal-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: start; }

/* Columna izquierda: se ancla y se centra mientras la derecha hace scroll */
.reveal-left {
  position: sticky; top: 0; align-self: start;
  min-height: 100vh; display: flex; flex-direction: column; justify-content: center;
  padding: 60px 0;
}
.reveal-left h2 { max-width: 15ch; margin-bottom: 44px; }
.reveal-states { position: relative; min-height: 210px; }
.reveal-state { position: absolute; inset: 0; opacity: 0; transform: translateY(12px); transition: opacity .5s ease, transform .5s ease; pointer-events: none; }
.reveal-state.is-active { opacity: 1; transform: none; pointer-events: auto; }
.reveal-state h3 { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-h3); margin-bottom: 18px; }
.reveal-state ul { list-style: none; padding: 0; margin: 0; }
.reveal-state li { position: relative; padding-left: 20px; margin-bottom: 12px; color: var(--ink-soft); font-size: var(--fs-body); }
.reveal-state li::before { content: ""; position: absolute; left: 0; top: 10px; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }

/* Columna derecha: panel con degradado y dos etapas apiladas */
.reveal-right {
  background: linear-gradient(160deg, #FDF1EC 0%, #EFF5FB 55%, #FAFAFA 100%);
  border: 1px solid var(--line); border-radius: 20px; overflow: hidden;
}
html[data-theme="dark"] .reveal-right { background: linear-gradient(160deg, #241D1A 0%, #1B1E26 60%, #191A1E 100%); }

.diagram-stage { position: relative; min-height: 90vh; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 20px; padding: 50px 24px; }
.diagram-stage.stage-1 { border-bottom: 1px dashed var(--line); }

/* Nodos / chips */
.node, .chip, .col-title {
  font-family: var(--font-mono); text-transform: uppercase; letter-spacing: .07em;
  background: #fff; border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 6px 20px rgba(22,19,15,.07);
}
.node { display: inline-flex; align-items: center; gap: 12px; padding: 12px 20px; font-size: 12px; }
.chip { padding: 8px 13px; font-size: 11px; border-radius: 9px; box-shadow: 0 4px 12px rgba(22,19,15,.05); }
.node.value { color: #33407a; }
.ico { width: 30px; height: 30px; border-radius: 8px; background: var(--ink); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-size: 15px; }
.ico.sm { width: 22px; height: 22px; font-size: 12px; border-radius: 6px; }
html[data-theme="dark"] .node, html[data-theme="dark"] .chip, html[data-theme="dark"] .col-title { background: #2a2c33; border-color: rgba(255,255,255,.12); box-shadow: 0 6px 20px rgba(0,0,0,.35); }

.chip-row { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; max-width: 420px; }

.center-circle {
  width: 150px; height: 150px; border-radius: 50%; border: 1.5px solid var(--ink);
  display: flex; align-items: center; justify-content: center; text-align: center;
  font-family: var(--font-mono); font-size: 13px; letter-spacing: .06em; text-transform: uppercase; line-height: 1.3;
  background: transparent;
}
.center-circle.filled { background: var(--ink); color: #fff; border: none; }
html[data-theme="dark"] .center-circle { border-color: rgba(255,255,255,.5); }
html[data-theme="dark"] .center-circle.filled { background: #fff; color: var(--ink); }

.diagram-cols { display: flex; align-items: center; justify-content: center; gap: 28px; flex-wrap: wrap; }
.diagram-col { display: flex; flex-direction: column; gap: 10px; align-items: center; }
.col-title { display: inline-flex; align-items: center; gap: 8px; padding: 8px 13px; font-size: 11.5px; font-weight: 500; }

@media (max-width: 900px) {
  .reveal-grid { grid-template-columns: 1fr; gap: 0; }
  .reveal-left { position: static; min-height: 0; padding: 40px 0 20px; }
  .reveal-left h2 { margin-bottom: 28px; }
  .reveal-states { min-height: 0; margin-bottom: 30px; }
  .reveal-state { position: static; opacity: 1; transform: none; margin-bottom: 24px; }   /* en móvil mostramos ambos */
  .diagram-stage { min-height: 70vh; }
}

/* ==========================================================================
   PROCESO (3 pasos numerados)
   ========================================================================== */
.process { padding: 80px 0; background: var(--bg-2); border-top: 1px solid var(--line); }
.process-head { max-width: 640px; margin-bottom: 50px; }
.steps { display: grid; grid-template-columns: repeat(3,1fr); gap: var(--gap); }
.step-icon { width: 46px; height: 46px; border-radius: 10px; background: var(--accent); display: flex; align-items: center; justify-content: center; color: #fff; font-size: 22px; margin-bottom: 18px; }
.step .eyebrow { margin-bottom: 8px; }
.step h3 { margin-bottom: 10px; }
.step p { color: var(--ink-soft); font-size: var(--fs-body); }

/* ==========================================================================
   PLATAFORMA (BENTO) — cards con gráficos animados al hover
   ========================================================================== */
.platform { padding: 90px 0; border-top: 1px solid var(--line); }
.platform-head { text-align: center; max-width: 720px; margin: 0 auto 52px; }
.platform-head h2 { margin: 14px 0 18px; }
.platform-head .lead { margin: 0 auto; }

.bento { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.bento-card {
  position: relative; overflow: hidden;
  background: #fff; border: 1px solid var(--line); border-radius: 16px;
  padding: 30px 30px 26px; display: flex; flex-direction: column;
  transition: box-shadow .3s ease, border-color .3s ease;
}
html[data-theme="dark"] .bento-card { background: var(--bg-2); }
.bento-card:hover { box-shadow: 0 18px 40px rgba(22,19,15,.10); border-color: rgba(247,86,43,.4); }
.bento-card .eyebrow { margin-bottom: 10px; }
.bento-card h3 { margin-bottom: 10px; }
.b-desc { color: var(--ink-soft); font-size: var(--fs-body); margin-bottom: 16px; }
.bento-link { margin-top: auto; font-family: var(--font-mono); font-size: 12.5px; text-transform: uppercase; letter-spacing: .06em; display: inline-flex; gap: 6px; align-items: center; }
.bento-link:hover { color: var(--accent); }

.card-tall { grid-column: 1; grid-row: 1 / 3; }
.card-wide { grid-column: 2 / 4; grid-row: 1; }
.card-c    { grid-column: 2; grid-row: 2; }
.card-d    { grid-column: 3; grid-row: 2; }

/* --- Gráfico de barras (crece al hover, escalonado) --- */
.chart { display: flex; align-items: flex-end; gap: 16px; height: 150px; margin-top: 22px; }
.chart .bar {
  flex: 1; border-radius: 7px 7px 0 0; background: var(--accent);
  transform: scaleY(.35); transform-origin: bottom;
  transition: transform .55s cubic-bezier(.2,.7,.2,1);
}
.chart .bar:nth-child(even) { background: #9cc2ec; }
.b-h1 { height: 45%; } .b-h2 { height: 70%; } .b-h3 { height: 55%; } .b-h4 { height: 85%; } .b-h5 { height: 100%; }
.card-wide:hover .chart .bar { transform: scaleY(1); }
.card-wide:hover .chart .bar:nth-child(2) { transition-delay: .07s; }
.card-wide:hover .chart .bar:nth-child(3) { transition-delay: .14s; }
.card-wide:hover .chart .bar:nth-child(4) { transition-delay: .21s; }
.card-wide:hover .chart .bar:nth-child(5) { transition-delay: .28s; }

/* --- Etiquetas flotantes (derivan al hover) --- */
.tags { position: relative; flex: 1; margin-top: 18px; min-height: 230px; }
.tag {
  position: absolute; font-family: var(--font-mono); font-size: 12px;
  background: rgba(74,144,226,.12); color: #2f6dbf;
  border-radius: 8px; padding: 5px 10px; white-space: nowrap;
  transition: transform .55s cubic-bezier(.2,.7,.2,1);
}
html[data-theme="dark"] .tag { background: rgba(74,144,226,.20); color: #9cc2ec; }
.tag:nth-child(1){ top: 4%;  left: 6%; }
.tag:nth-child(2){ top: 19%; left: 44%; }
.tag:nth-child(3){ top: 35%; left: 12%; }
.tag:nth-child(4){ top: 51%; left: 42%; }
.tag:nth-child(5){ top: 67%; left: 8%; }
.tag:nth-child(6){ top: 83%; left: 38%; }
.card-tall:hover .tag:nth-child(1){ transform: translate(10px,-8px); }
.card-tall:hover .tag:nth-child(2){ transform: translate(-12px,8px);  transition-delay: .05s; }
.card-tall:hover .tag:nth-child(3){ transform: translate(14px,6px);   transition-delay: .10s; }
.card-tall:hover .tag:nth-child(4){ transform: translate(-10px,-10px);transition-delay: .15s; }
.card-tall:hover .tag:nth-child(5){ transform: translate(12px,-6px);  transition-delay: .20s; }
.card-tall:hover .tag:nth-child(6){ transform: translate(-14px,8px);  transition-delay: .25s; }

@media (max-width: 900px) {
  .bento { grid-template-columns: 1fr; }
  .card-tall, .card-wide, .card-c, .card-d { grid-column: auto; grid-row: auto; }
  .tags { min-height: 200px; }
}
@media (prefers-reduced-motion: reduce) {
  .chart .bar { transform: none; }
  .card-tall:hover .tag { transform: none !important; }
}

/* ==========================================================================
   TESTIMONIO
   ========================================================================== */
.quote { padding: 90px 0; }
.quote-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 60px; align-items: center; }
.quote blockquote { font-family: var(--font-serif); font-size: clamp(24px,2.6vw,34px); line-height: 1.3; margin: 0 0 28px; }
.quote-author { display: flex; align-items: center; gap: 16px; font-size: 14px; }
.quote-author strong { display: block; }
.quote-photo { background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--r); aspect-ratio: 4/3; }

/* ==========================================================================
   CTA FINAL
   ========================================================================== */
.cta { text-align: center; padding: var(--sp-sec) 24px; background: var(--grad-hero); border-top: 1px solid var(--line); }
.cta h2 { max-width: 16ch; margin: 0 auto 18px; }
.cta .cta-title { font-family: var(--font-serif); font-size: var(--fs-section); font-weight: 500; line-height: 1.1; max-width: 16ch; margin: 0 auto 18px; color: var(--ink); }
.cta .lead { margin: 0 auto 32px; }
.cta-actions { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }

/* ==========================================================================
   PÁGINA DE SERVICIO (e-commerce)
   ========================================================================== */
/* Hero de servicio: texto a la izquierda + visual a la derecha */
.svc-hero {
  position: relative; overflow: hidden;
  min-height: 100vh; display: flex; align-items: center;   /* ocupa toda la pantalla */
  margin-top: -120px; padding: clamp(120px, calc(50vh - 186px), 186px) 0 80px;
  background: var(--grad-hero);
}
/* Fundido suave del degradado hacia el fondo (sin salto al bajar) */
.svc-hero::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 180px;
  background: linear-gradient(to bottom, transparent, var(--bg));
  z-index: 1; pointer-events: none;
}
.svc-hero .container {
  position: relative; z-index: 2; display: grid; grid-template-columns: 1.05fr .95fr; gap: 56px; align-items: center;
  /* El hero es flex → sin esto cada container encogía a su contenido y el margen
     variaba entre páginas. Ancho fijo = margen idéntico en todos los servicios
     (calcado al que tenía diseño web). */
  width: 100%; max-width: 1280px;
}
/* solo el titular grande: el kicker también puede ser <h1> y lleva su clase */
.svc-hero h1.serif { font-size: var(--fs-hero); margin: 0 0 22px; max-width: 880px; }
.svc-hero .lead { margin-bottom: 32px; }
.svc-actions { display: flex; gap: 14px; flex-wrap: wrap; }
.svc-visual { display: flex; align-items: center; justify-content: center; }
.hero-pixel { width: 100%; max-width: 560px; height: auto; display: block; }

/* Mockup de tienda (browser frame con product cards) */
.shop-mock { background: #fff; border: 1px solid var(--line); border-radius: 16px; box-shadow: 0 30px 60px rgba(22,19,15,.14); overflow: hidden; }
html[data-theme="dark"] .shop-mock { background: var(--bg-2); }
.shop-bar { display: flex; gap: 7px; padding: 13px 16px; border-bottom: 1px solid var(--line); }
.shop-bar span { width: 11px; height: 11px; border-radius: 50%; background: var(--line); }
.shop-bar span:first-child { background: var(--accent); }
.shop-body { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 14px; padding: 18px; }
.shop-card { border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.shop-img { aspect-ratio: 1/1; background: linear-gradient(135deg, var(--accent-soft), #eef3fb); }
.shop-card:nth-child(2) .shop-img { background: linear-gradient(135deg,#eef3fb,var(--accent-soft)); }
.shop-meta { padding: 10px 12px; }
.shop-line { height: 7px; width: 80%; background: var(--line); border-radius: 4px; margin-bottom: 8px; }
.shop-line.short { width: 50%; }
.shop-price { font-family: var(--font-mono); font-size: 13px; font-weight: 600; color: var(--accent); }

/* Pipeline horizontal (flujo) */
.pipeline-wrap { padding: var(--sp-sec) 0; border-top: 1px solid var(--line); }
.pipeline-head { text-align: center; max-width: 680px; margin: 0 auto 48px; }
.pipeline-head h2 { margin: 14px 0 16px; }
.pipeline { display: flex; align-items: stretch; justify-content: center; gap: 12px; flex-wrap: wrap; }
.stage { flex: 1; min-width: 190px; background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 26px 22px; text-align: center; transition: box-shadow .3s, transform .3s; }
html[data-theme="dark"] .stage { background: var(--bg-2); }
.stage:hover { box-shadow: 0 16px 36px rgba(22,19,15,.10); transform: translateY(-3px); }
.stage .stage-ico { width: 46px; height: 46px; margin: 0 auto 16px; border-radius: 12px; background: var(--accent); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 22px; }
.stage h4 { font-family: var(--font-serif); font-weight: 500; font-size: 19px; margin: 0 0 8px; }
.stage p { font-size: var(--fs-body); color: var(--ink-soft); margin: 0; }
.pipeline .arrow { display: flex; align-items: center; color: var(--accent); font-size: 22px; }

/* Filas de características alternadas */
.feature { padding: var(--sp-sec) 0; border-top: 1px solid var(--line); }
.feature .container { display: grid; grid-template-columns: 1fr 1fr; gap: 60px; align-items: center; }
.feature.reverse .feat-text { order: 2; }
.feature h2 { font-size: var(--fs-section); margin: 14px 0 18px; }
.feature .b-desc, .feature p { color: var(--ink-soft); }
.feat-list { list-style: none; padding: 0; margin: 22px 0 0; }
.feat-list li { position: relative; padding-left: 22px; margin-bottom: 12px; color: var(--ink-soft); }
.feat-list li::before { content: ""; position: absolute; left: 0; top: 9px; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
.feat-list strong { color: var(--ink); }
.feat-visual { min-height: 340px; border: 1px solid var(--line); border-radius: 18px; background: var(--grad-hero); position: relative; overflow: hidden; display: flex; align-items: center; justify-content: center; }
/* El gráfico de barras dentro de una feature se anima al pasar el cursor */
.feature .chart .bar { transform: scaleY(.4); }
.feature:hover .chart .bar { transform: scaleY(1); }
.feature:hover .chart .bar:nth-child(2) { transition-delay: .07s; }
.feature:hover .chart .bar:nth-child(3) { transition-delay: .14s; }
.feature:hover .chart .bar:nth-child(4) { transition-delay: .21s; }
.feature:hover .chart .bar:nth-child(5) { transition-delay: .28s; }

/* Principios (3 columnas) */
.principles { padding: var(--sp-sec) 0; border-top: 1px solid var(--line); }
.principles-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 40px; margin-top: 44px; }
.principle .p-ico { width: 50px; height: 50px; border-radius: 12px; background: var(--ink); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 22px; margin-bottom: 18px; }
.principle h3 { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-h3); margin-bottom: 12px; }
.principle p { color: var(--ink-soft); font-size: var(--fs-body); }

/* ============================================================
   FEATURE BLOCKS — bloques de servicio con visuales variados
   ============================================================ */
.feat-block { padding: var(--sp-sec) 0; border-top: 1px solid var(--line); }
.feat-block .container { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center; }
.feat-block.reverse .fb-text { order: 2; }
.feat-block h2 { font-size: var(--fs-section); line-height: 1.05; margin: 14px 0 18px; }
.feat-block .fb-desc { color: var(--ink-soft); margin-bottom: 22px; max-width: 52ch; line-height: 1.65; }
.feat-block .fb-list { list-style: none; padding: 0; margin: 0 0 28px; display: flex; flex-direction: column; gap: 12px; }
.feat-block .fb-list li { position: relative; padding-left: 24px; color: var(--ink); font-size: 16px; line-height: 1.5; }
.feat-block .fb-list li::before {
  content: ""; position: absolute; left: 0; top: 8px;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent);
}
.feat-block .fb-cta {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--ink); font-weight: 600; text-decoration: none;
  border-bottom: 1px solid var(--ink); padding-bottom: 4px;
  transition: color .2s, border-color .2s;
}
.feat-block .fb-cta:hover { color: var(--accent); border-color: var(--accent); }
.feat-block .fb-cta .arr { transition: transform .25s; }
.feat-block .fb-cta:hover .arr { transform: translateX(4px); }

/* Visual: pila escalonada de tarjetas */
.fb-visual { position: relative; min-height: 460px; display: flex; align-items: center; justify-content: center; }
.fb-pixels {
  position: absolute; inset: 0; pointer-events: none;
  background-image: radial-gradient(var(--accent) 1.5px, transparent 1.6px);
  background-size: 14px 14px;
  opacity: .35;
  -webkit-mask-image: radial-gradient(ellipse at center, #000 0%, transparent 70%);
          mask-image: radial-gradient(ellipse at center, #000 0%, transparent 70%);
}
.fb-stack { position: relative; width: 100%; max-width: 380px; height: 420px; }
.fb-card {
  position: absolute; background: var(--bg); border: 1px solid var(--line); border-radius: 16px;
  padding: 18px; width: 86%;
  box-shadow: 0 24px 50px rgba(22,19,15,.12);
}
.fb-card.c1 { top: 0; left: 0; }
.fb-card.c2 { top: 125px; left: 7%; }
.fb-card.c3 { top: 250px; left: 14%; box-shadow: 0 36px 70px rgba(22,19,15,.18); }
.fb-card h5 { font-family: var(--font-serif); font-weight: 500; font-size: 17px; margin-bottom: 12px; color: var(--ink); }
.fb-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;   /* que etiqueta y valor nunca se toquen en pantallas estrechas */
  padding: 9px 12px; background: var(--bg-2); border: 1px solid var(--line);
  border-radius: 8px; font-size: 13px; color: var(--ink); margin-bottom: 6px;
}
.fb-row:last-child { margin-bottom: 0; }
.fb-row .fb-val { color: var(--ink-soft); font-variant-numeric: tabular-nums; text-align: right; }
.fb-row.is-accent { background: var(--accent-soft); border-color: rgba(247,86,43,.25); }
.fb-row.is-accent .fb-val { color: var(--accent-700); font-weight: 600; }

/* Visual: código / mockup técnico */
.fb-code {
  background: var(--ink); color: var(--bg);
  border-radius: 14px; padding: 0;
  box-shadow: 0 30px 60px rgba(22,19,15,.20);
  max-width: 480px; width: 100%;
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
  font-size: 13px; line-height: 1.7;
  overflow: hidden;
}
.fb-code-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 18px;
  background: rgba(255,255,255,.04);
  border-bottom: 1px solid rgba(255,255,255,.08);
  font-family: var(--font-sans); font-size: 12px; color: rgba(250,250,250,.65);
}
.fb-code-head .fb-pill {
  display: inline-block; padding: 3px 10px; border-radius: 999px;
  background: var(--accent); color: #fff; font-weight: 600; font-size: 11px;
}
.fb-code-body { padding: 18px 20px; }
.fb-code-body .ln { display: block; white-space: pre; }
.fb-code-body .kw { color: #FFB997; }
.fb-code-body .str { color: #B0E5C7; }
.fb-code-body .num { color: #C9B4FF; }
.fb-code-body .com { color: #6E737A; }
.fb-code-body .fn { color: #9CC2EC; }

/* Visual: workflow diagram (nodos conectados) */
.fb-flow {
  position: relative;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 26px 22px;
  box-shadow: 0 30px 60px rgba(22,19,15,.12);
  max-width: 460px;
  width: 100%;
}
.fb-flow-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 22px;
  font-size: 12px; color: var(--ink-faint);
  font-family: var(--font-sans);
  padding-bottom: 14px;
  border-bottom: 1px dashed var(--line);
}
.fb-flow-head .fb-pill {
  display: inline-block; padding: 4px 10px; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent-700);
  font-weight: 600; font-size: 11px;
  text-transform: uppercase; letter-spacing: .04em;
}
.fb-flow .fb-node {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 12px;
  position: relative;
  margin-bottom: 28px;
}
.fb-flow .fb-node:last-child { margin-bottom: 0; }
.fb-flow .fb-node:not(:last-child)::after {
  content: ""; position: absolute;
  left: 33px; bottom: -22px;
  width: 2px; height: 16px;
  background: var(--accent);
}
.fb-flow .fb-node:not(:last-child)::before {
  content: ""; position: absolute;
  left: 27px; bottom: -22px;
  border-left: 7px solid transparent;
  border-right: 7px solid transparent;
  border-top: 8px solid var(--accent);
  z-index: 2;
}
.fb-flow .fb-node-ico {
  width: 36px; height: 36px; border-radius: 10px;
  background: var(--ink); color: var(--bg);
  display: flex; align-items: center; justify-content: center;
  font-size: 17px; flex-shrink: 0;
}
.fb-flow .fb-node.is-ai .fb-node-ico { background: var(--accent); box-shadow: 0 6px 16px rgba(247,86,43,.35); }
.fb-flow .fb-node.is-done .fb-node-ico { background: #6BB07F; }
.fb-flow .fb-node-text { flex: 1; min-width: 0; }
.fb-flow .fb-node-title { font-weight: 600; font-size: 14px; color: var(--ink); line-height: 1.2; }
.fb-flow .fb-node-sub { font-size: 12px; color: var(--ink-soft); margin-top: 2px; }
.fb-flow .fb-node-tag {
  font-size: 10px; padding: 3px 8px; border-radius: 6px;
  background: var(--bg); color: var(--ink-faint);
  font-family: ui-monospace, monospace;
  border: 1px solid var(--line);
  flex-shrink: 0;
}

/* Visual: integraciones (grid radial con IA en el centro) */
.fb-apps {
  position: relative;
  width: 100%;
  max-width: 440px;
  aspect-ratio: 1;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: 14px;
  padding: 6px;
}
.fb-apps::before {
  content: ""; position: absolute; inset: -30px;
  background-image: radial-gradient(var(--accent) 1.5px, transparent 1.6px);
  background-size: 14px 14px; opacity: .18;
  -webkit-mask-image: radial-gradient(ellipse at center, #000 0%, transparent 70%);
          mask-image: radial-gradient(ellipse at center, #000 0%, transparent 70%);
  z-index: 0;
}
.fb-app {
  position: relative; z-index: 1;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 16px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-serif);
  font-size: 22px; font-weight: 500;
  color: var(--ink);
  box-shadow: 0 10px 22px rgba(22,19,15,.06);
  transition: transform .3s, box-shadow .3s;
  cursor: default;
}
.fb-app:hover { transform: translateY(-3px); box-shadow: 0 18px 36px rgba(22,19,15,.12); }
.fb-app.is-ai {
  background: var(--ink); color: var(--bg);
  border-color: var(--ink);
  box-shadow: 0 20px 40px rgba(22,19,15,.30);
  font-size: 14px; text-align: center; line-height: 1.1;
  font-family: var(--font-sans); font-weight: 700;
  letter-spacing: .04em;
}
.fb-app.is-ai::after {
  content: ""; position: absolute; inset: -6px;
  border: 2px dashed var(--accent); border-radius: 22px;
  opacity: .55;
  animation: fb-ai-pulse 4s linear infinite;
}
@keyframes fb-ai-pulse {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
.fb-app .fb-app-name {
  position: absolute; bottom: 6px; left: 0; right: 0;
  text-align: center;
  font-family: var(--font-sans); font-size: 10px; font-weight: 600;
  color: var(--ink-faint); letter-spacing: .04em;
  text-transform: uppercase;
}

/* ============================================================
   CONTACTO
   ============================================================ */
.contact-wrap { padding: 60px 0 30px; }
.contact-intro { max-width: 720px; margin: 0 auto 50px; text-align: center; }
.contact-intro h1 {
  font-family: var(--font-serif); font-weight: 500;
  font-size: var(--fs-hero); line-height: 1.05;
  margin: 14px 0 18px;
}
.contact-intro .lead { margin: 0 auto; }

.contact-grid {
  display: grid; grid-template-columns: 1.2fr .8fr;
  gap: 50px; align-items: start;
  max-width: 1100px; margin: 0 auto;
}
/* los items no pueden ensanchar su pista con el min-content (móvil) */
.contact-grid > * { min-width: 0; }

/* Form card */
.contact-form {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 22px;
  padding: 36px 38px;
  box-shadow: 0 30px 60px rgba(22,19,15,.08);
}
.contact-form h2 {
  font-family: var(--font-serif); font-weight: 500;
  font-size: var(--fs-section); line-height: 1.2; margin-bottom: 26px;
}
.cf-row { margin-bottom: 18px; }
.cf-row.cf-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.cf-label {
  display: block; font-size: 12px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-soft); margin-bottom: 8px;
}
.cf-label .req { color: var(--accent); margin-left: 4px; }
.cf-input, .cf-textarea, .cf-select {
  width: 100%; padding: 12px 16px;
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--bg-2); color: var(--ink);
  font-family: inherit; font-size: 15px; line-height: 1.4;
  transition: border-color .2s, background .2s, box-shadow .2s;
}
.cf-input:focus, .cf-textarea:focus, .cf-select:focus {
  outline: none; border-color: var(--accent); background: var(--bg);
  box-shadow: 0 0 0 4px var(--accent-soft);
}
.cf-textarea { resize: vertical; min-height: 140px; line-height: 1.55; }
.cf-select {
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2354585F'><path d='M7 10l5 5 5-5z'/></svg>");
  background-repeat: no-repeat; background-position: right 14px center;
  padding-right: 42px;
}
.cf-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.cf-chip {
  display: inline-block; padding: 8px 14px;
  border-radius: 999px; border: 1px solid var(--line);
  background: var(--bg-2); color: var(--ink-soft);
  font-size: 13px; font-weight: 500;
  cursor: pointer; user-select: none;
  position: relative;
  transition: all .2s;
}
.cf-chip:hover { color: var(--ink); border-color: var(--ink); }
/* `display: none` saca la casilla del orden de tabulación: los chips no se
   podían marcar con el teclado. Se oculta a la vista pero se deja enfocable. */
.cf-chip input {
  position: absolute; width: 1px; height: 1px;
  opacity: 0; margin: 0; pointer-events: none;
}
.cf-chip.is-checked {
  background: var(--ink); color: var(--bg); border-color: var(--ink);
}
.cf-submit {
  width: 100%;
  padding: 14px 22px; border: 0; border-radius: 999px;
  background: var(--accent); color: #fff;
  font-family: inherit; font-weight: 700; font-size: 15px;
  cursor: pointer; transition: background .2s, transform .2s;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  margin-top: 8px;
}
.cf-submit:hover { background: var(--accent-700); transform: translateY(-1px); }
.cf-foot { margin-top: 14px; font-size: 12px; color: var(--ink-faint); text-align: center; }
.cf-success {
  display: none; padding: 22px; border-radius: 14px;
  background: var(--accent-soft); border: 1px solid var(--accent);
  color: var(--accent-700); font-weight: 600; text-align: center;
}
.cf-success.is-visible { display: block; }

/* Side info */
.contact-side { display: flex; flex-direction: column; gap: 18px; }
.ci-card {
  background: var(--bg); border: 1px solid var(--line);
  border-radius: 18px; padding: 24px 26px;
  transition: transform .25s, border-color .25s;
}
.ci-card:hover { transform: translateY(-2px); border-color: var(--accent); }
.ci-card .ci-eyebrow {
  display: inline-block; font-size: 11px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent-700); margin-bottom: 10px;
}
.ci-card h3 {
  font-family: var(--font-serif); font-weight: 500;
  font-size: var(--fs-h3); line-height: 1.2; margin-bottom: 8px;
}
.ci-card p { color: var(--ink-soft); font-size: var(--fs-body); line-height: 1.55; margin: 0; }
.ci-card a { color: var(--ink); font-weight: 600; text-decoration: none; }
.ci-card a:hover { color: var(--accent); }
.ci-card.is-dark {
  background: var(--ink); color: var(--bg);
  border-color: var(--ink); position: relative; overflow: hidden;
}
.ci-card.is-dark::before {
  content: ""; position: absolute; right: -40px; bottom: -40px;
  width: 200px; height: 200px; border-radius: 50%;
  background: radial-gradient(circle, rgba(247,86,43,.35), transparent 70%);
}
.ci-card.is-dark .ci-eyebrow { color: var(--accent); }
.ci-card.is-dark h3 { color: var(--bg); position: relative; z-index: 1; }
.ci-card.is-dark p { color: color-mix(in srgb, var(--bg) 72%, transparent); position: relative; z-index: 1; }
.ci-card.is-dark a { color: var(--bg); border-bottom: 1px solid var(--accent); }

.ci-channels { display: flex; flex-direction: column; gap: 12px; }
.ci-channel {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 14px; background: var(--bg-2);
  border-radius: 12px; text-decoration: none; color: var(--ink);
  transition: all .2s;
}
.ci-channel:hover { background: var(--accent-soft); }
.ci-channel .cc-icon {
  width: 38px; height: 38px; border-radius: 10px;
  background: var(--ink); color: var(--bg);
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; flex-shrink: 0;
}
.ci-channel .cc-text { flex: 1; min-width: 0; }
.ci-channel .cc-label { font-size: 11px; color: var(--ink-faint); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; }
.ci-channel .cc-val { display: block; font-weight: 600; font-size: 14px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ------------------------------------------------------------------
   Contacto · 31-ago-2026
   ------------------------------------------------------------------ */

/* Marca de campo opcional dentro de una etiqueta en versalitas. No hereda el
   peso ni las mayúsculas: si los heredara pesaría igual que el nombre del
   campo, que es justo lo contrario de lo que tiene que decir. */
.cf-label .cf-opt {
  font-weight: 500; text-transform: none; letter-spacing: 0;
  color: var(--ink-faint);
}

/* La tarjeta de canales pasa a negra, así que sus filas se invierten. Van con
   `--bg`/`--ink` y no con un color fijo porque `.is-dark` se voltea con el
   tema: en oscuro la tarjeta es la blanca, y estas reglas valen igual.
   El `z-index` es por la mancha naranja de `.ci-card.is-dark::before`, que al
   ir en absoluto pinta por encima de todo lo que esté en `static`. */
.ci-card.is-dark .ci-channel {
  /* Opaca, no translúcida: la mancha naranja del `::before` se veía por detrás
     de la última fila y la dejaba con pinta de estar ya seleccionada. Mezclando
     sobre `--ink` en vez de sobre `transparent`, la mancha sólo asoma por los
     bordes de la tarjeta, que es donde se quería. */
  background: color-mix(in srgb, var(--bg) 10%, var(--ink));
  border-bottom: 0;              /* anula el filete naranja de `.is-dark a` */
  position: relative; z-index: 1;
}
/* El hover es el naranja de marca a pelo, no una mezcla: mezclado con `--ink`
   salía un granate apagado. Sobre `--accent` el texto va en blanco fijo
   (`--white`, no `--bg`): en tema oscuro `--bg` es casi negro y sobre naranja
   se queda en 3,4:1, que no llega. */
.ci-card.is-dark .ci-channel:hover { background: var(--accent); }
.ci-card.is-dark .ci-channel:hover .cc-val,
.ci-card.is-dark .ci-channel:hover .cc-label { color: var(--white); }
.ci-card.is-dark .ci-channel:hover .cc-icon { background: var(--white); color: var(--accent); }
.ci-card.is-dark .ci-channel .cc-icon { background: var(--bg); color: var(--ink); }
.ci-card.is-dark .ci-channel .cc-label { color: color-mix(in srgb, var(--bg) 58%, transparent); }
.ci-card.is-dark .ci-channel .cc-val { color: var(--bg); }

/* Los tres iconos, misma casilla y mismo peso óptico. El de LinkedIn es macizo
   y los otros dos de trazo, así que va un punto más pequeño: a igual tamaño de
   caja, una forma llena pesa más que una de línea. */
.ci-channel .cc-icon svg { width: 19px; height: 19px; display: block; }
.ci-channel .cc-icon svg[viewBox="0 0 256 256"] { width: 16px; height: 16px; }

/* Sin rótulo, la tarjeta de canales no necesita el aire de arriba: son tres
   botones y nada más. */
.ci-card-canales { padding: 14px; }
/* Y sin la mancha naranja del `::before`: era la decoración de una tarjeta con
   titular, y aquí sólo hay tres botones. Con 14px de margen se le queda un
   sitio en el que no cabe, y lo que se ve es un manchón en la esquina. */
.ci-card.is-dark.ci-card-canales::before { content: none; }

/* `.cc-val` global lleva `nowrap` + `text-overflow: ellipsis`, y en móvil el
   nombre de LinkedIn salía como «GRAFS — Marketing / DESA…». Una elipsis
   esconde contenido sin avisar y `altos.mjs` no la caza —sólo mide escritorio—,
   así que aquí se deja partir en dos renglones. A 1440 sigue cabiendo en uno. */
.ci-card-canales .cc-val { white-space: normal; overflow: visible; text-overflow: clip; }

/* Aro de foco del chip: la casilla es invisible, así que el aro lo lleva la
   etiqueta. Sin esto, marcar con el teclado se hace a ciegas. */
.cf-chip:has(input:focus-visible) {
  outline: 2px solid var(--accent); outline-offset: 2px;
  color: var(--ink); border-color: var(--ink);
}

/* Consentimientos. Casilla NATIVA a propósito: con `accent-color` se tiñe de
   naranja sola, y viene con el foco, el teclado y el estado de error del
   navegador ya puestos. Una casilla dibujada a mano habría que reconstruirlo
   todo, y es justo el campo donde no conviene equivocarse. */
.cf-consent { display: flex; flex-direction: column; gap: 12px; margin-top: 22px; }
.cf-check {
  display: flex; align-items: flex-start; gap: 10px;
  font-size: 13px; line-height: 1.5; color: var(--ink-soft);
  cursor: pointer;
}
.cf-check input {
  accent-color: var(--accent);
  width: 17px; height: 17px; flex: none;
  margin: 2px 0 0; cursor: pointer;
}
.cf-check a { color: var(--ink); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
.cf-check a:hover { color: var(--accent); }
.cf-check:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

/* Qué pasa después (3 pasos) */
.next-steps { padding: var(--sp-sec) 0; border-top: 1px solid var(--line); background: var(--bg-2); margin-top: 80px; }
.next-steps-head { text-align: center; max-width: 720px; margin: 0 auto 50px; }
.next-steps-head h2 { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-section); line-height: 1.1; margin: 14px 0 14px; }
.next-steps-grid {
  display: grid; grid-template-columns: repeat(3,1fr);
  gap: 24px; max-width: 1000px; margin: 0 auto;
  position: relative;
}
.next-steps-grid::before {
  content: ""; position: absolute;
  top: 44px; left: 14%; right: 14%;
  height: 2px;
  background: repeating-linear-gradient(90deg, var(--accent) 0 6px, transparent 6px 12px);
  z-index: 0;
}
.ns-card {
  position: relative; z-index: 1;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 30px 26px;
  text-align: center;
}
.ns-num {
  width: 56px; height: 56px; border-radius: 50%;
  background: var(--bg); border: 2px solid var(--accent);
  color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-serif); font-weight: 500; font-size: 22px;
  margin: -56px auto 18px;
  box-shadow: 0 10px 24px rgba(247,86,43,.25);
}
.ns-card h3 { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-h3); margin-bottom: 10px; }
.ns-card p { color: var(--ink-soft); font-size: var(--fs-body); line-height: 1.55; margin: 0; }
.ns-card .ns-time { display: inline-block; margin-top: 12px; font-size: 12px; font-weight: 700; letter-spacing: .04em; color: var(--accent-700); background: var(--accent-soft); padding: 4px 10px; border-radius: 999px; }

/* FAQ */
.faq-wrap { padding: var(--sp-sec) 0; border-top: 1px solid var(--line); background: var(--bg-2); }
.faq-head { text-align: center; max-width: 720px; margin: 0 auto 50px; }
.faq-list {
  max-width: 860px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 14px;
}
.faq-item {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 20px;
  overflow: hidden;
  transition: border-color .25s, box-shadow .25s, transform .25s;
}
.faq-item:hover { border-color: var(--accent); transform: translateY(-2px); box-shadow: 0 16px 32px rgba(22,19,15,.06); }
.faq-item.is-open {
  border-color: var(--accent);
  box-shadow: 0 24px 50px rgba(247,86,43,.10);
  transform: translateY(0);
}
.faq-q {
  width: 100%; text-align: left;
  display: flex; align-items: center; gap: 18px;
  padding: 22px 26px;
  background: transparent; border: 0;
  cursor: pointer;
  color: var(--ink);
  font-family: inherit;
}
.faq-num {
  font-family: var(--font-serif); font-weight: 500;
  font-size: 14px; color: var(--accent);
  line-height: 1;
  flex-shrink: 0;
  min-width: 28px;
  letter-spacing: .02em;
}
.faq-q-body { flex: 1; min-width: 0; }
.faq-cat {
  display: inline-block;
  font-size: 10.5px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--accent-700);
  background: var(--accent-soft);
  padding: 3px 9px; border-radius: 999px;
  margin-bottom: 8px;
}
.faq-q-text {
  display: block;
  font-family: var(--font-serif); font-weight: 500;
  font-size: 19px; line-height: 1.3;
  color: var(--ink);
}
.faq-toggle {
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--bg-2); color: var(--ink-soft);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 18px; font-weight: 400;
  flex-shrink: 0;
  transition: all .25s;
  line-height: 1;
}
.faq-item:hover .faq-toggle { background: var(--accent-soft); color: var(--accent-700); }
.faq-item.is-open .faq-toggle { background: var(--accent); color: #fff; transform: rotate(45deg); }
.faq-a {
  max-height: 0; overflow: hidden;
  transition: max-height .4s ease, padding .4s ease;
  padding: 0 26px 0 72px;
}
.faq-item.is-open .faq-a { max-height: 600px; padding: 0 26px 26px 72px; }
.faq-a p {
  color: var(--ink-soft);
  font-size: var(--fs-body); line-height: 1.7;
  margin: 0;
}

@media (max-width: 640px) {
  .faq-q { padding: 18px 18px; gap: 12px; }
  .faq-num { min-width: 22px; font-size: 13px; }
  .faq-q-text { font-size: 17px; }
  .faq-a, .faq-item.is-open .faq-a { padding-left: 50px; padding-right: 18px; }
}

@media (max-width: 900px) {
  .contact-grid { grid-template-columns: 1fr; gap: 30px; }
  /* ≥16px en campos de texto: por debajo, iOS hace zoom al enfocar */
  .cf-input, .cf-textarea, .cf-select { font-size: 16px; }
  .next-steps-grid { grid-template-columns: 1fr; gap: 50px; }
  .next-steps-grid::before { display: none; }
  .cf-row.cf-2col { grid-template-columns: 1fr; }
}

/* ============================================================
   BLOG · index + post hero
   ============================================================ */
.blog-intro { padding: 60px 0 30px; }
.blog-intro .container { max-width: var(--maxw); }  /* blog: intro a la izquierda, ancho estándar */
.blog-crumb {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-faint); margin-bottom: 24px;
}
.blog-crumb a { color: var(--ink-soft); text-decoration: none; font-weight: 600; }
.blog-crumb a:hover { color: var(--accent); }
.blog-crumb .sep { color: var(--ink-faint); }
.blog-crumb .here { color: var(--accent-700); font-weight: 700; }
.blog-crumb .crumb-home {
  display: inline-flex; align-items: center;
  color: var(--ink-soft);
  line-height: 1;
}
.blog-crumb .crumb-home:hover { color: var(--accent); }
.blog-crumb .crumb-home svg { display: block; }
.blog-intro h1 {
  font-family: var(--font-serif); font-weight: 500;
  font-size: var(--fs-hero);
  line-height: 1.02; letter-spacing: -.01em;
  margin-bottom: 20px;
}
.blog-intro .lead { max-width: 56ch; }

/* Featured post */
.blog-featured { padding: 30px 0 70px; }
.fp-card {
  display: grid; grid-template-columns: 1.05fr .95fr;
  gap: 0;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 24px;
  overflow: hidden;
  box-shadow: 0 30px 60px rgba(22,19,15,.10);
  transition: transform .3s, box-shadow .3s;
}
.fp-card:hover { transform: translateY(-4px); box-shadow: 0 40px 80px rgba(22,19,15,.14); }
.fp-img {
  position: relative;
  background-color: var(--ink);
  background-size: cover; background-position: center;
  min-height: 380px;
}
.fp-img::after {
  content: ""; position: absolute; inset: 0;
  background-image: radial-gradient(rgba(255,255,255,.18) 1.5px, transparent 1.6px);
  background-size: 14px 14px;
}
.fp-img .fp-badge {
  position: absolute; top: 22px; left: 22px;
  padding: 6px 12px; border-radius: 999px;
  background: var(--accent); color: #fff;
  font-size: 11px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  z-index: 1;
}
.fp-body { padding: 36px 40px; display: flex; flex-direction: column; justify-content: center; }
.fp-tags {
  display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px;
}
.fp-tags .fp-tag {
  font-size: 11px; font-weight: 700;
  padding: 4px 10px; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent-700);
  letter-spacing: .06em; text-transform: uppercase;
}
.fp-body h2 {
  font-family: var(--font-serif); font-weight: 500;
  font-size: var(--fs-section); line-height: 1.1;
  margin-bottom: 18px;
}
.fp-meta { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink-faint); margin-bottom: 22px; }
.fp-meta .dot { width: 4px; height: 4px; border-radius: 50%; background: var(--ink-faint); }
.fp-author { display: flex; align-items: center; gap: 12px; margin-bottom: 24px; }
.fp-avatar {
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--ink); color: var(--bg);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-serif); font-weight: 500; font-size: 18px;
}
.fp-author-name { font-weight: 700; font-size: 14px; color: var(--ink); }
.fp-author-role { font-size: 13px; color: var(--ink-soft); }
.fp-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.fp-actions .btn { padding: 10px 18px; }
.fp-actions .btn-ai {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--bg); color: var(--ink);
  border: 1px solid var(--line);
  padding: 10px 16px; border-radius: 999px;
  text-decoration: none; font-weight: 600; font-size: 14px;
}
.fp-actions .btn-ai:hover { border-color: var(--accent); color: var(--accent); }
.fp-actions .btn-ai .spark { color: var(--accent); }

/* Grid de posts */
/* Menos aire ARRIBA que abajo: la fila de filtros va justo debajo de la
   entradilla, como en la referencia. Con `--sp-sec` (hasta 110px) por los dos
   lados quedaba un banco vacío entre el titular y los filtros — se notaba
   porque la banda del destacado, que era lo que llenaba ese hueco, ya no está.
   El borde superior lo anula igualmente la regla global de «sin líneas
   separadoras» del final del archivo; se deja escrito por si esa se retira. */
.post-grid-wrap { padding: 40px 0 var(--sp-sec); border-top: 1px solid var(--line); background: var(--bg-2); }
/* Fila de filtros. Sin rótulo encima y sin píldoras: texto suelto, y sólo el
   activo se mete en una caja. `.post-grid-head` se queda definido aunque ya no
   lo use ninguna plantilla — lo usaba la cabecera con la h2 a la izquierda y
   los filtros a la derecha, que es lo que sustituye esto. */
.post-grid-head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 20px;
  margin-bottom: 40px; flex-wrap: wrap;
}
.post-grid-head h2 { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-section); line-height: 1.1; }

/* Centrada en los tres anchos, por decisión de Aitor del 11-sep. */
.post-filters { display: flex; justify-content: center; gap: 4px; flex-wrap: wrap; margin-bottom: 36px; }
.post-filters .pf-btn {
  padding: 8px 16px; border-radius: 10px;
  border: 1px solid transparent; background: transparent;
  color: var(--ink-soft); font-size: 14px; font-weight: 500;
  text-decoration: none; cursor: pointer;
  transition: color .2s, border-color .2s, background .2s;
}
.post-filters .pf-btn:hover { color: var(--ink); }
.post-filters .pf-btn.is-active {
  background: var(--bg); border-color: var(--line); color: var(--ink);
}

.post-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.post-card {
  background: var(--bg); border: 1px solid var(--line);
  border-radius: 18px; overflow: hidden;
  display: flex; flex-direction: column;
  transition: transform .25s, box-shadow .25s, border-color .25s;
  text-decoration: none; color: inherit;
}
.post-card:hover { transform: translateY(-4px); box-shadow: 0 24px 50px rgba(22,19,15,.10); border-color: var(--accent); }
.post-card .pc-img {
  aspect-ratio: 16/10;
  background-color: var(--ink);
  background-size: cover; background-position: center;
  position: relative;
}
.post-card .pc-img::after {
  content: ""; position: absolute; inset: 0;
  background-image: radial-gradient(rgba(255,255,255,.12) 1.2px, transparent 1.4px);
  background-size: 12px 12px;
}
.post-card .pc-body { padding: 22px; display: flex; flex-direction: column; flex: 1; }
.post-card .pc-tag { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--accent-700); margin-bottom: 10px; }
.post-card h3 { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-h3); line-height: 1.2; margin-bottom: 10px; }
.post-card .pc-excerpt { color: var(--ink-soft); font-size: var(--fs-body); line-height: 1.55; margin-bottom: 18px; flex: 1; }
.post-card .pc-meta {
  display: flex; align-items: center; justify-content: space-between;
  padding-top: 14px; border-top: 1px solid var(--line);
  font-size: 12px; color: var(--ink-faint);
}
/* `min-width: 0` para que el recorte de la descripción corta funcione: sin
   esto, un hijo de flex no baja de su contenido y la fila se ensancha en vez
   de recortar. */
.post-card .pc-author { display: flex; align-items: center; gap: 8px; min-width: 0; }
.post-card .pc-avatar {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--ink); color: var(--bg);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-serif); font-size: 11px; font-weight: 600;
  /* El retrato va encima de la inicial, como en el artículo: `relative` para
     anclarlo y `flex-shrink: 0` para que el círculo no se aplaste cuando el
     nombre es largo. Sin `overflow: hidden`, que es lo que dentaba el canto. */
  position: relative; flex-shrink: 0;
}
.post-card .pc-avatar img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; border-radius: 50%;
  display: block; margin: 0;
  background: var(--ink);
}


/* ---- Las dos variantes de tarjeta de la rejilla -------------------------
   La ALTA ocupa la columna izquierda de dos filas y es la única con imagen y
   con entradilla; las PLANAS son sólo rótulo, titular y firma. El reparto lo
   hace `grid-row: span 2`, no una altura fija: así la fila mide lo que midan
   las dos tarjetas de al lado y nunca se corta ningún titular.
   ---------------------------------------------------------------------- */
.post-card.pc-alto { grid-row: span 2; }
/* La imagen de la alta no lleva proporción fija: se come el hueco que dejen el
   titular y la firma, que es lo que la mantiene a la altura de las dos de al
   lado. El mínimo evita que se quede en una raya cuando el titular es largo. */
.post-card.pc-alto .pc-img { aspect-ratio: auto; flex: 1; min-height: 200px; }
/* El titular de la alta NO crece: en la referencia los dos tamaños son el
   mismo, y lo que distingue a la tarjeta es la imagen y el hueco que ocupa.
   La escala del sitio sólo tiene hero/section/h3, y section (40px) aquí
   aplasta a las de al lado. */

/* La plana no tiene entradilla, así que hace falta algo que empuje la firma
   abajo: sin esto, titular y firma quedan pegados y las tarjetas de una misma
   fila dejan de alinearse entre sí. */
.post-card.pc-plano .pc-body { min-height: 210px; }
.post-card.pc-plano h3 { margin-bottom: 0; }
.post-card.pc-plano .pc-meta { margin-top: auto; }

.post-card .pc-author-txt { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.post-card .pc-author-name { color: var(--ink); font-weight: 600; }
/* La descripción corta se escribe para la cabecera del artículo, donde hay un
   renglón entero; aquí cae en una tarjeta estrecha. Se queda en una línea y se
   recorta: si se dejara envolver, la firma crecería a tres renglones y las
   tarjetas de una misma fila dejarían de alinearse por abajo. */
.post-card .pc-author-role {
  color: var(--ink-faint); font-size: 11px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ---- Paginación --------------------------------------------------------- */
.post-pager {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; flex-wrap: wrap; margin-top: 44px;
}
.pager-nums { display: flex; align-items: center; gap: 4px; }
.pager-nums .page-numbers {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 36px; height: 36px; padding: 0 10px;
  border-radius: 10px; border: 1px solid transparent;
  color: var(--ink-soft); font-size: 14px; text-decoration: none;
  transition: color .2s, border-color .2s, background .2s;
}
.pager-nums .page-numbers:hover { color: var(--ink); }
.pager-nums .page-numbers.current {
  background: var(--bg); border-color: var(--line); color: var(--ink); font-weight: 600;
}
.pager-nums .page-numbers.dots { border: 0; background: none; color: var(--ink-faint); }
.pager-next {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 9px 20px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--bg);
  color: var(--ink); font-size: 14px; font-weight: 500; text-decoration: none;
  transition: border-color .2s, color .2s;
}
.pager-next:hover { border-color: var(--ink); }
.pager-next.is-off { color: var(--ink-faint); border-color: var(--line); opacity: .5; }

/* ============================================================
   BLOG · single post (artículo abierto)
   ============================================================ */
/* La cabecera del artículo lleva la retícula de puntos de la home, y se apaga
   con un degradado que muere justo en el divisor —el borde inferior de
   .post-meta-bar, que es el final de la cabecera—. Mismo montaje que el CTA de
   las páginas de servicio: el lienzo dentro de la sección, el contenido por
   encima en z-index 2 (sin eso el titular sale lavado) y el degradado en
   medio, en z-index 1.
   `overflow: hidden` es lo que recorta el lienzo a la caja; sin él, la
   retícula se sale por abajo y pisa el cuerpo del artículo. */
.post-hero { padding: 50px 0 0; position: relative; overflow: hidden; background: var(--bg); }
/* Ancho estándar del sitio, el mismo que la cabecera del listado: el artículo
   abre alineado con /blog/ y no metido 230px hacia dentro. Los 980px que había
   eran medida de lectura, y la cabecera no es texto de lectura — el cuerpo sí,
   y ese se queda en 720. En tablet y móvil no cambia nada: ahí ya iba de lado
   a lado, con los 24px de aire del contenedor. */
.post-hero .container { max-width: var(--maxw); }

/* La geometría de la columna derecha vive en dos variables porque la usan DOS
   sitios que no se tocan entre sí —el padding de la cabecera y la rejilla del
   cuerpo—, y si se escriben a mano acaban desincronizadas: cambiar una sin la
   otra descuadra el margen izquierdo y nadie lo ve hasta que lo mides.
   `--art-indice` son los 260px del índice MÁS el aire que se le deja a su
   derecha; el índice en sí lo topa `.post-toc`. */
:root {
  --art-toc:      300px;   /* ancho del índice */
  --art-aire:      40px;   /* aire a su derecha; lo comparten índice y botones */
  --art-medida:   720px;   /* medida de lectura del cuerpo */
  --art-desplace:  40px;   /* cuánto se corre el bloque hacia la izquierda */
  --art-indice: calc(var(--art-toc) + var(--art-aire));
}

/* EL MARGEN IZQUIERDO DE LA CABECERA CUADRA CON EL DEL CUERPO (sólo escritorio).
   El del cuerpo no es un número: lo reparte el centrado del texto dentro de la
   columna que queda a la izquierda del índice, así que cambia con el ancho de
   la ventana —206px a 1440, 286 a 1920— y no se puede copiar a mano.
   Se rehace la misma cuenta: el hueco interior del contenedor es
   `min(100%, --maxw) - 48` (los 48 son sus dos paddings), de ahí salen los 260
   del índice y los 720 del texto, y lo que sobra se parte en dos. Los 24 del
   final son el padding propio del contenedor, que este `padding-left`
   sustituye.
   El `100%` mide contra la SECCIÓN, no contra el contenedor, que es justo lo
   que hace falta: el contenedor ya viene topado por --maxw y centrado.
   Sólo de 1101 para arriba: por debajo no hay índice ni dos columnas, el texto
   ocupa todo el ancho y no hay nada que cuadrar. */
@media (min-width: 1101px) {
  .post-hero > .container {
    /* El `max()` es una red: en un escritorio estrecho la cuenta se queda en
       negativo —el cuerpo ya llena su columna y no hay centrado que corregir—
       y sin él la cabecera se saldría por la izquierda. */
    padding-left: max(24px, calc((min(100%, var(--maxw)) - 48px - var(--art-indice) - var(--art-medida)) / 2 + 24px - var(--art-desplace)));
    /* Escuchar y Compartir acaban donde acaba el índice de abajo, no en el
       borde del contenedor: el mismo aire, escrito una sola vez. */
    padding-right: calc(24px + var(--art-aire));
  }
}

.post-dots { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.post-dots .hero-dots { display: block; width: 100%; height: 100%; }
.post-hero > .container { position: relative; z-index: 2; }
.post-hero::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0;
  height: clamp(70px, 11vh, 140px);
  background: linear-gradient(180deg, transparent 0%, var(--bg) 100%);
  pointer-events: none; z-index: 1;
}
.post-hero h1 {
  font-family: var(--font-serif); font-weight: 500;
  font-size: clamp(36px, 5vw, 64px);
  line-height: 1.05; letter-spacing: -.01em;
  margin: 18px 0 24px; max-width: 18ch;
}
.post-meta-bar {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 20px;
  padding: 24px 0 24px;
  border-bottom: 1px solid var(--line);
  margin-top: 16px;
}
.post-meta-line {
  display: flex; align-items: center; gap: 10px;
  font-size: 14px; color: var(--ink-soft);
}
.post-meta-line .dot { width: 4px; height: 4px; border-radius: 50%; background: var(--ink-faint); }
.post-author-card {
  display: flex; align-items: center; gap: 14px;
}
/* La foto se superpone a la inicial, que queda debajo como respaldo. Las dos
   comparten el círculo, así que la imagen va absoluta y recortada. */
.post-author-card .pa-avatar img,
.post-author-bio .pab-avatar img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; border-radius: 50%;
  display: block;
  /* `margin: 0` NO es redundante: la caja de autor vive dentro de `.post-body`,
     y la regla de las imágenes del artículo les da 28px de aire arriba y abajo.
     Con `inset: 0`, ese margen empujaba el retrato 28px hacia abajo y dejaba
     una luna oscura asomando por encima del círculo. */
  margin: 0;
  /* Fondo propio, y no por capricho: una foto con transparencia —un PNG
     recortado, un logo— dejaría ver la inicial por debajo y saldrían las dos
     cosas encima. Con el fondo del círculo, la imagen tapa siempre. */
  background: var(--ink);
}
/* SIN `overflow: hidden` a propósito. El círculo se recortaba DOS veces —el
   contenedor con overflow y la imagen con su propio radio— y ese doble recorte
   es lo que dejaba el borde dentado, en sierra. Con el radio sólo en la imagen,
   el navegador lo dibuja con suavizado y el canto sale limpio. Nada se sale de
   la caja: dentro no hay más que la inicial, que va centrada. */
.post-author-card .pa-avatar,
.post-author-bio .pab-avatar { position: relative; }

.post-author-card .pa-avatar {
  width: 48px; height: 48px; border-radius: 50%;
  background: var(--ink); color: var(--bg);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-serif); font-weight: 500; font-size: 20px;
  flex-shrink: 0;
}
.post-author-card .pa-name { font-weight: 700; font-size: 14px; color: var(--ink); }
/* La descripción corta va pegada al nombre, detrás de una coma, y en el peso y
   el color del texto secundario: el nombre manda, el oficio acompaña. La regla
   ya existía sin usarse; ahora es un `span` dentro de `.pa-name`, así que hay
   que devolverle el peso normal, que lo hereda en negrita. */
.post-author-card .pa-role { font-size: 13px; color: var(--ink-soft); font-weight: 400; }
.post-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.post-actions .pa-btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 18px; border-radius: 999px;
  background: var(--bg); color: var(--ink);
  border: 1px solid var(--line); text-decoration: none;
  font-weight: 600; font-size: 14px;
  font-family: inherit;
  transition: all .2s; cursor: pointer;
  white-space: nowrap;
  line-height: 1.2;
}
.post-actions .pa-btn:hover { border-color: var(--accent); color: var(--accent); }
.post-actions .pa-btn .spark { color: var(--accent); display: inline-flex; align-items: center; }
.post-actions .pa-btn .spark svg { width: 14px; height: 14px; }
.post-actions .pa-btn .caret { color: var(--ink-faint); font-size: 11px; }
.post-actions .pa-btn .pa-time {
  font-size: 12px; font-weight: 600;
  color: var(--ink-soft);
  padding-left: 8px; margin-left: 2px;
  border-left: 1px solid var(--line);
}
.post-actions .pa-btn.is-playing { border-color: var(--accent); color: var(--accent); }
.post-actions .pa-btn.is-playing .spark { animation: pa-pulse 1.4s ease-in-out infinite; }
@keyframes pa-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .4; }
}

/* Botón "Escuchar artículo" */
.post-listen {
  display: inline-flex; align-items: center; gap: 14px;
  padding: 9px 22px 9px 9px;
  border-radius: 999px;
  background: linear-gradient(90deg, rgba(247,86,43,.06), rgba(247,86,43,.02));
  border: 1px solid var(--line);
  margin: 36px auto 0;
  cursor: pointer; user-select: none;
  transition: transform .2s, box-shadow .2s, border-color .2s;
  font-family: inherit;
  text-align: left;
}
.post-listen-wrap { display: flex; justify-content: center; }
.post-listen:hover { transform: translateY(-2px); box-shadow: 0 12px 24px rgba(247,86,43,.15); border-color: rgba(247,86,43,.3); }
.post-listen .pl-btn {
  width: 44px; height: 44px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-700));
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; flex-shrink: 0;
  box-shadow: 0 8px 18px rgba(247,86,43,.35);
  position: relative;
}
.post-listen .pl-btn svg { width: 18px; height: 18px; }
.post-listen .pl-btn::after {
  content: "✦"; position: absolute; top: -2px; right: -2px;
  width: 15px; height: 15px; border-radius: 50%;
  background: #fff; color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-size: 8px;
  box-shadow: 0 2px 5px rgba(247,86,43,.25);
}
.post-listen .pl-info { display: flex; flex-direction: column; gap: 1px; }
.post-listen .pl-title {
  font-weight: 700; color: var(--accent-700);
  font-size: 14px; display: inline-flex; align-items: center; gap: 6px;
  line-height: 1.2;
}
.post-listen .pl-title .pl-help {
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent-700);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 8px; font-weight: 700;
}
.post-listen .pl-time { font-size: 12px; color: var(--ink-soft); line-height: 1.2; }

/* Resumen IA panel */
.post-summary {
  margin: 22px auto 0; max-width: 720px;
  background: var(--bg-2);
  border: 1px solid rgba(247,86,43,.3);
  border-radius: 18px;
  overflow: hidden;
  max-height: 0; opacity: 0;
  transition: max-height .4s ease, opacity .3s, margin .4s;
}
.post-summary.is-open { max-height: 1200px; opacity: 1; margin-top: 22px; }
.post-summary .ps-inner { padding: 24px 28px 26px; }
.post-summary .ps-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 14px;
}
.post-summary .ps-title {
  font-weight: 700; color: var(--accent-700); font-size: 13px;
  letter-spacing: .08em; text-transform: uppercase;
  display: inline-flex; align-items: center; gap: 8px;
}
.post-summary .ps-close {
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--bg); border: 1px solid var(--line);
  cursor: pointer; font-size: 14px; color: var(--ink-soft);
  display: inline-flex; align-items: center; justify-content: center;
  transition: all .2s;
}
.post-summary .ps-close:hover { border-color: var(--accent); color: var(--accent); }
.post-summary ul { margin: 0; padding-left: 24px; font-size: 15px; line-height: 1.65; color: var(--ink); }
.post-summary ul li { margin-bottom: 8px; }
.post-summary ul li::marker { color: var(--accent); }
.post-summary .ps-foot {
  font-size: 11px; color: var(--ink-faint); margin-top: 16px;
  padding-top: 12px; border-top: 1px dashed var(--line);
  letter-spacing: .04em;
}

/* Estados del botón listen */
.post-listen.is-playing .pl-btn { animation: pl-pulse 1.6s ease-in-out infinite; }
@keyframes pl-pulse {
  0%, 100% { box-shadow: 0 10px 24px rgba(247,86,43,.35); }
  50% { box-shadow: 0 10px 24px rgba(247,86,43,.55), 0 0 0 8px rgba(247,86,43,.12); }
}

/* Cover */
.post-cover {
  max-width: 1100px;
  margin: 40px auto 0;
  aspect-ratio: 16 / 8;
  border-radius: 24px;
  background-color: var(--ink);
  background-size: cover; background-position: center;
  position: relative;
  box-shadow: 0 40px 80px rgba(22,19,15,.18);
}
.post-cover::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background-image: radial-gradient(rgba(255,255,255,.15) 1.5px, transparent 1.6px);
  background-size: 16px 16px;
}

/* Body */
.post-body-wrap { padding: 60px 0 30px; }
.post-body { max-width: 720px; margin: 0 auto; min-width: 0; overflow-wrap: break-word; }

/* Una tabla puede ser más ancha que la columna de lectura —la de este artículo
   lo es— y la página NO desplaza en horizontal, así que lo que sobresale no se
   recorta con una barra: se pierde. En un móvil de 390 se perdían 150px de
   tabla sin que nada avisara. Se desliza dentro de su propia caja, que es lo
   único que puede desbordar en esta página.
   Y `margin-inline: 0` porque el navegador le pone 40px a cada lado a un
   `figure` por defecto: la tabla se quedaba con 262px de los 342 que hay.
   Ojo: el resto de la tabla sigue sin estilos propios en el tema. Esto arregla
   que se pierda contenido, no cómo se ve. */
.post-body figure.wp-block-table { max-width: 100%; overflow-x: auto; margin-inline: 0; }

/* Texto justificado, con partición de palabras. `hyphens` no es opcional aquí:
   justificar sin partir abre ríos de espacio en blanco entre palabras, y en
   castellano —con palabras largas— se nota el doble. El navegador parte por
   sílabas porque el documento declara lang="es".
   El `>` es lo que mantiene fuera a la caja de autor, que también lleva un
   párrafo pero no es texto del artículo; el contenido de WordPress sí cuelga
   directo de .post-body. */
.post-body > p,
.post-body > ul li,
.post-body > ol li {
  text-align: justify;
  hyphens: auto;
}

/* Layout grid con TOC.
   El ÍNDICE se queda clavado a la derecha, en el mismo margen que el botón de
   Compartir de la cabecera. El TEXTO se centra en todo lo que queda a su
   izquierda, así que tiene el mismo aire a un lado que al otro (11-sep,
   petición de Aitor).
   El `gap` es 0 A PROPÓSITO y no es un descuido: con un canal declarado, ese
   canal se suma al aire de la derecha y los dos márgenes del texto dejan de
   medir lo mismo. Aquí el hueco lo reparte el centrado del propio cuerpo.
   Y el cuerpo NO crece: 720px es medida de lectura —unos 85 caracteres por
   línea, ya en el límite alto—; ensancharlo haría el texto más incómodo, no
   más generoso. */
.post-body-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--art-indice);
  gap: 0;
  align-items: start;
}
/* Centrado en su columna y luego corrido a la izquierda. El `max(0px, …)`
   evita que, en un escritorio estrecho donde el texto ya llena la columna, el
   desplazamiento lo empuje fuera por la izquierda. */
.post-body-grid > .post-body {
  max-width: var(--art-medida);
  margin-left: max(0px, calc((100% - var(--art-medida)) / 2 - var(--art-desplace)));
  margin-right: auto;
}

/* TOC */
.post-toc {
  position: sticky;
  top: 100px;
  align-self: start;
  width: 100%;
  /* El índice mide --art-toc dentro de una columna de --art-indice: la
     diferencia es el aire que le queda a su derecha, para que no vaya pegado
     al borde. */
  max-width: var(--art-toc);
}
.post-toc-eyebrow {
  display: inline-block;
  font-size: 11px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--accent-700);
  padding: 4px 10px; border-radius: 999px;
  background: var(--accent-soft);
  margin-bottom: 18px;
  margin-left: 22px;
}
.post-toc-title {
  font-family: var(--font-serif); font-weight: 500;
  font-size: 22px; line-height: 1.15; color: var(--ink);
  margin: 0 0 14px;
  padding-left: 12px;   /* alineado con el texto de los epígrafes */
}

/* FUERA EL CARRIL. El índice llevaba una línea vertical a la izquierda y el
   epígrafe activo se marcaba pintando de naranja su tramo. Sin carril no hay
   tramo que pintar, así que el activo pasa a ser una pastilla —el mismo
   recurso de la referencia, que lo marca con una tarjeta— usando el tono de
   sección del sitio.
   Y MÁS COMPACTO: 15px/1.5 con 10px de aire arriba y abajo daba 65px por
   epígrafe de dos líneas; 14px/1.4 con 7px da 46. Con diez epígrafes son casi
   200px menos de índice. */
.post-toc-list {
  list-style: none; padding: 0; margin: 0;
  max-height: calc(100vh - 220px);
  overflow-y: auto;
  display: flex; flex-direction: column;
  position: relative;
  /* Se desliza, pero SIN barra: las tres declaraciones hacen falta porque cada
     motor la esconde por su lado. */
  scrollbar-width: none;         /* Firefox */
  -ms-overflow-style: none;      /* Edge viejo */
}
.post-toc-list::-webkit-scrollbar { width: 0; height: 0; }
.post-toc-list li a {
  display: block;
  padding: 7px 12px;
  border-radius: 10px;
  font-size: 14px; line-height: 1.4;
  color: var(--ink-soft);
  text-decoration: none;
  transition: color .2s, background .2s;
}
.post-toc-list li a:hover { color: var(--ink); }
.post-toc-list li a.is-active {
  color: var(--ink);
  font-weight: 600;
  background: var(--bg-2);
}

/* JERARQUÍA. Los epígrafes de segundo nivel (h3) van sangrados y con una
   flecha naranja que baja y gira a la derecha: dice de un vistazo que ese
   apartado cuelga del de arriba.
   La flecha se dibuja con dos pseudoelementos y no con un carácter (↳) ni con
   un icono: el carácter no está en Poppins y caería a una tipografía de
   respaldo, con otro tamaño y otro grosor en cada sistema. El codo es una caja
   con dos bordes; la punta, un cuadrado con otros dos, girado 45 grados. */
/* Los de primer nivel en negrita: con 42 epígrafes, el sangrado y la flecha
   solos no bastan para separar de un vistazo los capítulos de sus apartados.
   El activo NO sube de peso —ya lo marcan la pastilla y el color de la
   tinta—, así que un h2 activo pesa lo mismo que uno cualquiera y no da un
   salto al pasar por él. */
.post-toc-list li.nivel-2 > a { font-weight: 600; }

.post-toc-list li.nivel-3 > a {
  padding-left: 34px;
  font-size: 13px;
  position: relative;
}
.post-toc-list li.nivel-3 > a::before {
  content: ''; position: absolute;
  left: 14px; top: 9px;
  width: 8px; height: 7px;
  border-left: 1.5px solid var(--accent);
  border-bottom: 1.5px solid var(--accent);
  border-bottom-left-radius: 2px;
}
.post-toc-list li.nivel-3 > a::after {
  content: ''; position: absolute;
  left: 19px; top: 12.5px;
  width: 4px; height: 4px;
  border-top: 1.5px solid var(--accent);
  border-right: 1.5px solid var(--accent);
  transform: rotate(45deg);
}

/* Sin barra no hay forma de saber que el índice sigue por debajo. Lo dice un
   degradado al pie, y SÓLO cuando de verdad queda contenido por ver: puesto
   siempre, en un índice corto lavaría el último epígrafe sin motivo. La clase
   la pone y la quita el JS de la plantilla. */
.post-toc.hay-mas::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0;
  height: 44px; pointer-events: none;
  background: linear-gradient(180deg, transparent 0%, var(--bg) 100%);
}

@media (max-width: 1100px) {
  .post-body-grid { grid-template-columns: 1fr; gap: 0; }
  .post-toc { display: none; }
  /* El centrado del cuerpo es SÓLO de la versión de dos columnas. En una
     columna no hay nada que centrar —el texto ya ocupa el ancho— y además el
     `margin-inline: auto` hace daño: un elemento de rejilla con márgenes auto
     deja de estirarse y pasa a medir por su contenido, con suelo en el mínimo.
     Aquí ese mínimo son 524px (lo marca la barra de compartir, que va en una
     fila que no parte), así que en un móvil de 390 el cuerpo salía de 524 y el
     texto se cortaba por la derecha sin dar ningún error: la página no llega
     ni a desbordar, simplemente recorta. */
  .post-body-grid > .post-body { max-width: none; margin-inline: 0; }
}
.post-body .post-lead {
  font-family: var(--font-serif); font-weight: 400;
  font-size: 22px; line-height: 1.5; color: var(--ink);
  margin-bottom: 36px;
  padding-bottom: 30px;
  border-bottom: 1px solid var(--line);
}
.post-body p { font-size: var(--fs-body); line-height: 1.75; color: var(--ink); margin-bottom: 22px; }
.post-body h2 { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-section); line-height: 1.15; margin: 50px 0 18px; }
.post-body h3 { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-h3); line-height: 1.2; margin: 36px 0 14px; }
.post-body ul, .post-body ol { margin: 0 0 22px 24px; font-size: 17px; line-height: 1.7; color: var(--ink); }
.post-body ul li, .post-body ol li { margin-bottom: 10px; }
.post-body ul li::marker { color: var(--accent); }
.post-body blockquote {
  border-left: 4px solid var(--accent);
  padding: 8px 0 8px 26px; margin: 36px 0;
  font-family: var(--font-serif); font-style: italic;
  font-size: 24px; line-height: 1.4; color: var(--ink);
}
.post-body code { background: var(--bg-2); padding: 2px 7px; border-radius: 4px; font-size: 0.92em; font-family: ui-monospace, monospace; color: var(--accent-700); }
.post-body pre { background: var(--ink); color: var(--bg); padding: 22px 24px; border-radius: 14px; overflow-x: auto; font-size: 14px; line-height: 1.6; margin: 28px 0; }
.post-body pre code { background: transparent; padding: 0; color: var(--bg); }
.post-body a { color: var(--accent-700); text-decoration: underline; text-decoration-thickness: 1.5px; text-underline-offset: 3px; }
.post-body a:hover { color: var(--accent); }
.post-body img { max-width: 100%; border-radius: 14px; margin: 28px 0; }

/* Highlight box */
.post-callout {
  background: var(--accent-soft);
  border-left: 4px solid var(--accent);
  border-radius: 12px;
  padding: 22px 26px; margin: 30px 0;
}
.post-callout .pc-label {
  font-size: 11px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent-700);
  margin-bottom: 6px;
}
.post-callout p { font-size: 16px; margin: 0; color: var(--ink); }

/* Compartir flotante */
.post-share-bar {
  display: flex; align-items: center; gap: 14px;
  padding: 22px 0; margin: 50px 0 0;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  font-size: 13px; color: var(--ink-soft);
}
.post-share-bar .ps-label { font-weight: 700; color: var(--ink); }
.post-share-bar .ps-btn {
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--bg); border: 1px solid var(--line);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 14px; color: var(--ink); text-decoration: none;
  transition: all .2s;
}
.post-share-bar .ps-btn:hover { border-color: var(--accent); color: var(--accent); }

/* Author bio (al final) */
.post-author-bio {
  max-width: 720px; margin: 50px auto 0;
  padding: 30px 32px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 20px;
  display: flex; gap: 24px; align-items: center;
}
.post-author-bio .pab-avatar {
  width: 72px; height: 72px; border-radius: 50%;
  background: var(--ink); color: var(--bg);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-serif); font-weight: 500; font-size: 28px;
  flex-shrink: 0;
}
.post-author-bio h4 { font-family: var(--font-serif); font-weight: 500; font-size: 19px; margin-bottom: 2px; }
/* El oficio, entre el nombre y la biografía: más pequeño que el texto y en el
   color secundario, para que se lea como un subtítulo del nombre y no como el
   primer renglón de la biografía. */
.post-author-bio .pab-role {
  color: var(--ink-faint); font-size: 13px; line-height: 1.4;
  margin: 0 0 8px;
}
.post-author-bio p { color: var(--ink-soft); font-size: 14.5px; line-height: 1.55; margin: 0 0 8px; }
/* Los enlaces de la firma pasan de palabras a iconos (12-sep). Mismo botón
   redondo que la barra de compartir de justo encima, para que las dos filas de
   la misma zona no se contradigan. Llevan `aria-label` y `title` porque, sin
   la palabra al lado, el icono es lo único que hay. */
.post-author-bio .pab-links { display: flex; gap: 10px; margin-top: 12px; }
.post-author-bio .pab-links a {
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--bg); border: 1px solid var(--line);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--ink); text-decoration: none;
  transition: color .2s, border-color .2s;
}
.post-author-bio .pab-links a:hover { color: var(--accent); border-color: var(--accent); }
.post-author-bio .pab-links svg { width: 17px; height: 17px; display: block; fill: currentColor; }

/* Related posts */
.post-related { padding: 60px 0 80px; background: var(--bg-2); border-top: 1px solid var(--line); margin-top: 60px; }
.post-related h3 { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-section); margin-bottom: 30px; }

@media (max-width: 900px) {
  .post-meta-bar { flex-direction: column; align-items: flex-start; }
  .post-author-bio { flex-direction: column; text-align: center; }
}

/* Newsletter */
.newsletter {
  padding: var(--sp-sec) 0; border-top: 1px solid var(--line);
}
.newsletter .container {
  display: grid; grid-template-columns: 1.2fr 1fr; gap: 50px; align-items: center;
  background: var(--ink); color: var(--bg);
  border-radius: 24px; padding: 50px 50px;
  position: relative; overflow: hidden;
}
.newsletter .container::before {
  content: ""; position: absolute; right: -50px; bottom: -50px;
  width: 300px; height: 300px; border-radius: 50%;
  background: radial-gradient(circle, rgba(247,86,43,.35), transparent 70%);
}
.newsletter h2 { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-section); line-height: 1.1; margin-bottom: 12px; position: relative; z-index: 1; }
.newsletter p { color: rgba(250,250,250,.7); position: relative; z-index: 1; }
.newsletter form {
  display: flex; gap: 10px; flex-wrap: wrap; position: relative; z-index: 1;
}
.newsletter input[type="email"] {
  flex: 1; min-width: 200px;
  padding: 14px 18px; border-radius: 999px;
  border: 1px solid rgba(255,255,255,.15);
  background: rgba(255,255,255,.06); color: var(--bg);
  font-size: 14px; font-family: inherit;
}
.newsletter input[type="email"]::placeholder { color: rgba(250,250,250,.5); }
.newsletter button {
  padding: 13px 22px; border-radius: 999px;
  border: 0; background: var(--accent); color: #fff;
  font-weight: 600; font-size: 14px; cursor: pointer;
  transition: background .2s;
}
.newsletter button:hover { background: var(--accent-700); }

/* Paso intermedio: con dos columnas la tarjeta alta sigue teniendo sentido
   —ocupa la izquierda de dos filas y a su lado caben dos— y no hace falta
   tocar el `span 2`. */
@media (max-width: 1180px) {
  .post-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 900px) {
  .fp-card { grid-template-columns: 1fr; }
  .fp-img { min-height: 240px; }
  .fp-body { padding: 28px 24px; }
  .newsletter .container { grid-template-columns: 1fr; padding: 36px 28px; }
}

/* La rejilla aguanta DOS columnas hasta bien entrado el tablet, y por eso su
   corte no va con el resto (que estaba en 900). A 810 —el iPad que captura
   `shots`— una sola columna deja las tarjetas a todo lo ancho y, sobre todo,
   la imagen de la alta pasa a medir 16/10 de 760px: medio metro de foto para
   un titular de dos líneas. */
@media (max-width: 680px) {
  .post-grid { grid-template-columns: 1fr; }
  /* En una sola columna NO hay dos filas que ocupar: si se deja el `span 2`,
     la tarjeta alta se queda con una fila vacía debajo y abre un hueco. */
  .post-card.pc-alto { grid-row: auto; }
  .post-card.pc-alto .pc-img { aspect-ratio: 16/10; flex: none; }
  .post-card.pc-plano .pc-body { min-height: 0; }
  .post-pager { margin-top: 32px; }
}

/* ============================================================
   PROCESS TIMELINE — zigzag vertical
   ============================================================ */
.process-wrap { padding: 70px 0 100px; }
.process-head { text-align: center; max-width: 720px; margin: 0 auto 70px; }
.process-head h1 { font-size: var(--fs-hero); line-height: 1.05; margin: 14px 0 18px; }
.process-head .lead { margin: 0 auto; }

.process-timeline {
  position: relative;
  max-width: 1000px;
  margin: 0 auto;
  padding: 30px 0;
}
.process-timeline::before {
  content: "";
  position: absolute; left: 50%; top: 0; bottom: 0;
  width: 2px; transform: translateX(-50%);
  background: linear-gradient(180deg, transparent 0%, var(--accent) 8%, var(--accent) 92%, transparent 100%);
  opacity: .5;
}
.pt-stage {
  position: relative;
  display: grid; grid-template-columns: 1fr 80px 1fr;
  gap: 36px; margin-bottom: 56px;
  align-items: start;
}
.pt-stage:last-child { margin-bottom: 0; }
.pt-marker {
  grid-column: 2;
  width: 72px; height: 72px; border-radius: 50%;
  background: var(--bg); border: 2px solid var(--accent);
  display: flex; align-items: center; justify-content: center;
  position: relative; z-index: 2;
  margin: 0 auto;
  box-shadow: 0 14px 30px rgba(247,86,43,.28);
}
.pt-marker .pt-num {
  font-family: var(--font-serif); font-weight: 500;
  font-size: 28px; color: var(--accent); line-height: 1;
}
.pt-marker::before {
  content: ""; position: absolute; inset: -8px;
  border-radius: 50%; border: 1px dashed var(--accent);
  opacity: .35;
}
.pt-card {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 26px 28px;
  box-shadow: 0 18px 40px rgba(22,19,15,.06);
  position: relative;
  transition: transform .25s, box-shadow .25s;
}
.pt-card:hover { transform: translateY(-3px); box-shadow: 0 24px 50px rgba(22,19,15,.10); }
.pt-stage.left  .pt-card { grid-column: 1; text-align: right; }
.pt-stage.right .pt-card { grid-column: 3; text-align: left; }
.pt-card::after {
  content: ""; position: absolute; top: 32px;
  width: 14px; height: 14px;
  background: var(--bg); border: 1px solid var(--line);
  transform: rotate(45deg);
}
.pt-stage.left  .pt-card::after { right: -8px; border-left: 0; border-bottom: 0; }
.pt-stage.right .pt-card::after { left:  -8px; border-right: 0; border-top:    0; }
.pt-week {
  display: inline-block;
  font-size: 11px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent-700);
  background: var(--accent-soft);
  padding: 4px 10px; border-radius: 6px;
  margin-bottom: 14px;
}
.pt-card h3 {
  font-family: var(--font-serif); font-weight: 500;
  font-size: var(--fs-h3); line-height: 1.15; margin-bottom: 10px;
  color: var(--ink);
}
.pt-card p { color: var(--ink-soft); font-size: 14.5px; line-height: 1.6; margin-bottom: 16px; }
.pt-card ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.pt-stage.left  .pt-card ul { align-items: flex-end; }
.pt-card ul li {
  position: relative; padding-left: 22px;
  font-size: 14px; color: var(--ink); line-height: 1.45;
}
.pt-stage.left  .pt-card ul li { padding-left: 0; padding-right: 22px; }
.pt-card ul li::before {
  content: "✓"; position: absolute; top: 0;
  color: var(--accent); font-weight: 700;
}
.pt-stage.left  .pt-card ul li::before { right: 0; left: auto; }
.pt-stage.right .pt-card ul li::before { left: 0; }

@media (max-width: 900px) {
  .process-timeline::before { left: 32px; }
  .pt-stage { grid-template-columns: 64px 1fr; gap: 16px; }
  .pt-marker { grid-column: 1; width: 56px; height: 56px; }
  .pt-marker .pt-num { font-size: 22px; }
  .pt-stage.left .pt-card,
  .pt-stage.right .pt-card { grid-column: 2; text-align: left; }
  .pt-stage.left .pt-card::after,
  .pt-stage.right .pt-card::after { left: -8px; right: auto; border-right: 0; border-top: 0; }
  .pt-stage.left  .pt-card ul,
  .pt-stage.right .pt-card ul { align-items: flex-start; }
  .pt-stage.left  .pt-card ul li { padding-left: 22px; padding-right: 0; }
  .pt-stage.left  .pt-card ul li::before { left: 0; right: auto; }
}

/* ============================================================
   SPRINT CARD — qué entregas en cada ciclo
   ============================================================ */
.sprint-card {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 28px;
  box-shadow: 0 30px 60px rgba(22,19,15,.10);
  max-width: 460px; width: 100%;
}
.sprint-card .sc-head {
  display: flex; align-items: center; justify-content: space-between;
  padding-bottom: 16px; margin-bottom: 16px;
  border-bottom: 1px dashed var(--line);
}
.sprint-card .sc-head .sc-title { font-family: var(--font-serif); font-weight: 500; font-size: 19px; }
.sprint-card .sc-head .sc-day {
  font-size: 12px; padding: 4px 10px; border-radius: 999px;
  background: var(--ink); color: var(--bg);
  font-weight: 600; letter-spacing: .04em;
}
.sprint-card .sc-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.sprint-card .sc-item {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 14px; background: var(--bg-2);
  border: 1px solid var(--line); border-radius: 10px;
  font-size: 14px; color: var(--ink);
}
.sprint-card .sc-item .sc-tag {
  margin-left: auto; font-size: 10px; padding: 3px 8px; border-radius: 6px;
  background: var(--bg); color: var(--ink-faint);
  font-family: ui-monospace, monospace; border: 1px solid var(--line);
  letter-spacing: .04em;
}
.sprint-card .sc-item .sc-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent); flex-shrink: 0;
}
.sprint-card .sc-item.is-done .sc-dot { background: #6BB07F; }
.sprint-card .sc-item.is-todo .sc-dot { background: var(--ink-faint); }

/* ============================================================
   CASOS DE ÉXITO — portfolio
   ============================================================ */
.cases-wrap { padding: 70px 0 60px; }
.cases-intro { text-align: center; max-width: 720px; margin: 0 auto 50px; }
.cases-intro h1 { font-size: var(--fs-hero); line-height: 1.05; margin: 14px 0 18px; }
.cases-intro .lead { margin: 0 auto; }

.case-featured {
  display: grid; grid-template-columns: 1.05fr .95fr; gap: 48px;
  align-items: center;
  background: linear-gradient(135deg, var(--bg-2), var(--bg));
  border: 1px solid var(--line);
  border-radius: 24px;
  padding: 44px 44px 44px 44px;
  margin-bottom: 60px;
  overflow: hidden;
  position: relative;
}
.case-featured::before {
  content: ""; position: absolute; inset: 0;
  background-image: radial-gradient(var(--accent) 1.5px, transparent 1.6px);
  background-size: 14px 14px; opacity: .07;
  pointer-events: none;
}
.case-featured .cf-img {
  position: relative; z-index: 1;
  aspect-ratio: 4/3;
  border-radius: 18px;
  background-color: var(--ink);
  background-size: cover; background-position: center;
  box-shadow: 0 30px 60px rgba(22,19,15,.18);
}
.case-featured .cf-body { position: relative; z-index: 1; }
.case-featured .cf-pill {
  display: inline-block; padding: 5px 12px; border-radius: 999px;
  background: var(--accent); color: #fff; font-size: 11px;
  font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  margin-bottom: 14px;
}
.case-featured h2 { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-section); line-height: 1.1; margin-bottom: 16px; }
.case-featured .cf-desc { color: var(--ink-soft); font-size: 17px; line-height: 1.6; margin-bottom: 24px; }
.case-featured .cf-metrics { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-bottom: 26px; }
.case-featured .cf-metric { padding: 14px 16px; background: var(--bg); border: 1px solid var(--line); border-radius: 12px; }
.case-featured .cf-metric .cf-num { font-family: var(--font-serif); font-size: 28px; font-weight: 500; color: var(--accent); line-height: 1; margin-bottom: 4px; }
.case-featured .cf-metric .cf-label { font-size: 12px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: .04em; }
.case-featured .cf-services { display: flex; flex-wrap: wrap; gap: 8px; }
.case-featured .cf-service {
  font-size: 12px; padding: 5px 10px; border-radius: 8px;
  background: var(--bg); border: 1px solid var(--line);
  color: var(--ink-soft);
}

.case-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 28px; }
.case-card {
  background: var(--bg); border: 1px solid var(--line);
  border-radius: 20px; overflow: hidden;
  transition: transform .3s, box-shadow .3s, border-color .3s;
  display: flex; flex-direction: column;
}
.case-card:hover { transform: translateY(-4px); box-shadow: 0 24px 50px rgba(22,19,15,.10); border-color: var(--accent); }
.case-card .cc-img {
  aspect-ratio: 16/10;
  background-color: var(--ink);
  background-size: cover; background-position: center;
  position: relative;
}
.case-card .cc-img .cc-logo {
  position: absolute; top: 16px; left: 16px;
  padding: 6px 12px; background: rgba(255,255,255,.95); backdrop-filter: blur(8px);
  border-radius: 8px; font-weight: 700; font-size: 13px; color: var(--ink);
  font-family: var(--font-sans); letter-spacing: .03em;
}
.case-card .cc-body { padding: 26px; display: flex; flex-direction: column; flex: 1; }
.case-card .cc-tag { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--accent-700); margin-bottom: 10px; }
.case-card h3 { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-h3); line-height: 1.2; margin-bottom: 10px; }
.case-card .cc-desc { color: var(--ink-soft); font-size: 14.5px; line-height: 1.55; margin-bottom: 18px; flex: 1; }
.case-card .cc-metrics { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin-bottom: 18px; }
.case-card .cc-metric { padding: 10px 12px; background: var(--bg-2); border-radius: 10px; }
.case-card .cc-metric .cc-num { font-family: var(--font-serif); font-size: 22px; font-weight: 500; color: var(--accent); line-height: 1; }
.case-card .cc-metric .cc-label { font-size: 11px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: .04em; margin-top: 4px; }
.case-card .cc-foot { padding-top: 16px; border-top: 1px solid var(--line); display: flex; align-items: center; justify-content: space-between; font-size: 13px; }
.case-card .cc-services { color: var(--ink-faint); }
.case-card .cc-link { color: var(--ink); font-weight: 600; text-decoration: none; }
.case-card .cc-link:hover { color: var(--accent); }

/* Banda métricas globales */
.cases-stats {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 30px;
  padding: 50px 40px;
  background: var(--ink); color: var(--bg);
  border-radius: 24px;
  margin-top: 70px;
}
.cases-stats .cs-item { text-align: center; }
.cases-stats .cs-num { font-family: var(--font-serif); font-weight: 500; font-size: clamp(36px,4vw,54px); color: var(--accent); line-height: 1; margin-bottom: 8px; }
.cases-stats .cs-label { font-size: 13px; color: rgba(250,250,250,.65); letter-spacing: .04em; }

@media (max-width: 900px) {
  .case-featured { grid-template-columns: 1fr; padding: 30px; }
  .case-featured .cf-metrics { grid-template-columns: 1fr 1fr; }
  .case-grid { grid-template-columns: 1fr; }
  .cases-stats { grid-template-columns: 1fr 1fr; padding: 36px 24px; gap: 24px; }
}

/* Visual: tarjeta de syllabus / progreso de curso */
.fb-lessons {
  background: var(--bg); border: 1px solid var(--line);
  border-radius: 18px; padding: 24px; max-width: 420px; width: 100%;
  box-shadow: 0 30px 60px rgba(22,19,15,.12);
}
.fb-lessons h5 { font-family: var(--font-serif); font-weight: 500; font-size: 19px; margin: 0 0 6px; color: var(--ink); }
.fb-lessons .fl-sub { color: var(--ink-soft); font-size: 14px; margin-bottom: 18px; }
.fb-lessons .fl-bar { height: 6px; background: var(--bg-2); border-radius: 99px; overflow: hidden; margin-bottom: 22px; }
.fb-lessons .fl-bar > i { display: block; height: 100%; background: var(--accent); border-radius: inherit; }
.fb-lessons ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }
.fb-lessons li {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; background: var(--bg-2); border-radius: 10px;
  font-size: 14px; color: var(--ink);
}
.fb-lessons li .fl-check {
  width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent); color: #fff; font-size: 12px; font-weight: 700;
}
.fb-lessons li.is-pending { color: var(--ink-soft); }
.fb-lessons li.is-pending .fl-check { background: var(--bg); border: 1px solid var(--line); color: var(--ink-faint); }
.fb-lessons li .fl-dur { margin-left: auto; color: var(--ink-faint); font-size: 12px; font-variant-numeric: tabular-nums; }

@media (max-width: 900px) {
  .feat-block .container { grid-template-columns: 1fr; gap: 50px; }
  .feat-block.reverse .fb-text { order: 0; }
  .fb-visual { min-height: 480px; }
  .fb-stack { max-width: 320px; }
}

/* ============================================================
   GALERÍA DE MÓDULOS — grid de tarjetas
   ============================================================ */
.gallery-wrap { padding: var(--sp-sec) 0; border-top: 1px solid var(--line); background: var(--bg-2); }
.gallery-head { text-align: center; max-width: 720px; margin: 0 auto 50px; }
.gallery-head h1 { font-size: var(--fs-hero); margin: 14px 0 14px; }
.gallery-head h2 { font-size: var(--fs-section); margin: 14px 0 14px; }
/* utilidad: texto solo para lectores de pantalla (h1 de páginas sin titular visible) */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.gallery-head .lead { margin: 0 auto; }

.gallery-filters { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-bottom: 40px; }
.gallery-filters .gf-btn {
  padding: 8px 16px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--bg); color: var(--ink-soft); font-size: 14px; font-weight: 500;
  cursor: pointer; transition: all .2s;
}
.gallery-filters .gf-btn:hover { color: var(--ink); border-color: var(--ink); }
.gallery-filters .gf-btn.is-active { background: var(--ink); color: var(--bg); border-color: var(--ink); }

.gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.g-card {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 26px;
  display: flex; flex-direction: column;
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s;
}
.g-card:hover { transform: translateY(-4px); box-shadow: 0 24px 50px rgba(22,19,15,.08); border-color: var(--accent); }
.g-card .g-thumb {
  position: relative;
  height: 150px;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--bg-2), var(--bg));
  border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 22px;
  overflow: hidden;
}
.g-card .g-thumb::before {
  content: ""; position: absolute; inset: 0;
  background-image: radial-gradient(var(--accent) 1px, transparent 1.2px);
  background-size: 10px 10px;
  opacity: .15;
}
.g-card .g-ico {
  position: relative; z-index: 1;
  width: 60px; height: 60px; border-radius: 14px;
  background: var(--ink); color: var(--bg);
  display: flex; align-items: center; justify-content: center;
  font-size: 26px;
  box-shadow: 0 12px 30px rgba(22,19,15,.18);
}
.g-card .g-tag {
  display: inline-block; font-size: 11px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent-700); margin-bottom: 10px;
}
.g-card h3 {
  font-family: var(--font-serif); font-weight: 500;
  font-size: var(--fs-h3); line-height: 1.2; margin-bottom: 10px;
  color: var(--ink);
}
.g-card p { color: var(--ink-soft); font-size: var(--fs-body); line-height: 1.5; margin: 0; flex: 1; }
.g-card .g-foot {
  margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between;
  font-size: 13px;
}
.g-card .g-foot .g-status { color: var(--ink-faint); }
.g-card .g-foot .g-link {
  color: var(--ink); font-weight: 600; text-decoration: none;
  display: inline-flex; align-items: center; gap: 4px;
}
.g-card .g-foot .g-link:hover { color: var(--accent); }

@media (max-width: 1024px) {
  .gallery { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .gallery { grid-template-columns: 1fr; }
  .gallery-filters { justify-content: flex-start; overflow-x: auto; flex-wrap: nowrap; padding-bottom: 6px; }
  .gallery-filters .gf-btn { white-space: nowrap; }
}

@media (max-width: 900px) {
  .svc-hero .container,
  .feature .container { grid-template-columns: 1fr; gap: 36px; }
  .feature.reverse .feat-text { order: 0; }
  .principles-grid { grid-template-columns: 1fr; gap: 30px; }
  .stage { min-width: 140px; }
  .pipeline .arrow { transform: rotate(90deg); }
}

/* ==========================================================================
   QUIÉNES SOMOS — hero de-zoom + marquee + patrón
   ========================================================================== */
/* Fondo PLANO, no el degradado de héroe.  Aitor, 31-ago: el hero y el río
   tienen que ser el mismo blanco.  El degradado dejaba una costura visible
   justo en la junta, porque acaba en un azulado (#F1F5FB) y el río es
   #FAFAFA.  Se cambia SÓLO aquí: `--grad-hero` lo comparten otras seis
   piezas del sitio (la home, el CTA, los visuales de servicio). */
.about-hero { position: relative; height: 230vh; margin-top: -120px; background: var(--bg); color: var(--ink); }
.about-sticky { position: sticky; top: 0; height: 100vh; overflow: hidden; display: flex; align-items: center; justify-content: center; }

.about-top { position: absolute; top: 42px; left: 0; right: 0; text-align: center; z-index: 5; }
.about-top img { height: 24px; width: auto; margin: 0 auto 12px; display: block; }
.about-top .eyebrow { color: var(--ink-soft); margin: 0; }

/* Marquee (dos filas que se desplazan en sentidos opuestos) */
.about-marquee { position: absolute; left: 0; width: 100%; white-space: nowrap; overflow: hidden; z-index: 1; }
.about-marquee.row1 { top: 38%; }
.about-marquee.row2 { top: 50%; }
.about-marquee .track { display: inline-block; will-change: transform; line-height: 1; }
/* Cambiadas de sentido el 31-ago (Aitor): «Esto es Grafs» va hacia la DERECHA
   y la de abajo hacia la izquierda.  `marq-r` arranca en −50% y termina en 0,
   que es lo que hace que se vea avanzar hacia la derecha. */
.about-marquee.row1 .track { font-family: var(--font-serif); font-style: italic; font-size: 8.5vw; color: var(--accent); animation: marq-r 28s linear infinite; }
.about-marquee.row2 .track { font-family: var(--font-head); font-weight: 800; text-transform: uppercase; font-size: 8.5vw; color: var(--ink); opacity: .88; animation: marq-l 34s linear infinite; }
@keyframes marq-l { from { transform: translateX(0); }    to { transform: translateX(-50%); } }
@keyframes marq-r { from { transform: translateX(-50%); }  to { transform: translateX(0); } }

/* Foto a pantalla completa que se aleja (de-zoom) al hacer scroll, revelando el marquee */
.about-photo { position: relative; z-index: 2; margin: 0; width: 100vw; height: 100vh; transform: scale(var(--z, 1.05)); transform-origin: center; will-change: transform; }
.about-photo img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  /* móvil (vertical): el centro de la foto son las cortinas — se encuadra al lado derecho */
  filter: grayscale(1) contrast(1.05);   /* blanco y negro */
  border-radius: 3px;
}
@media (max-width: 900px) { .about-photo img { object-position: 78% center; } }

/* Intro tras el hero */
.about-intro { padding: var(--sp-sec) 0; }
.about-intro h2 { max-width: 18ch; margin: 14px 0 20px; }
.about-intro .lead { max-width: 680px; }

/* etiquetas grotescas (Manifiesto / Metodología / Por qué ahora) — fuente Inter, estilo tagline Orb */
.page-about .manifesto .eyebrow,
.page-about .method .eyebrow,
.page-about .stats .eyebrow { font-family: var(--font-label); }

/* Manifiesto: intro centrada en estilo cita (comilla izq. arriba, dcha. abajo, firma a la derecha) */
.manifesto .container { max-width: 900px; }
.manifesto .eyebrow { text-align: center; }
.manifesto h2 { max-width: 820px; margin: 16px auto 48px; text-align: center; }
/* divisor full-width que separa secciones (Manifiesto / Metodología) */
.section-div { width: 100%; border: 0; border-top: 1px solid var(--line); margin: 0; }

/* ═══ MARQUESINA DE LOGOS (2026-08-31) ═════════════════════════════════════
   Puerto de grootstudio/logo-marquee (21st.dev), fuente aportado por Aitor.
   Números del original: hueco 42px, vuelta de 80s, altura de logo 16/20px,
   máscara al 25/75% y ancho máximo de 1280px (max-w-7xl).
   ═══════════════════════════════════════════════════════════════════════ */
.marq { padding: clamp(76px, 8vw, 118px) 0; overflow: hidden; }
.marq-rotulo { text-align: center; margin: 0 0 48px; }
/* Máscara del original: `to right, transparent, black 25%, black 75%,
   transparent`. Es MUCHO más ancha que un desvanecido de cortesía — se come
   media banda, y es lo que le da el aire. */
.marq-caja {
  max-width: 1280px; margin: 0 auto; padding: 16px 0; overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 25%, #000 75%, transparent);
          mask-image: linear-gradient(to right, transparent, #000 25%, #000 75%, transparent);
}
.marq-pista { display: flex; align-items: stretch; width: max-content; animation: marq-corre 80s linear infinite; }

/* CADA LOGO EN UNA CASILLA DEL MISMO TAMAÑO. Es lo que iguala los tamaños:
   los ficheros son de todo tipo —unos son sólo el símbolo (Obsidian, Klaviyo),
   otros llevan símbolo Y palabra (Visual Studio Code, NotebookLM, Google
   Antigravity)— y con una altura común los de palabra salían al triple de
   ancho y parecían enormes. Dentro de la casilla, `object-fit: contain` con
   tope de alto Y de ancho: el que es ancho se encoge hasta caber y baja de
   altura solo, que es justo lo que iguala el peso visual. Sin excepciones por
   fichero: se corrige sin tocar nada cuando entre un logo nuevo. */
.marq-hueco {
  flex: none; width: auto; min-width: 152px; height: 56px; margin-right: 40px;
  display: flex; align-items: center; justify-content: center;
}
/* `flex: none` en el LOGO, y es el arreglo de un fallo real: como hijo de un
   flex, la imagen encogía para caber en la casilla de 152px, y encoger a un
   <img> le cambia el ancho pero NO el alto.  Los cuatro rótulos más anchos
   salían aplastados: Antigravity −17%, Search Console −26%, NotebookLM −33%.
   Ahora la casilla se ensancha para el que lo necesita y ninguno se deforma. */
.marq-logo { flex: none; display: block; }
/* Del original: en modo oscuro los logos se aplastan a blanco. Se pierde el
   color, sí — pero casi todos traen el rótulo en NEGRO y sobre fondo oscuro
   desaparecerían. El color se ve en modo claro, que es donde vive. */
html[data-theme="dark"] .marq-logo { filter: brightness(0) invert(1); }
/* `reverse` en el original: la tira avanza hacia la DERECHA, no hacia la izquierda */
@keyframes marq-corre { from { transform: translateX(-50%); } to { transform: translateX(0); } }

/* ═══ INTEGRACIONES · TITULAR DE BOMBO (2026-08-31) ════════════════════════
   Referencia: `slot-headline`.  La última palabra del titular vive en una
   chapa y va pasando como el rodillo de una tragaperras.  Sustituye a la
   retícula de tarjetas, que gastaba 903px en enseñar once logos quietos.

   Lo único que se anima es un `transform` sobre la pista.  Ni la chapa ni el
   titular se mueven: si lo hicieran, la línea entera bailaría en cada paso.
   El bucle y sus tiempos, en el <script> de page-quienes-somos.php.
   ═══════════════════════════════════════════════════════════════════════ */
.slot { padding: var(--sp-sec) 0; }
.slot > .container { text-align: center; }
.slot .eyebrow { margin-bottom: 16px; }

.slot-tit {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  column-gap: .32em; row-gap: .22em;
  font-size: var(--fs-section); line-height: 1.1; letter-spacing: -.015em;
  margin: 0; color: var(--ink);
}

/* La chapa NO cambia de tamaño al cambiar la palabra: la ventana mide lo que
   la fila MÁS ANCHA, porque las diez están pintadas siempre.  Pintar sólo la
   actual haría que la chapa diera un respingo en cada paso. */
.slot-chapa {
  display: inline-flex; align-items: center;
  padding: .12em .34em; border-radius: .34em; line-height: 1;
  border: 1px solid var(--line);
  background: color-mix(in srgb, var(--ink) 4%, transparent);
}
/* 1,25em y no 1em: justo un poco más que la línea, para que la ventana no
   corte las colas de la «g» ni de la «y». */
.slot-ventana { display: block; overflow: hidden; height: 1.25em; }
.slot-pista   { display: flex; flex-direction: column; will-change: transform; }
/* A la IZQUIERDA, como el original.  Se probaron centradas —la chapa mide lo
   que «Microsoft Outlook», así que «Notion» dejaba un palmo de hueco— y Aitor
   las quiso a la izquierda: así el icono se queda quieto de un paso a otro y
   sólo cambia la palabra, que es lo que hace que se lea como un rodillo. */
.slot-fila {
  display: flex; align-items: center; gap: .3em;
  height: 1.25em; white-space: nowrap;
}
.slot-icono { flex: none; width: .78em; height: .78em; object-fit: contain; display: block; }
/* La marca de Notion es negra sobre blanco y en tema oscuro desaparecía.  Es
   la ÚNICA que lo necesita: las demás traen color propio, y Calendar y Sheets
   llevan su propio blanco dentro.  Invertida es la versión que la propia
   Notion usa en fondo oscuro, así que no es un apaño: es su otro lockup. */
html[data-theme="dark"] .slot-icono[src*="notion"] { filter: invert(1); }

/* La palabra de verdad, sólo para lectores de pantalla: la ventana enseña las
   diez a la vez y leerlas todas no dice nada. */
.slot-sr {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* Sin `max-width`: Aitor la quiere en UN renglón.  En móvil parte, claro. */
.slot-lead {
  margin: 24px auto 0;
  font-size: 18px; line-height: 1.7; color: var(--ink-soft);
}

@media (max-width: 600px) {
  .slot-lead { font-size: 17px; }
}

@media (prefers-reduced-motion: reduce) {
  .marq-pista { animation: none; }
}

/* ═══ MANIFIESTO · RÍO DE IMÁGENES (2026-08-31) ════════════════════════════
   Puerto fiel de ruixen.ui/image-stream-hero.  Dos carriles de tarjetas vienen
   desde muy detrás de la pantalla hacia el espectador.  La PERSPECTIVA sola
   hace lo que parecen dos animaciones: al crecer la Z, la tarjeta se agranda Y
   su x en pantalla se abre desde el punto de fuga, porque la proyección escala
   posición y tamaño por el mismo factor.

   Tres cosas dan la forma, y cada una arregla un defecto concreto:

   1. La profundidad se escribe como TAMAÑO APARENTE, en progresión geométrica:
      cada tarjeta es una razón constante más grande que la de detrás, todo el
      camino.  Repartir un rango de Z a intervalos iguales hace que las cercanas
      se desgarren unas de otras, porque ahí la proyección se dispara.
   2. Los carriles abren de golpe en el primer tramo y luego aguantan
      (`apertura` > 1).  Esa apertura cancela el crecimiento —todavía lento— del
      fondo, así que la cinta sale del centro como una banda plana, dobla una
      vez, y sólo entonces se va por la diagonal.  Unos carriles paralelos
      proyectan un cono recto, sin codo ninguno.
   3. Ningún extremo del bucle se ve nunca.  Una tarjeta muere con su borde
      interior pasado el 50cqw, fuera del marco.  Y NACE CRUZADA: `carril_nace`
      es negativo, así que la nueva empieza al otro lado y barre de vuelta por
      el centro.  Eso tapona la garganta —el eje queda cubierto en todo
      momento— y además la recién nacida cae detrás de otras que ya la tapan,
      así que no necesita fundido de entrada.  Naciendo en su propio lado se
      abre en el centro exacto un agujero que parpadea una vez por ciclo.

   Todo va en `cqw`, tanto por ciento del ancho del CONTENEDOR, así que el
   pasillo conserva sus proporciones a cualquier tamaño.  De paso es lo que
   arregla el móvil sin escribir un bloque aparte: allí se ensancha el
   contenedor (media query del final) y el pasillo entero crece con él.

   Los @keyframes NO están aquí: los calcula PHP muestreando la curva en
   page-quienes-somos.php, que es donde viven las constantes.
   ═══════════════════════════════════════════════════════════════════════ */
.rio {
  --rio-eje:   55%;     /* alto del eje del pasillo, y del punto de fuga */
  --rio-fuga:  30cqw;   /* fuerza de la proyección.  Menor = más gran angular */
  --rio-ancho: 18cqw;
  --rio-alto:  25cqw;
  /* Aire arriba y abajo.  Es el mismo respiro que separa cualquier otra
     sección del sitio, no un número propio de este bloque.  Las tarjetas de
     salida son ENORMES —46cqw de alto— y sin esto llegan pegadas al hero y a
     la franja de estadísticas. */
  --rio-aire:  var(--sp-sec);
  --rio-banda: min(52vw, 700px);   /* alto del PASILLO, sin contar el aire */
  position: relative; overflow: hidden;
  height: calc(var(--rio-banda) + 2 * var(--rio-aire));
  min-height: calc(420px + 2 * var(--rio-aire));
}

/* Esta es la caja contra la que miden los cqw.  Va centrada y puede ser MÁS
   ANCHA que la sección: entonces se ve la franja central de un pasillo más
   ancho que la pantalla, que es la palanca del móvil. */
.rio-escena {
  position: absolute; top: var(--rio-aire); bottom: var(--rio-aire); left: 50%;
  width: 100%; transform: translateX(-50%);
  overflow: hidden;   /* sin esto las tarjetas de salida se meten en el aire */
  container-type: inline-size;
  pointer-events: none;
}
/* La perspectiva va en un hijo a propósito: un elemento no puede consultar su
   propio tamaño, así que `30cqw` puesto en .rio-escena mediría contra el
   contenedor de más arriba, no contra ella. */
.rio-mundo   { position: absolute; inset: 0; perspective: var(--rio-fuga); perspective-origin: 50% var(--rio-eje); }
.rio-espacio { position: absolute; inset: 0; transform-style: preserve-3d; }

.rio-carta {
  position: absolute; left: 50%; top: var(--rio-eje);
  width: var(--rio-ancho); height: var(--rio-alto);
  margin: calc(var(--rio-alto) / -2) 0 0 calc(var(--rio-ancho) / -2);
  border-radius: .4cqw; overflow: hidden;
  backface-visibility: hidden;
  animation-duration: 18s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
.rio-carta img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rio-der { animation-name: rio-der; }
.rio-izq { animation-name: rio-izq; }

/* El texto va arriba y abajo, no en medio: el centro es la garganta del pasillo
   y ahí es donde se amontonan las tarjetas pequeñas. */
/* El texto va PEGADO A LA BANDA, no a la sección: si se estirara con el aire,
   el título se iría hacia el hero y la bajada hacia las estadísticas. */
.rio-tx {
  position: absolute; inset: var(--rio-aire) 0; z-index: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: space-between;
  text-align: center; padding: clamp(30px, 3.4vw, 48px) 24px;
  pointer-events: none;
}
/* `--fs-section`, el mismo que el resto de titulares de sección; antes iba con
   `--fs-hero` y cantaba al lado de los demás.  El `max-width` en ch es lo que
   lo parte en DOS renglones: sin él la frase entra en uno solo en pantalla
   ancha. */
.rio-tx h2 { font-size: var(--fs-section); line-height: 1.16; margin: 0; max-width: 30ch; color: var(--ink); }
/* Sin `max-width`: en un renglón (Aitor, 31-ago).  En móvil parte, claro. */
.rio-bajada { margin: 0; font-size: 18px; line-height: 1.6; color: var(--ink-soft); }

@media (max-width: 900px) {
  .rio { --rio-banda: min(110vw, 560px); }
  .rio-escena { width: 190%; }   /* el pasillo mide en cqw: para agrandarlo, se ensancha su caja */
}

@media (prefers-reduced-motion: reduce) {
  /* Pausar, no quitar.  Cada tarjeta ya está soltada a mitad de vuelo por su
     retardo negativo, así que se congela como un fotograma terminado.  Con
     `animation: none` se apilarían las 18 en el punto de fuga. */
  .rio-carta { animation-play-state: paused; }
}

/* ==========================================================================
   NOS PRESENTAMOS — fundadores (4 layouts de comparación · info GENÉRICA)
   Al elegir layout, dejar solo ese.  TODO: fotos reales, roles, frases, LinkedIn.
   ========================================================================== */
.founders { padding: var(--sp-sec) 0; }
.fdr-titulo { font-size: var(--fs-section); line-height: 1.1; margin: 0 0 clamp(28px, 3vw, 44px); text-align: center; }
.founders > .container > .eyebrow { text-align: center; margin-bottom: 8px; }
.fdr-tag { font-family: var(--font-mono); font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); text-align: center; margin: 64px 0 26px; }

/* piezas compartidas */
.fdr-name { font-family: var(--font-serif); font-size: 26px; margin: 16px 0 4px; }
.fdr-role { font-family: var(--font-mono); font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--accent); margin: 0 0 12px; }
.fdr-line { color: var(--ink-soft); font-size: 15px; line-height: 1.6; margin: 0 0 14px; }
.fdr-li { display: inline-flex; align-items: center; gap: 8px; font-family: var(--font-mono); font-size: 12.5px; color: var(--ink); border: 1px solid var(--line); border-radius: 999px; padding: 8px 15px; transition: border-color .2s, color .2s; }
.fdr-li:hover { border-color: var(--accent); color: var(--accent); }
.fdr-li svg { width: 15px; height: 15px; }

/* tarjetas flip (hover / focus) */
.fdrC { display: grid; grid-template-columns: 1fr 1fr; gap: 36px; max-width: 800px; margin: 0 auto; }
.flip { perspective: 1200px; aspect-ratio: 4 / 5; }
.flip-inner { position: relative; width: 100%; height: 100%; transition: transform .7s cubic-bezier(.16,1,.3,1); transform-style: preserve-3d; }
.flip:hover .flip-inner, .flip:focus-within .flip-inner { transform: rotateY(180deg); }
.flip-face { position: absolute; inset: 0; backface-visibility: hidden; border: 1px solid var(--line); border-radius: 18px; overflow: hidden; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 26px; background: var(--bg-2); }
.flip-front .ini { font-family: var(--font-serif); font-size: 72px; color: var(--ink-faint); }
.flip-back { transform: rotateY(180deg); }
.flip-back .m-chips { justify-content: center; margin-bottom: 16px; }

@media (max-width: 820px) {
  .fdrC { grid-template-columns: 1fr; gap: 40px; }
}

/* ==========================================================================
   ESTADÍSTICAS — "Por qué ahora": datos de mercado con fuente (count-up).
   Jerarquía: 3 hero + tira de secundarias + cierre humano.  Cifras con fuente real.
   ========================================================================== */
.stats { padding: 100px 0; }
.stats > .container > .eyebrow { text-align: center; margin-bottom: 8px; }
/* franja ticker entre cita y tarjetas de equipo (sin título, borde propio separa) */
.stats-band { padding: 40px 0; }
.st-num { font-family: var(--font-serif); font-weight: 500; line-height: 1; color: var(--ink); display: inline-flex; align-items: baseline; }
.st-num .sym { color: var(--accent); }
.st-num .st-unit { font-size: .5em; color: var(--accent); margin-left: 3px; }

.st-src { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .03em; color: var(--ink-faint); font-style: italic; margin: 0; }

/* etiqueta de comparación (provisional) */
.st-tag { font-family: var(--font-mono); font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); text-align: center; margin: 64px 0 24px; }

/* B · filas editoriales (número gigante) */
.stB { display: flex; flex-direction: column; }
.stB-row { display: grid; grid-template-columns: minmax(0, auto) 1fr; gap: 40px; align-items: center; padding: 26px 0; border-top: 1px solid var(--line); }
.stB-row:last-child { border-bottom: 1px solid var(--line); }
.stB-row .st-num { font-size: clamp(54px, 9vw, 104px); }
.stB-claim { color: var(--ink); font-size: 18px; line-height: 1.5; margin: 0 0 6px; }

/* ═══ ESTADÍSTICAS · CONTADORES (2026-08-31) ══════════════════════════════
   Sustituye a la cinta ticker.  Referencia: `counting-number` de cnippet.dev;
   sólo hay capturas, el código de 21st.dev va tras autenticación (403).

   Nació como banda OSCURA con la parábola de `hero-01` de fondo.  El 31-ago
   Aitor la quiso **blanca y sin patrón**, y con las letras y los colores que
   tenía la cinta: la Fraunces del número con el `%` en naranja, la explicación
   en `--ink-soft` y la fuente en la mono, pequeña y en cursiva.  Por eso la
   cifra reutiliza `.st-num` y `.sym` tal cual, en vez de copiarlas.
   ═══════════════════════════════════════════════════════════════════════ */
.cifras { position: relative; padding: var(--sp-sec) 0; }

.cifras-rejilla {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(12px, 1.2vw, 20px);
}

/* La tarjeta es ALTA a propósito: rótulo arriba del todo, cifra abajo.  Ese
   hueco en medio es lo que hace que el número pese; sin él se lee como tabla. */
.cifra {
  display: flex; flex-direction: column; justify-content: space-between;
  min-height: clamp(180px, 14.5vw, 220px);
  padding: clamp(20px, 1.9vw, 30px);
  border-radius: clamp(16px, 1.5vw, 24px);
  background: #FFFFFF;
  border: 1px solid var(--line);
  box-shadow: 0 4px 14px rgba(25,26,30,.04);
  transition: transform .28s cubic-bezier(.2,.7,.2,1), box-shadow .28s ease, border-color .28s ease;
}
/* Un gesto corto al pasar el cursor: se levanta y la sombra se abre.  Es una
   TRANSICIÓN, no una animación; aquí nunca se toca el reloj de una animación. */
.cifra:hover { transform: translateY(-5px); box-shadow: 0 16px 34px rgba(25,26,30,.09); border-color: var(--ink-faint); }
html[data-theme="dark"] .cifra:hover { box-shadow: 0 16px 34px rgba(0,0,0,.45); }
/* En oscuro una tarjeta blanca sería un foco: se va al gris de tarjeta. */
html[data-theme="dark"] .cifra { background: var(--bg-2); box-shadow: none; }

/* Las tres piezas, con las letras y los colores de la cinta. */
/* A la DERECHA y un punto más grande (Aitor, 31-ago).  Enfrentada al número,
   que va a la izquierda: los dos extremos de la tarjeta quedan ocupados. */
.cifra-fuente {
  margin: 0; font-family: var(--font-mono); font-style: italic;
  font-size: 14px; line-height: 1.3; color: var(--ink-faint); text-align: right;
}
.cifra-pie { display: block; }
.cifra-num {
  margin: 0 0 10px;
  font-size: clamp(38px, 3.9vw, 58px); line-height: 1;
  /* Sin esto el ancho del número baila mientras cuenta y la tarjeta tirita. */
  font-variant-numeric: tabular-nums;
}
.cifra-tx {
  margin: 0; font-size: clamp(14px, 1.1vw, 16px); line-height: 1.5;
  color: var(--ink-soft);
}

@media (prefers-reduced-motion: reduce) { .cifra, .cifra:hover { transition: none; transform: none; } }

@media (max-width: 1100px) { .cifras-rejilla { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  {
  .cifras-rejilla { grid-template-columns: 1fr; }
  .cifra { min-height: 0; }
  .cifra-pie { margin-top: 34px; }
}

/* D · ticker animado (cinta) */
.stD { overflow: hidden; border-block: 1px solid var(--line); padding: 16px 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
/* Sin `gap`, y no es capricho: la lista va DUPLICADA y el bucle salta a
   `-50%`.  Con 2N elementos hay 2N−1 huecos, así que la mitad del ancho cae
   medio hueco antes del punto donde la lista se repite —28px medidos— y el
   ticker pega un tirón en cada vuelta.  Con `margin-right` hay 2N márgenes y
   la mitad es exacta. */
.stD-track { display: inline-flex; white-space: nowrap; animation: st-marq 34s linear infinite; }
.stD:hover .stD-track { animation-play-state: paused; }
.stD-item { display: inline-flex; align-items: baseline; gap: 12px; margin-right: 56px; }
.stD-item .st-num { font-size: 32px; }
.stD-claim { color: var(--ink-soft); font-size: 14px; }
.stD-src { font-family: var(--font-mono); font-size: 11px; color: var(--ink-faint); font-style: italic; }
@keyframes st-marq { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .stD-track { animation: none; } }

@media (max-width: 820px) {
  .stB-row { grid-template-columns: 1fr; gap: 8px; }
}

/* ==========================================================================
   CITA FINAL — full-bleed B&W. Animación: parallax fuerte del fondo (ligado al
   scroll, en vivo) + aparición del texto (fade-up). SIN zoom de entrada.
   Parallax: data-amt (px recorrido) / data-dir (sentido).  Encuadre: --qb-pos.
   TODO foto: assets/img/charlie-munger.jpg
   ========================================================================== */
.quote-bleed {
  position: relative; overflow: hidden; background: #0d0e11;
  /* escritorio: full-bleed a lo ancho, formato grande (2026-07-08) */
  min-height: clamp(480px, 74vh, 720px);
  display: flex; align-items: center; justify-content: center;
}
.qb-media { position: absolute; inset: -80px 0; will-change: transform; }
/* móvil: tarjeta estrecha para que la foto se aprecie completa */
@media (max-width: 900px) {
  .quote-bleed { max-width: calc(100% - 40px); margin: 0 auto; border-radius: 20px;
    min-height: 0; aspect-ratio: 1200 / 900; padding: 24px 0; }
  .qb-media { inset: -26px 0; }
  .qb-content { padding: 0 22px; }
  .qb-content blockquote { font-size: 21px; margin-bottom: 10px; }
}
.qb-img {
  position: absolute; inset: 0;
  background: #15161a url('../img/charlie-munger.jpg') center var(--qb-pos, 30%) / cover no-repeat;
  filter: grayscale(1) contrast(1.05) brightness(.82);
  will-change: transform;   /* el zoom lo gobierna el JS según el scroll */
}
.qb-overlay { position: absolute; inset: 0; background: radial-gradient(ellipse at center, rgba(0,0,0,.22) 0%, rgba(0,0,0,.62) 100%); }
/* 1.180px y no 1.040: la cita se quedaba a 30px de caber en un renglón.  El
   bloque va a sangre, así que hay sitio de sobra. */
.qb-content {
  position: relative; z-index: 2; max-width: 1180px; padding: 0 28px; text-align: center; color: #fff;
  opacity: 0; transform: translateY(30px); transition: opacity 1s ease, transform 1s cubic-bezier(.16,1,.3,1);
}
.quote-bleed.in .qb-content { opacity: 1; transform: none; }
.qb-content blockquote {
  font-family: var(--font-serif); font-style: italic; font-weight: 500;
  font-size: clamp(26px, 3.6vw, 48px); line-height: 1.25; margin: 0 0 20px;
  text-shadow: 0 2px 30px rgba(0,0,0,.4);
}
.qb-content figcaption {
  font-family: var(--font-mono); font-size: 13px; letter-spacing: .16em; text-transform: uppercase; opacity: .82;
}
@media (prefers-reduced-motion: reduce) {
  .qb-img { transform: none; }
  .qb-content { transition: none; opacity: 1; transform: none; }
}
.manifesto-quote { margin: 0; }
/* comillas blocky (sans heavy); fila con line-height 0 → hueco simétrico arriba/abajo */
.manifesto-quote .q-row { line-height: 0; }
.manifesto-quote .q-top { text-align: left;  margin-bottom: 14px; }
.manifesto-quote .q-bot { text-align: right; margin-top: 14px; }
.manifesto-quote .q-mark {
  display: inline-block; font-family: var(--font-head); font-weight: 800;
  font-size: 84px; line-height: 1; color: var(--ink); opacity: .15; user-select: none;
}
.manifesto-quote .q-bot .q-mark { transform: rotate(180deg); }
.manifesto-quote p { text-align: justify; font-size: 18px; line-height: 1.85; color: var(--ink-soft); margin: 0 0 22px; }
.manifesto-quote p.strong { font-weight: 600; color: var(--ink); }
.manifesto-quote p:last-of-type { margin-bottom: 0; }
.manifesto-sign { text-align: right; font-family: var(--font-serif); font-style: italic; font-size: 19px; color: var(--ink); margin-top: 28px; }
@media (max-width: 640px) {
  .manifesto-quote p { text-align: left; }
  .manifesto h2 br { display: none; }
}

@media (max-width: 768px) {
  .about-marquee.row1 .track, .about-marquee.row2 .track { font-size: 12vw; }
  .about-hero { height: 160vh; }   /* efecto más corto en móvil: menos scroll para el mismo zoom */
}
@media (prefers-reduced-motion: reduce) {
  .about-marquee .track { animation: none; }
}

/* ==========================================================================
   FOOTER
   ========================================================================== */
.footer { padding: 70px 0 40px; border-top: 1px solid var(--line); }
.footer-grid { display: grid; grid-template-columns: repeat(4,1fr); gap: 40px; }
.footer h4 { font-family: var(--font-mono); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint); margin: 0 0 18px; font-weight: 500; }
.footer ul { list-style: none; padding: 0; margin: 0; }
.footer li { margin-bottom: 12px; }
.footer li a { font-size: 15px; color: var(--ink-soft); }
.footer li a:hover { color: var(--ink); }
.footer-bottom { display: flex; justify-content: space-between; align-items: center; margin-top: 56px; padding-top: 22px; border-top: 1px solid var(--line); font-size: 13.5px; color: var(--ink-faint); }

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media (max-width: 900px) {
  .cards-grid, .steps, .footer-grid { grid-template-columns: 1fr 1fr; }
  .statement-grid, .quote-grid { grid-template-columns: 1fr; }
  .statement-visual { min-height: 240px; }
}
@media (max-width: 640px) {
  .cards-grid, .steps, .footer-grid { grid-template-columns: 1fr; }
  .hero { padding: 60px 20px 50px; }
  /* método/pipeline: fases en columna con la flecha apuntando abajo */
  .pipeline { flex-direction: column; align-items: stretch; }
  .stage { min-width: 0; }
  .pipeline .arrow { width: auto; max-width: 100%; height: 34px; justify-content: center; transform: rotate(90deg); }
}

/* ==========================================================================
   FORMACIÓN IA — beneficios (grid con check) + método a 4 columnas
   ========================================================================== */
/* Diseño web · "Qué tienen nuestras webs" = bento (3 col; Desarrollo destacado 2×2) */
.web-bento { display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 154px; gap: 18px; margin-top: 44px; }
.web-bento .wb { background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--r); padding: 22px; display: flex; flex-direction: column; justify-content: space-between; transition: box-shadow .25s, transform .25s, border-color .25s; }
.web-bento .wb:hover { transform: translateY(-2px); box-shadow: 0 16px 32px rgba(22,19,15,.07); border-color: rgba(247,86,43,.4); }
.web-bento .wb .ic { color: var(--ink); }
.web-bento .wb .ic svg { width: 44px; height: 44px; display: block; }
.web-bento .wb p { margin: 0; font-size: var(--fs-body); line-height: 1.4; color: var(--ink); }
.web-bento .wb-feature { grid-column: span 2; grid-row: span 2; background: var(--accent-soft); border-color: transparent; padding: 30px; }
.web-bento .wb-feature .ic svg { width: 58px; height: 58px; }
.web-bento .wb-feature p { font-family: var(--font-serif); font-weight: 500; font-size: 26px; line-height: 1.14; max-width: 18ch; text-wrap: balance; }
/* Con OCHO tarjetas la rejilla dejaba de cerrar.  La destacada ocupa 4 celdas y
   quedan 7 sueltas: 11 en total, y 3 columnas piden múltiplo de 3.  Que la más
   larga ocupe DOS deja 12 justas y ni un hueco.  Va abajo a la derecha, en
   diagonal con la destacada de arriba a la izquierda: dos bloques anchos en la
   misma columna se leerían como una columna, no como un bento. */
.web-bento .wb-ancha { grid-column: span 2; }
/* 18ch, no 14: con 14 la frase salia en TRES lineas.  La tinta de una sola
   mide 509px, asi que el corte de dos cae sobre los 255 de cada mitad y 18ch
   -308px- deja sitio de sobra sin que quepa una tercera palabra arriba. */

/* Método: cuatro pasos en una fila (override de .steps, que es de 3) */
.steps.steps-4 { grid-template-columns: repeat(4,1fr); }

@media (max-width: 1000px) {
  .steps.steps-4 { grid-template-columns: 1fr 1fr; }
  .web-bento { grid-template-columns: 1fr 1fr; } .web-bento .wb-feature { grid-row: span 1; }
}
@media (max-width: 600px) {
  .steps.steps-4 { grid-template-columns: 1fr; }
  /* en columna, la altura fija de fila (154px) corta el texto de la tarjeta destacada */
  .web-bento { grid-template-columns: 1fr; grid-auto-rows: auto; }
  /* en una sola columna, `span 2` crearía una segunda columna implícita */
  .web-bento .wb-ancha { grid-column: auto; }
  .web-bento .wb { min-height: 140px; }
  .web-bento .wb-feature { grid-column: span 1; }
}

/* Beneficios — diagrama HUB (cajas-pastilla + líneas con flechas a núcleo central, ref. Orb) */
.benefit-hub {
  position: relative; width: 100%; max-width: 1000px; margin: 56px auto 0;
  aspect-ratio: 1200 / 460; z-index: 1;
}
/* Fondo de la seccion: la reticula de puntos de la home, la misma que llevan
   los CTA, con el mismo difuminado de entrada y salida.  Sustituye a las
   manchas de colores desenfocadas del original (ref. Orb), que traian tres
   radiales, cuatro tramas y un `blur(16px)` a pantalla completa.
   La cabecera y el diagrama van en z-index 2, por encima de los degradados de
   los extremos, o el titular se veia lavado por arriba. */
#beneficios { position: relative; overflow: hidden; background: var(--bg); }
#beneficios > .container { position: relative; z-index: 2; }
.ben-dots { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.ben-dots .hero-dots { display: block; width: 100%; height: 100%; }
#beneficios::before, #beneficios::after {
  content: ""; position: absolute; left: 0; right: 0; z-index: 1; pointer-events: none;
  height: clamp(70px, 11vh, 140px);
}
#beneficios::before { top: 0;    background: linear-gradient(180deg, var(--bg) 0%, transparent 100%); }
#beneficios::after  { bottom: 0; background: linear-gradient(180deg, transparent 0%, var(--bg) 100%); }

/* MÉTODO + intro — scrollytelling: imagen comparativa fija (sticky) izq. + paneles de texto que se intercambian (estilo Orb) */
.scrolly { position: relative; }
/* formacion-ia: sin líneas divisorias entre secciones (solo esta página) */
body.page-formacion section { border-top: none; }
/* formacion-ia: tamaño de H2 de sección unificado (el hero conserva su tamaño inline) */
body.page-formacion h2 { font-size: var(--fs-section); line-height: 1.08; }
/* formacion-ia: la pregunta de FAQ ahora es h3 pero conserva el estilo del texto previo */
body.page-formacion h3.faq-q-text { margin: 0; }
/* formacion-ia: unificar el tamaño del texto de cuerpo entre intro (scrollytelling), método y ¿para quién? */
body.page-formacion .svc-hero-text .lead,
body.page-formacion .scrolly-panel .fb-desc,
body.page-formacion .method-list .ml-body p,
body.page-formacion .principle p { font-size: 16px; line-height: 1.6; }
/* ====================== diseño web (webs.html) — mismo tratamiento que formacion-ia ====================== */
/* quitar el "título de arriba" (eyebrow) de todas las secciones MENOS la 1 (el hero va en <header>, conserva el suyo) */
body.page-disenoweb section .eyebrow { display: none; }
/* excepción: los subtítulos PASO 1/2/3 de las tarjetas ladder SÍ se muestran */
body.page-disenoweb .ladder-card .eyebrow { display: block; }
/* sin líneas divisorias entre secciones (solo esta página) */
body.page-disenoweb section { border-top: none; }
/* tamaño de H2 de sección unificado (el hero conserva su tamaño) */
body.page-disenoweb h2 { font-size: var(--fs-section); line-height: 1.08; }
/* CTA de cierre "¿Hablamos de tu nueva web?" forzado a 1 línea */
body.page-disenoweb .cta h2 { max-width: none; white-space: nowrap; }
@media (max-width: 560px) { body.page-disenoweb .cta h2 { white-space: normal; max-width: 16ch; } }
/* lead del hero al mismo tamaño de cuerpo que el resto */
body.page-disenoweb .svc-hero-text .lead { font-size: 16px; line-height: 1.6; }
/* la pregunta de FAQ ahora es h3 pero conserva el estilo del texto previo */
body.page-disenoweb h3.faq-q-text { margin: 0; }
/* cita estilo testimonial: logo que alterna por tema (como el del nav) */
.quote-logo .ql-dark  { display: inline-block; }
.quote-logo .ql-light { display: none; }
html[data-theme="dark"] .quote-logo .ql-dark  { display: none; }
html[data-theme="dark"] .quote-logo .ql-light { display: inline-block; }

/* ====================== email marketing (email-marketing.html) — mismo tratamiento ====================== */
/* sin líneas divisorias entre secciones (solo esta página) */
body.page-email section { border-top: none; }
/* tamaño de H2 de sección unificado (el hero conserva su tamaño inline) */
body.page-email h2 { font-size: var(--fs-section); line-height: 1.08; }
/* lead del hero al mismo tamaño de cuerpo que el resto */
body.page-email .svc-hero-text .lead { font-size: 16px; line-height: 1.6; }
/* la pregunta de FAQ es h3 pero conserva el estilo del texto previo */
body.page-email h3.faq-q-text { margin: 0; }

/* animación de entrada deslizando desde la derecha (al hacer scroll) */
.reveal-r { opacity: 0; transform: translateX(48px); transition: opacity .6s cubic-bezier(.16,1,.3,1), transform .6s cubic-bezier(.16,1,.3,1); }
.reveal-r.in { opacity: 1; transform: none; }
.principles-grid .reveal-r:nth-child(2), .cards-grid .reveal-r:nth-child(2) { transition-delay: .08s; }
.principles-grid .reveal-r:nth-child(3), .cards-grid .reveal-r:nth-child(3) { transition-delay: .16s; }
@media (prefers-reduced-motion: reduce) { .reveal-r { opacity: 1; transform: none; transition: none; } }

/* POR QUÉ GRAFS — acordeón (izq.) + imagen (der.) */
.why-grafs { padding: 90px 0; }
.wg-grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: 64px; align-items: start; }
.wg-left .eyebrow { margin: 0 0 10px; }
.wg-acc { border-top: 1px solid var(--line); }
.wg-item { border-bottom: 1px solid var(--line); }
.wg-q {
  width: 100%; background: none; border: 0; cursor: pointer; text-align: left;
  display: flex; align-items: center; gap: 16px; padding: 22px 0;
  font-family: var(--font-serif); font-size: clamp(18px, 1.6vw, 22px); font-weight: 600; color: var(--ink);
  transition: color .2s ease;
}
.wg-q:hover { color: var(--accent); }
.wg-ico { position: relative; flex: 0 0 auto; width: 11px; height: 11px; }
.wg-ico::before, .wg-ico::after { content: ""; position: absolute; background: var(--accent); border-radius: 2px; transition: transform .3s ease, opacity .3s ease; }
.wg-ico::before { left: 0; right: 0; top: 5px; height: 1.5px; }
.wg-ico::after { top: 0; bottom: 0; left: 5px; width: 1.5px; }
.wg-item.is-open .wg-ico::after { transform: scaleY(0); opacity: 0; }
.wg-a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .35s ease; }
.wg-a-inner { overflow: hidden; }
.wg-a-inner p { margin: 0 0 22px 34px; color: var(--ink-soft); line-height: 1.7; max-width: 52ch; }
.wg-item.is-open .wg-a { grid-template-rows: 1fr; }
.wg-right { position: sticky; top: 110px; }
.wg-img {
  aspect-ratio: 4 / 3; border-radius: 18px; overflow: hidden; border: 1px solid var(--line); background: var(--bg-2);
  display: flex; align-items: center; justify-content: center;
}
.wg-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wg-img-ph { font-family: var(--font-mono); font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); }
@media (max-width: 900px) {
  .wg-grid { grid-template-columns: 1fr; gap: 32px; }
  .wg-right { position: static; order: -1; }
  .wg-img { aspect-ratio: 16 / 10; }
}
.scrolly-sticky { position: sticky; top: 0; min-height: 100vh; display: flex; align-items: center; }
.scrolly-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center; width: 100%; }
/* visuales izquierda: dos frames que se funden (comparativa <-> ilustración método) */
.scrolly-visuals { position: relative; min-height: 460px; }
.sv-frame {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  opacity: 0; visibility: hidden; transform: translateY(14px);
  transition: opacity .5s ease, transform .5s ease, visibility 0s linear .5s;
}
.sv-frame.is-active { opacity: 1; visibility: visible; transform: none; transition: opacity .5s ease, transform .5s ease; }
.scrolly-panels { position: relative; min-height: 62vh; }
/* ilustración método: tarjetas flotantes estilo Orb */
.method-illu { position: relative; width: 100%; max-width: 420px; min-height: 400px; margin: 0 auto; }
.method-illu::before {
  content: ""; position: absolute; inset: -12% -8%; z-index: 0; border-radius: 26px;
  background:
    radial-gradient(50% 60% at 24% 28%, rgba(43,182,194,.20), transparent 70%),
    radial-gradient(52% 60% at 82% 72%, rgba(247,86,43,.16), transparent 70%);
  filter: blur(32px);
}
/* liquid glass (estilo Apple): translúcido + desenfoque del fondo */
.mi-card {
  position: absolute; border-radius: 18px;
  background: rgba(255,255,255,.55);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  backdrop-filter: blur(16px) saturate(1.3);
  border: 1px solid rgba(255,255,255,.65);
  box-shadow: 0 10px 30px rgba(22,19,15,.08), inset 0 1px 0 rgba(255,255,255,.6);
}
html[data-theme="dark"] .mi-card {
  background: rgba(42,44,50,.45); border-color: rgba(255,255,255,.12);
  box-shadow: 0 10px 30px rgba(0,0,0,.25), inset 0 1px 0 rgba(255,255,255,.08);
}
/* tarjeta 1 (mini): roadmap horizontal de nodos, sin texto (no repite los pasos) */
.mi-mini { top: 6px; left: 0; width: 54%; padding: 18px 20px; z-index: 2; }
.mi-mini-road { position: relative; display: flex; align-items: center; justify-content: space-between; }
.mi-mini-line { position: absolute; left: 15px; right: 15px; top: 50%; height: 2px; background: var(--line); transform: translateY(-50%); }
.mi-mini-fill { position: absolute; left: 15px; width: 33%; top: 50%; height: 2px; background: var(--accent); transform: translateY(-50%); }
.mi-node-sm {
  position: relative; z-index: 1; flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%;
  background: rgba(255,255,255,.7); border: 2px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-size: 12px; font-weight: 600; color: var(--ink-faint);
}
.mi-node-sm.is-done { background: var(--accent); border-color: var(--accent); color: #fff; }
.mi-node-sm.is-now { border-color: var(--accent); color: var(--accent); background: rgba(255,255,255,.85); }
/* conector tipo cable entre tarjeta 1 y tarjeta 2 */
.mi-wire {
  position: absolute; left: 30px; top: 64px; width: 64px; height: 118px; z-index: 1;
  border-left: 2px solid var(--accent); border-bottom: 2px solid var(--accent);
  border-bottom-left-radius: 16px; opacity: .5;
}
/* tarjeta 2 (protagonista): diagnóstico de tareas */
.mi-diag { bottom: 0; right: 0; width: 76%; padding: 22px 24px; z-index: 3; display: flex; flex-direction: column; gap: 18px; }
.mi-diag-tag { font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--accent); }
.mi-q { display: flex; flex-direction: column; gap: 9px; }
.mi-q-text { margin: 0; font-family: var(--font-sans); font-size: 13.5px; font-weight: 600; color: var(--ink); line-height: 1.3; }
.mi-opt { display: flex; align-items: center; gap: 10px; }
.mi-radio { flex: 0 0 auto; width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--line); }
.mi-opt.is-sel .mi-radio { border-color: var(--accent); background: radial-gradient(circle, var(--accent) 0 42%, transparent 46%); }
.mi-opt-bar { height: 8px; border-radius: 4px; background: rgba(25,26,30,.10); }
html[data-theme="dark"] .mi-opt-bar { background: rgba(255,255,255,.14); }

/* LOGOS IA — marquee de tarjetas grises (auto-scroll continuo) */
.logos-strip {
  overflow: hidden; padding: 44px 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.logos-track { display: flex; gap: 18px; width: max-content; animation: logos-scroll 40s linear infinite; }
.logos-strip:hover .logos-track { animation-play-state: paused; }
.logo-card {
  flex: 0 0 auto; width: 200px; height: 108px; background: var(--bg-2); border-radius: 14px;
  display: flex; align-items: center; justify-content: center;
}
.logo-wm {
  font-family: var(--font-head, var(--font-sans)); font-weight: 700; font-size: 21px; letter-spacing: .01em;
  color: var(--ink-faint); opacity: .85;
}
@keyframes logos-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .logos-track { animation: none; } }
@media (max-width: 600px) { .logo-card { width: 152px; height: 88px; } .logo-wm { font-size: 17px; } }
.scrolly-panel {
  position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: center;
  opacity: 0; visibility: hidden; transform: translateY(18px);
  transition: opacity .5s ease, transform .5s ease, visibility 0s linear .5s;
}
.scrolly-panel.is-active { opacity: 1; visibility: visible; transform: none; transition: opacity .5s ease, transform .5s ease; }
.scrolly-panel h2 { font-size: var(--fs-section); line-height: 1.05; margin: 0 0 18px; }
.scrolly-panel .fb-desc { color: var(--ink-soft); margin-bottom: 18px; max-width: 52ch; line-height: 1.65; }
.scrolly-spacer { height: 88vh; }
@media (max-width: 980px) {
  .scrolly-sticky { position: static; min-height: 0; padding: 50px 0; }
  .scrolly-grid { grid-template-columns: 1fr; gap: 36px; }
  .scrolly-panels { min-height: 0; display: flex; flex-direction: column; gap: 40px; }
  .scrolly-panel { position: static; opacity: 1; visibility: visible; transform: none; }
  .scrolly-visuals { min-height: 0; display: flex; flex-direction: column; gap: 24px; }
  /* En una columna el texto va primero: el visual (bandeja, mockups…) baja tras él */
  .scrolly-grid > .scrolly-visuals { order: 1; }
  .sv-frame { position: static; opacity: 1; visibility: visible; transform: none; }
  .scrolly-spacer { display: none; }
}

/* ===== formacion-ia · S2 · cada texto con SU visual debajo (2026-09-02) =====
   La regla de arriba baja los visuales EN BLOQUE, así que en una columna salía
   texto 1, texto 2, visual 1, visual 2: el mockup de la comparativa quedaba a
   dos pantallas de la frase que explica. Aitor lo pidió intercalado.

   Se hace con `display: contents` en los dos contenedores: sus cajas
   desaparecen y los cuatro hijos pasan a ser hijos directos de `.scrolly-grid`,
   donde ya se pueden ordenar entre sí.  Sin eso no hay forma en CSS de
   intercalar hijos de dos padres distintos —`order` sólo ordena hermanos— y
   habría que partir el marcado en dos bloques, que es justo lo que rompería el
   escritorio, donde los visuales tienen que estar juntos para superponerse.

   Ojo: con `display: contents` mueren los `gap` de `.scrolly-panels` (40px) y
   `.scrolly-visuals` (24px), porque ya no hay caja que los aplique.  El aire
   entre los cuatro lo pone ahora el `gap` de `.scrolly-grid`, y por eso sube a
   44: antes separaba dos bloques y ahora separa cuatro.

   Va SÓLO en formación: `.scrolly` lo comparte email-marketing, donde el visual
   es una bandeja que se llena y el orden en bloque sí es el bueno. */
@media (max-width: 980px) {
  /* `align-items: stretch` NO es redundante.  `.scrolly-grid` trae
     `align-items: center` de la versión de escritorio, donde es una rejilla de
     dos columnas y centra verticalmente.  Al pasarla a flex EN COLUMNA, ese
     `center` deja de centrar y pasa a MEDIR: los hijos se encogen a su ancho de
     contenido en vez de ocupar la fila.  Y `.sv-frame` sólo contiene cajas en
     posición absoluta, así que su ancho de contenido es CERO: el mockup del
     diagnóstico salía en 50px, con una palabra por renglón. */
  .page-formacion-ia .scrolly-grid { display: flex; flex-direction: column; gap: 44px; align-items: stretch; }
  .page-formacion-ia .scrolly-panels,
  .page-formacion-ia .scrolly-visuals { display: contents; }
  .page-formacion-ia .scrolly-panel[data-panel="0"] { order: 1; }
  .page-formacion-ia .sv-frame[data-visual="0"]     { order: 2; }
  .page-formacion-ia .scrolly-panel[data-panel="1"] { order: 3; }
  .page-formacion-ia .sv-frame[data-visual="1"]     { order: 4; }
}

/* MÉTODO — lista numerada de pasos */
.method-list { list-style: none; padding: 0; margin: 26px 0 0; display: flex; flex-direction: column; gap: 20px; }
.method-list li { display: flex; gap: 16px; align-items: flex-start; }
.method-list .ml-num {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: 9px;
  background: var(--accent-soft); color: var(--accent);
  font-family: var(--font-mono); font-weight: 600; font-size: 15px;
  display: flex; align-items: center; justify-content: center;
}
.method-list .ml-body h3 { margin: 3px 0 6px; font-size: var(--fs-h3); line-height: 1.2; }
.method-list .ml-body p { margin: 0; color: var(--ink-soft); line-height: 1.6; max-width: 46ch; }
@media (max-width: 980px) {
  #practica .fb-visual { position: static; }
}
.bh-lines { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.bh-line { fill: none; stroke: var(--accent); stroke-width: 2; opacity: .55; }
.bh-arrow { fill: var(--accent); }
.bh-dot { fill: var(--accent); }
/* núcleo central */
.bh-core {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  z-index: 2; width: 19%; min-width: 116px;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  background: var(--white); border: 1px solid var(--line); border-radius: 18px;
  padding: 24px 18px; box-shadow: 0 18px 44px rgba(22,19,15,.10);
}
html[data-theme="dark"] .bh-core { background: var(--bg-2); }
.bh-core-ico {
  width: 54px; height: 54px; border-radius: 13px; background: var(--ink); color: var(--accent);
  display: flex; align-items: center; justify-content: center; font-size: 26px; line-height: 1;
}
.bh-core-label {
  font-family: var(--font-sans); font-size: 15px; font-weight: 600; color: var(--ink);
}
/* pastillas de beneficios */
.bh-items { position: absolute; inset: 0; list-style: none; margin: 0; padding: 0; }
.bh-item {
  position: absolute; transform: translateY(-50%); width: 23%;
  background: var(--white); border: 1px solid var(--line); border-radius: 12px;
  padding: 14px 18px; box-shadow: 0 8px 22px rgba(22,19,15,.05);
  font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 600; line-height: 1.32; color: var(--ink);
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}
html[data-theme="dark"] .bh-item { background: var(--bg-2); }
.bh-item:hover { box-shadow: 0 16px 32px rgba(22,19,15,.09); border-color: rgba(247,86,43,.45); }
/* posiciones: izquierda (ancla derecha a 25%) y derecha (ancla izquierda a 75%) */
.pos-l1, .pos-l2, .pos-l3 { right: 75%; }
.pos-r1, .pos-r2, .pos-r3 { left: 75%; }
.pos-l1 { top: 19.6%; } .pos-l2 { top: 50%; } .pos-l3 { top: 80.4%; }
.pos-r1 { top: 19.6%; } .pos-r2 { top: 50%; } .pos-r3 { top: 80.4%; }
.bh-item.pos-l1:hover, .bh-item.pos-l2:hover, .bh-item.pos-l3:hover { transform: translateY(-50%) translateX(-3px); }
.bh-item.pos-r1:hover, .bh-item.pos-r2:hover, .bh-item.pos-r3:hover { transform: translateY(-50%) translateX(3px); }
/* responsive: apila en columna y oculta las líneas.
   El corte es el MISMO en el que el hub deja de ser una composición radial y
   pasa a lista; los tres ajustes de abajo van atados a eso y no se mueven por
   separado.

   Las pastillas apiladas necesitan más caja de la que tenían.  En radial cada
   una ocupa el 23% del ancho y el texto parte donde quiera —es una nube—; en
   lista, partir deja jirones: medido a 810, «Atiende más clientes sin ampliar
   tu / equipo» y «Prepara presupuestos y propuestas más / rápido» dejaban
   segundos renglones de 64 y 60px.  Tres cosas, y hacen falta las tres:
   · Fuera el relleno lateral del hub (los 16px de cada lado): el `.container`
     ya separa del borde, y aquí ese relleno sólo estrechaba el texto.
   · El cuerpo baja de 18 a 16px.  18 es `--fs-body`, el tamaño de un párrafo,
     y esto son etiquetas.
   · `text-wrap: balance`, que es lo que convierte un jirón en dos renglones
     parejos cuando el texto no cabe de una.
   Resultado medido: a 810 las SEIS entran en un renglón (el hub pasa de 602 a
   527px) y a 390 sólo parten las dos largas, y parten por la mitad. */
@media (max-width: 860px) {
  .benefit-hub { aspect-ratio: auto; max-width: 460px; padding: 24px 0;
    display: flex; flex-direction: column; }
  .bh-item { padding: 13px 14px; font-size: 16px; text-wrap: balance; }
  .bh-lines { display: none; }

  /* «Tu negocio» va AL FINAL, no arriba, y con una flecha que baja hacia él.
     No es colocación: es lo que DICE el dibujo.  En escritorio los seis
     beneficios apuntan al centro con líneas y puntas de flecha —«todo esto
     alimenta tu negocio»—; apilados en una columna, esas líneas se esconden
     (`.bh-lines { display: none }`) y con el núcleo arriba la sección se queda
     en una lista de siete cosas sueltas, la primera más gorda. Poniéndolo
     abajo, la lista desemboca en él y la frase vuelve a leerse.

     La flecha es el `::after` de la lista: un elemento de la propia columna
     flex, así que se coloca solo detrás del último beneficio sin posiciones
     absolutas.  El `clip-path` dibuja el astil y la punta de una vez —una sola
     caja, un solo pseudoelemento— porque `.bh-items` ya no tiene otro libre. */
  .bh-core { position: static; transform: none; width: auto; min-width: 0;
    order: 2; margin: 0 auto; flex-direction: row; gap: 14px; }
  .bh-items { position: static; order: 1; display: flex; flex-direction: column; gap: 12px; }
  .bh-items::after {
    content: ""; align-self: center; flex: 0 0 auto;
    width: 15px; height: 30px; margin: 6px 0 0;
    background: var(--accent);
    clip-path: polygon(40% 0, 60% 0, 60% 60%, 100% 60%, 50% 100%, 0 60%, 40% 60%);
  }
  .bh-item { position: static; transform: none; width: 100%; }
  .bh-item.pos-l1:hover, .bh-item.pos-l2:hover, .bh-item.pos-l3:hover,
  .bh-item.pos-r1:hover, .bh-item.pos-r2:hover, .bh-item.pos-r3:hover { transform: translateY(-2px); }
}

/* ==========================================================================
   LADDER — tarjetas escalonadas que descienden (estilo Orb)
   Tres columnas; cada una arranca más abajo que la anterior. En móvil se apila.
   ========================================================================== */
.ladder {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--gap);
  align-items: start;
  margin-top: 56px;
}
.ladder-card { max-width: 33ch; }
/* el descenso escalonado */
.ladder .l2 { margin-top: 104px; }
.ladder .l3 { margin-top: 208px; }

.ladder-ico {
  width: 76px; height: 76px;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 24px;
  color: var(--ink);
  transition: transform .3s ease;
}
.ladder-ico svg { width: 76px; height: 76px; display: block; }
.ladder-card:hover .ladder-ico { transform: translateY(-4px); }

.ladder-card .eyebrow { color: var(--accent); font-size: 12.5px; margin-bottom: 12px; }
.ladder-card h3 { margin-bottom: 16px; max-width: 19ch; text-wrap: balance; }
/* 19ch, no 13: con 13 los pasos 1 y 3 salian en TRES lineas -«Estudio del
   proyecto y estrategia» y «Desarrollo, puesta en marcha y soporte»-, y el 2
   en dos.  Con 19 los tres van a dos.  `.ladder` solo la usa webs.php. */
.ladder-card p { color: var(--ink-soft); font-size: var(--fs-body); line-height: 1.6; margin: 0; }

@media (max-width: 960px) {
  .ladder { grid-template-columns: 1fr; gap: 44px; margin-top: 44px; }
  .ladder .l2, .ladder .l3 { margin-top: 0; }
  .ladder-card { max-width: 46ch; }
}

/* ==========================================================================
   QUIÉNES SOMOS — Sección Metodología (versión simplificada del sistema)
   Escalera Orb (stagger descendente): Diagnóstico · Cimientos · Crecimiento · Escalar.
   Jerarquía: Diagnóstico y Escalar = tarjetas claras (transición de análisis);
   Cimientos y Crecimiento = tarjetas con énfasis (solo nombres / motores + pregunta).
   El detalle fino vive en la página "Cómo trabajamos". Visual estilo Orb: aire,
   redondeado, hairlines finas. Ciclo recurrente cerrado con .cycle-loop.
   ========================================================================== */
.method { padding: calc(var(--sp-sec) - 24px) 0 var(--sp-sec); scroll-margin-top: 70px; }   /* al llegar por #metodologia, deja aire bajo el nav sticky (no tapa el intro) */
/* `z-index` porque la escena de abajo sube por debajo del titular con un margen
   negativo, y su `sticky` la convierte en elemento posicionado: sin esto, la
   caja del pin —vacía y transparente en su parte de arriba— quedaría por
   encima del h2 y se comería hasta la selección del texto. */
.method .m-head { position: relative; z-index: 1; max-width: 1240px; margin: 0 auto 8px; text-align: center; }
.method .m-head h2 { margin: 14px 0 16px; }
/* apoyo centrado y en 2 líneas: fuente fija (no el clamp que crece en pantallas anchas) + ancho holgado */
.method .m-head .lead { font-size: 18px; line-height: 1.6; max-width: 1180px; margin: 0 auto; }

/* ---------- piezas compartidas ---------- */
.b-tag {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent); margin: 0 0 12px;
}
.m-when {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--ink-faint);
}
.m-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.m-chip {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .04em;
  color: var(--accent); background: var(--accent-soft); border-radius: 999px; padding: 4px 11px;
}

/* sub-items (Marca / motor): sin caja, separados por hairline = look Orb */
.m-itemcard { background: transparent; border: 0; padding: 14px 0; }
.m-itemcard + .m-itemcard { border-top: 1px solid var(--line); }
.m-itemcard:first-child { padding-top: 0; }
.m-itemcard:last-child { padding-bottom: 0; }
.m-itemcard h4 { font-family: var(--font-head); font-weight: 700; font-size: 13px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink); margin: 0 0 9px; }
.m-itemcard h4:last-child { margin-bottom: 0; }
.m-itemcard .ic-hook { font-size: 13px; color: var(--ink-soft); font-style: italic; margin: 0 0 11px; }
.m-itemcard .ic-hook:last-child { margin-bottom: 0; }
.m-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.m-list li { position: relative; padding-left: 15px; font-size: 13.5px; color: var(--ink-soft); line-height: 1.5; }
.m-list li::before { content: ""; position: absolute; left: 2px; top: 10px; width: 5px; height: 5px; border-radius: 50%; background: var(--accent); }
.m-grid { display: grid; gap: 0; }

/* cabecera de fase protagonista (Cimientos / Crecimiento) */
.blk-head { margin-bottom: 18px; }
.blk-head .b-tag { display: block; }
.blk-head h3 { font-family: var(--font-serif); font-size: var(--fs-h3); margin: 0 0 4px; }
.blk-head .m-hook { color: var(--ink-soft); font-style: italic; margin: 0; font-size: 14.5px; }

/* recurrencia: insignia con icono de ciclo girando entre dos rieles que se desvanecen */
.cycle { display: flex; align-items: center; gap: 22px; margin-top: 44px; }
.cycle::before, .cycle::after { content: ""; flex: 1; height: 1px; }
.cycle::before { background: linear-gradient(90deg, transparent, var(--line)); }
.cycle::after  { background: linear-gradient(90deg, var(--line), transparent); }
.cycle .badge {
  display: inline-flex; align-items: center; gap: 13px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 999px; padding: 11px 24px 11px 17px;
  flex: 0 0 auto;
}
.cycle .spin { width: 30px; height: 30px; color: var(--accent); flex: 0 0 auto; animation: cycle-spin 9s linear infinite; }
@keyframes cycle-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .cycle .spin { animation: none; } }
.cycle .badge .txt { font-family: var(--font-mono); font-size: 12.5px; letter-spacing: .03em; color: var(--accent); line-height: 1.5; white-space: nowrap; }
@media (max-width: 620px) { .cycle .badge .txt { white-space: normal; } }

/* ---------- MÉTODO · visualización ESTÁTICA y COMPACTA: bucle "fórmula del éxito" (Ray Dalio)
   VECTORIZADO (SVG, manipulable y recoloreable), centrado; 4 fases 2 izq / 2 der con conector
   punteado a su flecha. El stage comparte proporción con el viewBox de conectores (1240×620). */
.mfx { margin-top: 36px; }
.mfx-stage { position: relative; width: 100%; max-width: 1240px; margin: 0 auto; aspect-ratio: 1240 / 620; }

/* conectores punteados · sutiles pero perceptibles (coords 1240×620) */
.mfx-links { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.mfx-links path { fill: none; stroke: var(--ink-soft); stroke-width: 2.2; stroke-linecap: round; stroke-dasharray: 0.1 8; opacity: .42; }
.mfx-links circle { fill: var(--accent); opacity: .7; }

/* la figura VECTORIZADA (trazado del PNG): curva = --ink (claro/oscuro), flechas = --accent.
   Cada flecha es un <path> independiente (.mfx-arrow-top/-left/-right/-bottom) → manipulable. */
.mfx-graph { position: absolute; left: 47%; top: 50.2%; transform: translate(-50%, -50%); transform-origin: 57% 45.5%; width: 48%; z-index: 1; }
.mfx-svg { display: block; width: 100%; height: auto; }
.mfx-vcurve { fill: var(--ink); }

.mfx-varrow { fill: var(--accent); }

/* las 4 fases · 2 izquierda / 2 derecha. Margen interno uniforme (padding igual en los 4 lados),
   ancladas por su centro vertical (casan con los conectores). Dos pares de tamaño idéntico. */
.mfx-card { position: absolute; width: 22%; transform: translateY(-50%); z-index: 2;
  display: flex; flex-direction: column; justify-content: flex-start; gap: 8px; padding: 24px;
  transition: transform .3s ease, box-shadow .3s ease, border-color .3s ease; }
.mfx-card h3 { margin: 0; }
.mfx-card .m-hook { margin: 0; }
.mfx-card .m-when { font-family: var(--font-mono); font-size: 11px; letter-spacing: .07em; text-transform: uppercase; color: var(--ink-faint); margin-top: 2px; }
.mfx-card .m-list { list-style: none; margin: 4px 0 0; padding: 0; gap: 0; }
.mfx-card .m-list li { padding: 8px 0; padding-left: 0; border-top: 1px solid var(--line); }
.mfx-card .m-list li::before { display: none; }   /* sin el bullet naranja heredado */
.mfx-card .m-list li:first-child { border-top: 0; padding-top: 0; }
.mfx-card .m-key { display: block; font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--ink); }
.mfx-card .m-q { display: block; margin-top: 2px; font-style: italic; font-size: 13px; color: var(--ink-soft); }
/* `min-height`, no `height`.  Con alto FIJO el contenido más largo no cabía y,
   al ir centrado, se comía el padding por los dos lados: Diagnóstico se
   quedaba en 8px de margen contra los 26 declarados, y por debajo de 1.100px
   el texto se salía de la tarjeta (−12px medidos a 960).  El suelo mantiene
   parejas del mismo alto mientras el contenido quepa; cuando no cabe, la
   tarjeta crece en vez de aplastarse. */
.pos-tl, .pos-tr { min-height: 184px; }
.pos-bl, .pos-br { min-height: 290px; }
.pos-tl { left: 2.4%; top: 17%; }    /* Diagnóstico → flecha izquierda */
.pos-tr { left: 75.6%; top: 17%; }   /* Escalar     → flecha superior  */
.pos-bl { left: 2.4%; top: 75%; }    /* Crecimiento → flecha inferior  */
.pos-br { left: 75.6%; top: 75%; }   /* Cimientos   → flecha derecha   */
/* hover EXTREMADAMENTE sutil; preserva el centrado (anula el salto del translateY(-4px) global) */
.mfx-stage .mfx-card:hover { transform: translateY(calc(-50% - 2px)); }
.mfx-stage .mfx-card.emph:hover  { box-shadow: 0 14px 32px rgba(22,19,15,.08); }
.mfx-stage .mfx-card.light:hover { border-color: var(--ink-soft); }

/* nota de ciclo · píldora centrada bajo la composición */
.mfx-cycle { display: flex; align-items: center; justify-content: center; gap: 10px;
  width: max-content; max-width: 92%; margin: 12px auto 0; padding: 10px 20px;
  border: 1px solid var(--line); border-radius: 999px;
  font-family: var(--font-mono); font-size: 12px; letter-spacing: .03em; color: var(--accent); }
.mfx-cycle svg { width: 16px; height: 16px; flex: none; }

/* ESCENA scrollytelling: la composición queda FIJA (sticky) mientras el scroll
   desvanece las 4 fases hacia arriba y trae el "gráfico grande" (coil) centrado.
   El JS escribe opacity/transform en vivo; aquí solo el escenario y el reposo. */
/* El margen NEGATIVO sube la escena entera por debajo del titular.  Es la
   palanca buena para este hueco: la escena lleva dentro un `sticky` que se
   pega a `top: 0`, así que **la composición fijada no se mueve** — sólo cambia
   dónde empieza. Tocar el `padding-top` del pin en cambio la subiría también
   mientras está pegada, y ahí es donde la pillaría el header. */
.mfx-scene { position: relative; height: 330vh; margin-top: -171px; }
.mfx-pin { position: sticky; top: 0; height: 100vh; box-sizing: border-box; padding-top: 92px;
  display: flex; align-items: center; justify-content: center; }
.mfx-pin .mfx-stage { margin: 0; }
.mfx-graph, .mfx-card, .mfx-links { will-change: transform, opacity; }
/* gráfico grande (coil) superpuesto y centrado · oculto hasta que el scroll lo revela */
.mfx-bigwrap { position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 18px; opacity: 0; pointer-events: none; overflow: hidden; }
.mfx-big { width: min(1680px, 96vw); transform-origin: center; will-change: transform, opacity; }
.coil-svg { display: block; width: 100%; height: auto; overflow: visible; }

/* ACTO 3 · dos bloques de texto en diagonal (estilo nombre de tarjeta) · el JS los revela en secuencia */
.mfx-tx { position: absolute; opacity: 0; max-width: 32%; z-index: 3; pointer-events: none; will-change: transform, opacity; }
.mfx-tx-h { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-section);
  line-height: 1.08; letter-spacing: -.02em; margin: 0; color: var(--ink); }
.mfx-tx-s { font-size: 15px; line-height: 1.55; letter-spacing: .01em; color: var(--ink-soft); margin: 11px 0 0; max-width: 34ch; }
.mfx-tx-b .mfx-tx-s { margin-left: auto; }                   /* el subtítulo derecho pega a la derecha bajo su titular */
.mfx-tx-a { top: 18%; left: 6%; text-align: left; }          /* arriba-izquierda, cerca del coil */
.mfx-tx-b { bottom: 10%; right: 6%; text-align: right; max-width: none; }   /* abajo-derecha, cerca del coil */
/* En UNA línea (Aitor, 31-ago).  Con el `max-width: 32%` heredado partía en
   dos.  No hace falta protegerlo en móvil: ahí `.mfx-tx` va con `display:none`. */
.mfx-tx-b .mfx-tx-h { white-space: nowrap; }
.mfx-tx-b .mfx-tx-s { max-width: 34ch; }

/* contraste: en oscuro las etiquetas mono (--ink-faint) quedan apagadas → un punto más claras (solo en este bloque) */
html[data-theme="dark"] .mfx-card .m-when { color: #969BA3; }

@media (max-width: 900px) {
  /* en móvil: sin scroll-scene; gráfica arriba, fases apiladas y el coil estático debajo */
  .mfx-scene { height: auto; }
  .mfx-pin { position: static; height: auto; display: block; }
  .mfx-stage { aspect-ratio: auto; }
  .mfx-links { display: none; }
  .mfx-graph { position: relative; left: auto; top: auto; transform: none; width: min(320px, 72%); margin: 0 auto 24px; }
  .mfx-card { position: static; width: auto; transform: none; margin: 0 0 14px; }
  .pos-tl, .pos-tr, .pos-bl, .pos-br { height: auto; }
  .mfx-stage .mfx-card:hover { transform: translateY(-2px); }
  .mfx-bigwrap { position: static; inset: auto; opacity: 1; margin-top: 12px; }
  .mfx-big { transform: none; width: 100%; }
  .mfx-pin { padding-top: 0; }
  .mfx-tx { position: static; opacity: 1; max-width: none; text-align: left; margin: 14px 0 0; }
  .mfx-tx-a { margin-top: 22px; }
}

/* sin animación (prefers-reduced-motion): composición y, debajo, el coil — ambos estáticos */
@media (prefers-reduced-motion: reduce) {
  /* Sin el pin no hay 92px de `padding-top` que absorban el margen negativo de
     la escena, así que aquí se anula: con −171px la composición se subía 122px
     POR ENCIMA del titular. */
  .mfx-scene { height: auto; margin-top: 0; }
  .mfx-pin { position: static; height: auto; display: block; }
  .mfx-bigwrap { position: static; inset: auto; opacity: 1; margin-top: 36px; }
  .mfx-big { transform: none; }
  .mfx-pin { padding-top: 0; }
  .mfx-tx { position: static; opacity: 1; max-width: none; text-align: left; margin: 14px 0 0; }
  .mfx-tx-a { margin-top: 22px; }
}

/* ---------- VARIANTE A · escalera Orb (stagger descendente, simplificada) ---------- */
.mA { display: grid; grid-template-columns: .82fr 1.18fr 1.18fr .82fr; gap: 20px; align-items: start; }
.mA .s2 { margin-top: 46px; }
.mA .s3 { margin-top: 92px; }
.mA .s4 { margin-top: 138px; }
.mA-card { border-radius: 20px; padding: 26px 24px; transition: transform .25s ease, box-shadow .25s ease; }
.mA-card.light { background: transparent; border: 1px dashed var(--line); }
.mA-card.emph  { background: var(--bg-2); border: 1px solid var(--line); box-shadow: 0 16px 38px rgba(22,19,15,.07); }
.mA-card:hover { transform: translateY(-4px); }
.mA-card.emph:hover { box-shadow: 0 22px 46px rgba(22,19,15,.12); }
.mA-card h3 { font-family: var(--font-serif); font-size: var(--fs-h3); margin: 0 0 6px; }
.mA-card.emph h3 { font-size: 24px; }
.mA-card > .m-hook { color: var(--ink-soft); font-style: italic; font-size: 14px; margin: 0; }
.mA-card .m-when { display: block; margin-top: 12px; }
.mA-card .m-grid { margin-top: 18px; }

@media (max-width: 980px) {
  .mA { grid-template-columns: 1fr; gap: 16px; }
  .mA .s2, .mA .s3, .mA .s4 { margin-top: 0; }
}

/* ==========================================================================
   EMAIL MARKETING — prototipos de dinamismo (A inbox · B flow · C hero sobre)
   Bloque de COMPARACIÓN — colapsar al bloque ganador después.
   ========================================================================== */

/* ---- C · Hero: píxeles que se ensamblan en un sobre ---- */
.eml-hero-pix { position: relative; width: 100%; max-width: 460px; margin: 0 auto; aspect-ratio: 1.25 / 1; }
.ehp-cell {
  position: absolute; top: 0; left: 0;
  width: var(--ps, 18px); height: var(--ps, 18px); border-radius: 3px;
  opacity: 0; will-change: transform, opacity;
  transition: transform 1s cubic-bezier(.16,1,.3,1), opacity .8s ease;
}
.eml-hero-pix.is-in .ehp-cell { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .ehp-cell { transition: none; opacity: 1 !important; }
}

/* ---- A · S2 "¿Por qué?": bandeja que se llena (scrolly sticky) ---- */
/* Baja el bloque (bandeja + texto a la vez) para centrarlo ópticamente bajo
   la barra flotante; compensa su altura (~tipo MacBook). Scopeado a esta página. */
.eml-why .scrolly-sticky { padding-top: 96px; }
.eml-why-head { margin: 0 0 30px; }
.eml-why-head h2 { font-size: var(--fs-section); line-height: 1.08; margin: 0 0 16px; }
.eml-why-head .lead { max-width: 46ch; margin: 0; }
.eml-reason {
  padding: 13px 0 13px 18px; margin: 0; border-left: 2px solid var(--line);
  opacity: .32; transition: opacity .45s ease, border-color .45s ease;
}
.eml-reason.is-active { opacity: 1; border-color: var(--accent); }
.eml-reason p { margin: 0; font-size: var(--fs-body); line-height: 1.55; color: var(--ink); }
.eml-reason strong { color: var(--ink); }

.eml-inbox {
  width: 100%; max-width: 380px; margin: 0 auto; background: var(--bg);
  border: 1px solid var(--line); border-radius: 18px; padding: 16px;
  box-shadow: 0 24px 60px rgba(22,19,15,.10);
}
html[data-theme="dark"] .eml-inbox { background: var(--bg-2); }
.eml-inbox-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.eml-inbox-title { font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); }
.eml-openrate { font-family: var(--font-serif); font-weight: 500; font-size: 19px; color: var(--accent); line-height: 1; }
.eml-openrate span { font-family: var(--font-mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); display: block; margin-top: 3px; }
.eml-mail {
  display: flex; gap: 11px; align-items: flex-start; padding: 11px; margin-bottom: 9px;
  background: var(--bg-2); border-radius: 12px;
  opacity: 0; transform: translateY(12px) scale(.97);
  transition: opacity .5s ease, transform .5s cubic-bezier(.16,1,.3,1);
}
html[data-theme="dark"] .eml-mail { background: rgba(255,255,255,.04); }
.eml-mail:last-child { margin-bottom: 0; }
.eml-mail.show { opacity: 1; transform: none; }
.eml-mail .em-dot { width: 32px; height: 32px; border-radius: 50%; background: var(--accent); color: #fff; display: flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.eml-mail .em-dot svg { width: 16px; height: 16px; }
.eml-mail .em-h { margin: 0; font-weight: 600; font-size: 13.5px; color: var(--ink); }
.eml-mail .em-s { margin: 2px 0 0; font-size: 12.5px; color: var(--ink-soft); line-height: 1.35; }
@media (prefers-reduced-motion: reduce) {
  .eml-mail { opacity: 1; transform: none; transition: none; }
  .eml-reason { opacity: 1; }
}

/* ---- S3 "Servicios": BENTO estilo Orb (5 tarjetas · cada servicio = H3) ---- */
.eml-svc { padding: var(--sp-sec) 0; }
.eml-svc-head { margin: 0 0 8px; }
body.page-email .eml-svc-head h2 { font-family: var(--font-sans); font-size: var(--fs-eyebrow); font-weight: 500; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); line-height: 1.4; margin: 0 0 14px; }
.eml-svc-head .svc-sub { font-family: var(--font-serif); font-style: normal; font-weight: 500; font-size: var(--fs-section); line-height: 1.08; color: var(--ink); margin: 0; white-space: nowrap; }
@media (max-width: 640px) { .eml-svc-head .svc-sub { white-space: normal; } }

.eml-bento { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-top: 44px;
  grid-template-areas: "auto camp" "cono todo" "lleg todo"; }
.eb-auto { grid-area: auto; } .eb-camp { grid-area: camp; } .eb-cono { grid-area: cono; }
.eb-lleg { grid-area: lleg; } .eb-todo { grid-area: todo; }
/* Nos encargamos (todo) ocupa 2 filas → su visual crece a lo alto */
.eb-todo .eb-art { flex: 1; }

.eb-card { background: var(--bg-2); border: 1px solid var(--line); border-radius: 20px; padding: 24px 24px 26px; display: flex; flex-direction: column; }
html[data-theme="dark"] .eb-card { background: rgba(255,255,255,.03); }
.eb-card.dark { background: #16161a; border-color: rgba(255,255,255,.08); color: #fff; }
.eb-art { position: relative; border-radius: 14px; background: var(--bg); border: 1px solid var(--line); margin-bottom: 18px; min-height: 124px; padding: 18px; overflow: hidden; display: flex; }
html[data-theme="dark"] .eb-art { background: rgba(255,255,255,.04); }
.eb-card.dark .eb-art { background: rgba(255,255,255,.04); border-color: rgba(255,255,255,.08); }
/* auto y camp comparten fila del grid → misma altura de visual para que sus títulos queden alineados */
.eb-auto .eb-art, .eb-camp .eb-art { min-height: 284px; }
.eb-h { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-h3); margin: 0 0 8px; color: var(--ink); }
.eb-card.dark .eb-h { color: #fff; }
.eb-d { margin: 0; color: var(--ink-soft); font-size: var(--fs-body); line-height: 1.6; }
.eb-card.dark .eb-d { color: rgba(255,255,255,.72); }

/* 1 · Automatizaciones — flow vertical animado (línea + punto pasan por el centro de los iconos) */
.ebflow { flex-direction: column; justify-content: center; }
.ebf-line { position: absolute; left: 44px; top: 34px; bottom: 34px; width: 2px; background: var(--line); z-index: 0; }
.ebf-dot { position: absolute; left: 41px; z-index: 0; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 2px var(--bg), 0 0 0 5px rgba(247,86,43,.22); animation: ebtravel var(--ebf-ciclo) ease-in-out infinite; }
/* Las paradas del punto salen de la geometría de los nodos, no de fracciones de
   la caja. Antes eran TRES —arriba, `50% - 4px` y abajo— para CUATRO nodos, así
   que la del medio no caía en ningún icono: caía entre el segundo y el tercero.
   Medido: nodo de 48px (icono 26 + 2×10 de margen interno + 2 de borde) y 16 de
   separación, o sea un paso de 64px exactos, igual a 1440, 1024 y 390.
   Los cuatro nodos van CENTRADOS en la caja, así que el primero no está a una
   distancia fija del techo: depende del alto de la caja (22px a 1440, 19 a 390).
   De ahí el `(100% - bloque) / 2`, que se recalcula solo. */
.ebflow {
  --ebf-nodo:  48px;    /* alto de un nodo */
  --ebf-hueco: 16px;    /* separación entre nodos (`.ebf-node + .ebf-node`) */
  --ebf-paso:   calc(var(--ebf-nodo) + var(--ebf-hueco));
  --ebf-bloque: calc(var(--ebf-nodo) * 4 + var(--ebf-hueco) * 3);
  /* centro del icono del primer nodo, menos el radio del punto (8px / 2) */
  --ebf-uno: calc((100% - var(--ebf-bloque)) / 2 + var(--ebf-nodo) / 2 - 4px);
  --ebf-ciclo: 4.4s;   /* uno solo para el punto y para los nodos: si van por
                          separado, se desincronizan en cuanto se toque uno */
}
.ebf-node { position: relative; z-index: 1; display: flex; align-items: center; gap: 11px; padding: 10px 14px; border-radius: 12px; background: var(--ebf-fondo, var(--bg-2)); border: 1px solid var(--ebf-borde, var(--line)); font-family: var(--font-sans); font-weight: 600; font-size: 13.5px; color: var(--ink); }
/* Cada nodo se enciende cuando el punto llega a él. Hace falta porque el punto
   va a x=45, o sea DENTRO de la caja del nodo: en cada parada queda tapado, y
   medido sólo se veía el 9% del ciclo, en tres destellos de 3% por los huecos.
   Sin esto, cuadrar las paradas no se notaría.
   Los colores salen de variables y no están escritos en los `@keyframes`: una
   animación pesa más que una declaración normal, así que valores fijos ahí se
   comerían el tema oscuro de la línea de abajo. */
.ebf-node { animation: ebnodo var(--ebf-ciclo) ease-in-out infinite; }
.ebf-node:nth-of-type(1) { animation-delay: 0s; }
.ebf-node:nth-of-type(2) { animation-delay: calc(var(--ebf-ciclo) * .28); }
.ebf-node:nth-of-type(3) { animation-delay: calc(var(--ebf-ciclo) * .56); }
.ebf-node:nth-of-type(4) { animation-delay: calc(var(--ebf-ciclo) * .84); }
@keyframes ebnodo {
  0%,  16% { border-color: var(--accent); background: var(--accent-soft); }
  24%, 100% { border-color: var(--ebf-borde, var(--line)); background: var(--ebf-fondo, var(--bg-2)); }
}
.ebf-node + .ebf-node { margin-top: 16px; }
html[data-theme="dark"] .ebf-line { background: rgba(255,255,255,.15); }
html[data-theme="dark"] .ebf-node { --ebf-fondo: rgba(255,255,255,.06); --ebf-borde: rgba(255,255,255,.1); color: #fff; }
.ebf-ic { width: 26px; height: 26px; border-radius: 50%; background: var(--accent); color: #fff; display: flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.ebf-ic svg { width: 13px; height: 13px; }
/* Cuatro paradas y tres tramos: 4×16 de espera + 3×12 de viaje = 100. */
@keyframes ebtravel {
  0%,   16% { top: var(--ebf-uno); }
  28%,  44% { top: calc(var(--ebf-uno) + var(--ebf-paso)); }
  56%,  72% { top: calc(var(--ebf-uno) + var(--ebf-paso) * 2); }
  84%, 100% { top: calc(var(--ebf-uno) + var(--ebf-paso) * 3); }
}
@media (prefers-reduced-motion: reduce) { .ebf-dot, .ebf-node { animation: none; } }

/* 2 · Campañas — mini calendario */
.ebcal { flex-direction: column; justify-content: center; gap: 6px; width: 100%; }
.ebcal-grid { display: grid; grid-template-columns: repeat(7,1fr); gap: 5px; }
.ebcal-cell { aspect-ratio: 1; border-radius: 5px; background: var(--bg-2); cursor: pointer; transition: background .2s ease, transform .15s ease; }
.ebcal-cell:hover { transform: scale(1.12); }
html[data-theme="dark"] .ebcal-cell { background: rgba(255,255,255,.07); }
.ebcal-cell.on { background: var(--accent); }
/* el override oscuro de arriba gana en especificidad → reafirmar el naranja del seleccionado */
html[data-theme="dark"] .ebcal-cell.on { background: var(--accent); }

/* 3 · Conoce mejor — tarjeta de cliente + tags de interés */
.ebcust { flex-direction: column; justify-content: center; gap: 16px; width: 100%; }
.ebc-row { display: flex; align-items: center; gap: 12px; }
.ebc-av { width: 38px; height: 38px; border-radius: 50%; flex: 0 0 auto; background: linear-gradient(150deg, var(--accent), #c23d18); }
.ebc-lines { display: flex; flex-direction: column; gap: 6px; flex: 1; }
.ebc-lines i { display: block; height: 7px; border-radius: 999px; background: var(--bg-2); }
.ebc-lines i:first-child { width: 52%; } .ebc-lines i:last-child { width: 80%; }
.ebc-tags { display: flex; flex-wrap: wrap; gap: 7px; }
.ebc-tags span { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .03em; padding: 4px 9px; border-radius: 999px; background: var(--bg-2); color: var(--ink-soft); cursor: pointer; user-select: none; transition: background .2s ease, color .2s ease; }
.ebc-tags span.on { background: var(--accent); color: #fff; }
html[data-theme="dark"] .ebc-lines i, html[data-theme="dark"] .ebc-tags span { background: rgba(255,255,255,.08); }
html[data-theme="dark"] .ebc-tags span.on { background: var(--accent); color: #fff; }

/* 4 · Que tus correos lleguen — bandeja con pestañas (cae en Principal) */
.ebinbox { flex-direction: column; justify-content: center; gap: 0; width: 100%; }
.ebi-tabs { display: flex; gap: 6px; padding-left: 2px; }
.ebi-tabs span { font-family: var(--font-mono); font-size: 10px; letter-spacing: .03em; padding: 6px 10px; border-radius: 8px 8px 0 0; background: var(--bg-2); color: var(--ink-faint); cursor: pointer; user-select: none; transition: background .2s ease, color .2s ease; }
.ebi-tabs span.on { background: var(--accent); color: #fff; }
html[data-theme="dark"] .ebi-tabs span { background: rgba(255,255,255,.07); }
html[data-theme="dark"] .ebi-tabs span.on { background: var(--accent); color: #fff; }
.ebi-mail { display: flex; align-items: center; gap: 11px; padding: 12px 13px; border-radius: 0 10px 10px 10px; background: var(--bg-2); border: 1px solid var(--line); }
html[data-theme="dark"] .ebi-mail { background: rgba(255,255,255,.07); }
.ebi-dot { width: 26px; height: 26px; border-radius: 50%; flex: 0 0 auto; background: var(--accent); }
.ebi-bars { flex: 1; display: flex; flex-direction: column; gap: 5px; }
.ebi-bars i { display: block; height: 6px; border-radius: 999px; background: var(--line); }
.ebi-bars i:first-child { width: 58%; } .ebi-bars i:last-child { width: 86%; }
.ebi-check { color: var(--accent); font-weight: 700; flex: 0 0 auto; }

/* 5 · Nos encargamos de todo — carrusel de foco (tarjeta alta, filas en blanco) */
.eb-todo .eb-art { border: 0; background: transparent; padding: 0; overflow: visible; }
/* en oscuro, .eb-art recibe un panel (rgba .04) por especificidad → reafirmar transparente (igual que en claro) */
html[data-theme="dark"] .eb-todo .eb-art { background: transparent; }
.ebcaro { flex: 1; display: flex; flex-direction: column; justify-content: space-between; gap: 11px; }
.ebcaro-row { display: flex; align-items: center; gap: 13px; padding: 11px 14px; border-radius: 12px; background: var(--bg); border: 1px solid var(--line); opacity: .5; cursor: pointer; transition: opacity .4s ease, transform .4s ease, border-color .4s ease, box-shadow .4s ease; }
/* sin relleno: que el borde defina la fila (como en claro, donde el relleno se funde con la tarjeta) */
html[data-theme="dark"] .ebcaro-row { background: transparent; }
.ebcaro-row.is-on { opacity: 1; border-color: var(--accent); transform: scale(1.03); box-shadow: 0 10px 26px rgba(22,19,15,.08); }
.ebcaro-ic { width: 34px; height: 34px; border-radius: 9px; flex: 0 0 auto; display: flex; align-items: center; justify-content: center; background: var(--bg-2); }
html[data-theme="dark"] .ebcaro-ic { background: rgba(255,255,255,.06); }
.ebcaro-ic svg { width: 22px; height: 22px; display: block; }
.ebcaro-lbl { font-family: var(--font-sans); font-weight: 600; font-size: 14px; color: var(--ink); }

@media (max-width: 820px) {
  .eml-bento { grid-template-columns: 1fr; grid-template-areas: "auto" "camp" "cono" "lleg" "todo"; }
  .eb-auto .eb-art { min-height: 200px; }
}

/* ---- herramientas · fila simple (Mailchimp · Klaviyo grande · Brevo) ---- */
.eml-tools { padding: var(--sp-sec) 0; text-align: center; }
.eml-tools .eyebrow { display: block; text-align: center; margin: 0 0 40px; font-family: var(--font-sans); font-size: var(--fs-eyebrow); font-weight: 500; letter-spacing: .04em; }
.eml-tools-row { display: flex; align-items: center; justify-content: center; gap: clamp(34px,6vw,80px); flex-wrap: wrap; }
.tlogo { display: block; width: auto; max-width: 100%; height: auto; }
.tool-side { height: clamp(20px,2.6vw,30px); }   /* Mailchimp y Brevo, ~mismo tamaño */
.tool-main { height: clamp(34px,4.8vw,54px); }   /* Klaviyo, mayor */
.tool-brevo { filter: brightness(0); }            /* Brevo en negro (no verde) */
/* modo oscuro: los logos oscuros se volverían invisibles → blanco */
html[data-theme="dark"] .eml-tools .tlogo { filter: brightness(0) invert(1); }
/* e-commerce: las tres plataformas en silueta, negra en claro y blanca en
   oscuro.  Sólo en esta página: en email-marketing los logos siguen a color.
   El modo oscuro ya lo resolvía la regla de arriba, que gana por especificidad
   (0,3,1 contra 0,3,0) aunque ésta venga después.
   OJO con las siluetas: sólo funcionan si los huecos del logo son transparentes
   de verdad.  La «s» de Shopify venía pintada de blanco y se fundía con la
   bolsa; se le vació el alfa el 1-sep (ver la trampa del logo de Notion). */
.page-ecommerce .eml-tools .tlogo { filter: brightness(0); }

/* carrusel "Nos encargamos de todo": pausa la animación con reduced-motion */
@media (prefers-reduced-motion: reduce) { .ebcaro-row { transition: none; } }

/* ==========================================================================
   S4 Especialista — testimonial editorial centrado
   ========================================================================== */
.eml-spec-e { padding: var(--sp-sec) 0; }
.eml-spec-e .container { max-width: 880px; text-align: center; }
.eml-spec-e h2 { font-size: var(--fs-section); line-height: 1.1; margin: 0 0 30px; }
/* email: estos dos títulos a una sola línea (desktop); vuelven a 2 líneas <1100px */
.eml-spec-e h2, body.page-email .faq-head h2 { white-space: nowrap; }
@media (max-width: 1100px) { .eml-spec-e h2, body.page-email .faq-head h2 { white-space: normal; } }
body.page-seo .faq-head, body.page-ecommerce .faq-head { max-width: none; }
body.page-seo .faq-head h2, body.page-ecommerce .faq-head h2 { white-space: nowrap; }   /* "Preguntas frecuentes sobre SEO…/…tiendas online" en 1 línea */
@media (max-width: 820px) { body.page-seo .faq-head h2, body.page-ecommerce .faq-head h2 { white-space: normal; } }
/* El avatar iba suelto entre la bajada y la cita, con 92px de aire por debajo:
   quedaba huérfano y el nombre solo, al final. Ahora va pegado encima del
   nombre y forman la firma, así que el margen de abajo se cierra a 12px. */
.ese-avatar { width: 74px; height: 74px; border-radius: 50%; margin: 0 auto 12px; background: linear-gradient(150deg, var(--accent), #c23d18); color: #fff; display: flex; align-items: center; justify-content: center; font-family: var(--font-serif); font-size: 30px; }
/* comillas blocky (estilo manifiesto de Nosotros): abre arriba, cierra abajo girada */
.ese-qm { display: block; color: var(--ink); opacity: .15; user-select: none; }
.ese-qm .qg { display: inline-block; font-family: var(--font-head); font-weight: 800; font-size: 64px; line-height: 1; }
.ese-qm-open { text-align: left; }                                /* abre: izquierda del todo */
.ese-qm-close { text-align: right; margin: 8px 0 16px; }          /* cierra: derecha del todo */
.ese-qm-close .qg { transform: rotate(180deg); }                  /* gira SOLO el símbolo, no el bloque */
/* quote a 3 líneas (desktop): ancho ~40ch */
.ese-quote { font-family: var(--font-serif); font-weight: 500; font-size: clamp(22px,2.7vw,32px); line-height: 1.32; color: var(--ink); margin: 2px auto; max-width: 40ch; }
.ese-name { font-family: var(--font-sans); font-weight: 700; font-size: 16px; color: var(--ink); margin: 0; }
.ese-role { font-family: var(--font-sans); font-size: 14px; color: var(--ink-soft); margin: 4px 0 0; }
.ese-role a { color: var(--accent); }
/* bio a 4 líneas (desktop): ancho ~76ch */
.ese-bio { color: var(--ink-soft); font-size: var(--fs-body); line-height: 1.65; max-width: 76ch; margin: 46px auto 0; }

/* ==========================================================================
   PÁGINA SEO (seo.html) — hero multi-superficie/ranking, escaparate, servicios, sinergia
   ========================================================================== */

/* etiquetas de comparación (temporales, borrar al colapsar variantes) */
.cmp-tag { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); background: var(--accent-soft, rgba(247,86,43,.1)); border: 1px dashed rgba(247,86,43,.4); border-radius: 999px; padding: 4px 12px; display: inline-block; margin: 0 0 12px; }
.cmp-tag-wide { margin: 38px 0 18px; }

/* ---- S1 HERO · dos visuales para comparar ---- */
.seo-hero-compare { display: flex; flex-direction: column; gap: 26px; }
.cmp-block { display: flex; flex-direction: column; align-items: flex-start; }

/* Variante A · superficies (Google/Maps/IA) */
.seo-surfaces { display: flex; flex-direction: column; gap: 12px; width: 100%; }
.seo-surface { display: flex; align-items: center; gap: 13px; padding: 14px 16px; border-radius: 16px; background: var(--bg-2); border: 1px solid var(--line); opacity: .55; transform: translateY(0); transition: opacity .45s ease, transform .45s ease, border-color .45s ease, box-shadow .45s ease; }
html[data-theme="dark"] .seo-surface { background: rgba(255,255,255,.04); }
.seo-surface.is-on { opacity: 1; border-color: var(--accent); transform: scale(1.03); box-shadow: 0 12px 30px rgba(22,19,15,.10); }
.ss-google { flex-direction: column; align-items: stretch; gap: 10px; }
.ssg-bar { display: flex; align-items: center; gap: 9px; padding: 8px 12px; border-radius: 999px; background: var(--bg); border: 1px solid var(--line); font-family: var(--font-sans); font-size: 13px; color: var(--ink-soft); }
.ssg-bar svg { width: 15px; height: 15px; color: var(--ink-faint); flex: 0 0 auto; }
.ssg-res { display: flex; align-items: flex-start; gap: 11px; }
.ssg-rank { flex: 0 0 auto; width: 24px; height: 24px; border-radius: 7px; background: var(--accent); color: #fff; font-family: var(--font-sans); font-weight: 700; font-size: 13px; display: flex; align-items: center; justify-content: center; }
.ssg-meta { flex: 1; min-width: 0; }
.ssg-title { font-family: var(--font-sans); font-weight: 600; font-size: 14.5px; color: var(--ink); margin: 0 0 3px; }
.ssg-url { font-family: var(--font-mono); font-size: 11px; color: #1a8a4a; margin: 0 0 7px; }
.ssg-line { display: block; height: 6px; width: 88%; border-radius: 999px; background: var(--line); }
.ssm-pin { flex: 0 0 auto; width: 40px; height: 40px; border-radius: 11px; background: rgba(247,86,43,.12); color: var(--accent); display: flex; align-items: center; justify-content: center; }
.ssm-pin svg { width: 22px; height: 22px; }
.ssm-name { font-family: var(--font-sans); font-weight: 700; font-size: 15px; color: var(--ink); margin: 0 0 2px; }
.ssm-sub { font-family: var(--font-sans); font-size: 12.5px; color: var(--ink-soft); margin: 0; }
.ssm-sub b { color: var(--accent); }
.ssa-ic { flex: 0 0 auto; width: 40px; height: 40px; border-radius: 50%; background: linear-gradient(150deg, var(--accent), #c23d18); color: #fff; display: flex; align-items: center; justify-content: center; }
.ssa-ic svg { width: 21px; height: 21px; }
.ssa-txt { font-family: var(--font-serif); font-style: italic; font-size: 15.5px; color: var(--ink); margin: 0; }
.ssa-txt b { font-style: normal; color: var(--accent); }

/* Variante B · ascenso de ranking */
.seo-rank { width: 100%; max-width: 380px; padding: 22px 24px 18px; border-radius: 20px; background: var(--bg-2); border: 1px solid var(--line); }
html[data-theme="dark"] .seo-rank { background: rgba(255,255,255,.04); }
.srk-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 14px; }
.srk-label { font-family: var(--font-mono); font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); }
.srk-pos { font-family: var(--font-serif); font-weight: 600; font-size: 34px; color: var(--accent); line-height: 1; }
.srk-chart { position: relative; display: flex; align-items: flex-end; justify-content: space-between; gap: 10px; height: 120px; }
.srk-bar { flex: 1; height: var(--h); border-radius: 7px 7px 0 0; background: var(--line); transform-origin: bottom; animation: srkGrow 1.1s cubic-bezier(.2,.8,.2,1) both; }
.srk-bar:nth-child(2){ animation-delay:.08s } .srk-bar:nth-child(3){ animation-delay:.16s } .srk-bar:nth-child(4){ animation-delay:.24s } .srk-bar:nth-child(5){ animation-delay:.32s }
.srk-bar.is-top { background: linear-gradient(180deg, var(--accent), #ff8a5c); }
.srk-line { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.srk-line path { fill: none; stroke: var(--accent); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 240; stroke-dashoffset: 240; animation: srkDraw 1.5s ease .3s forwards; }
.srk-dot { position: absolute; top: 5%; right: 0; width: 11px; height: 11px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 4px rgba(247,86,43,.22); transform: translate(40%,-40%); opacity: 0; animation: srkDot .4s ease 1.7s forwards; }
.srk-foot { font-family: var(--font-sans); font-size: 12.5px; color: var(--ink-soft); margin: 14px 0 0; text-align: center; }
@keyframes srkGrow { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes srkDraw { to { stroke-dashoffset: 0; } }
@keyframes srkDot { to { opacity: 1; } }

/* hero SEO sin visual: el contenedor llena el ancho (si no, al ser flex-item encoge a su
   contenido y margin:auto lo centra) y el texto queda alineado a la izquierda como el resto */
.page-seo .svc-hero .container { grid-template-columns: 1fr; width: 100%; }
/* el nav flotante tapa los ~134px de arriba; padding-top responsivo para centrar el
   contenido en el espacio visible (bajo el nav) en cualquier alto de pantalla */
.page-seo .svc-hero { padding-top: clamp(120px, calc(50vh - 186px), 186px); }
.page-seo .svc-hero-text { max-width: 880px; }          /* el titular cabe en 3 líneas */
.page-seo .svc-hero-text .lead { max-width: 600px; }    /* el apoyo sigue como columna legible */

/* El fundido de 180px del pie del hero se apaga donde hay fondo áureo: se
   comía la raya de abajo de la caja y el tramo final de la espiral. Estaba para
   difuminar el degradado del hero contra el fondo de la página, y aquí no hay
   degradado que difuminar — `.oro` ya pinta `--bg` plano. */
.svc-hero:has(.oro)::after { content: none; }

/* ---- El CTA con la retícula de puntos --------------------------------
   La misma del CTA de la home, pero con el lienzo DENTRO de la sección.  En la
   home hay un único `.dots-bg` `fixed` para toda la página, y eso obliga a que
   cada sección de en medio la tape con fondo opaco Y estando posicionada — un
   `fixed` pinta por encima de cualquier `static`.  Para una sola sección ese
   montaje no compensa: metido dentro, sólo se ve donde tiene que verse.

   Los dos degradados de los bordes vienen de la home y no son decoración: sin
   ellos la retícula termina en seco justo en la costura con la FAQ. */
.cta:has(.cta-dots) {
  position: relative; overflow: hidden;
  background: var(--bg);
}
.cta-dots { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.cta-dots .hero-dots { display: block; width: 100%; height: 100%; }
.cta:has(.cta-dots) > .container { position: relative; z-index: 2; }
.cta:has(.cta-dots)::before, .cta:has(.cta-dots)::after {
  content: ''; position: absolute; left: 0; right: 0;
  height: clamp(70px, 11vh, 140px);
  pointer-events: none; z-index: 1;
}
.cta:has(.cta-dots)::before { top: 0;    background: linear-gradient(180deg, var(--bg) 0%, transparent 100%); }
.cta:has(.cta-dots)::after  { bottom: 0; background: linear-gradient(180deg, transparent 0%, var(--bg) 100%); }

/* Titular y apoyo del CTA, en una línea cada uno.  Los partían sus topes: 16ch
   el titular (418px) y 620px el apoyo, cuando la tinta mide 728 y 750px.
   Por debajo de 880px vuelven a partir y recuperan su tope: 750px de tinta más
   los 24px de padding a cada lado dejan de caber ahí. */
.page-seo .cta .cta-title,
.page-seo .cta .lead { max-width: none; white-space: nowrap; }
@media (max-width: 880px) {
  .page-seo .cta .cta-title { white-space: normal; max-width: 16ch; }
  .page-seo .cta .lead      { white-space: normal; max-width: 620px; }
}

/* Lo mismo en webs.  Aquí el titular es un `h2`, no un `.cta-title`, y el apoyo
   ya entraba en una línea por los pelos —596px de tinta contra 620 de tope—,
   así que se le quita el tope para que no dependa de eso.  El titular mide 524.
   OJO: la regla que había para esto, `body.page-disenoweb .cta h2`, NUNCA se
   aplicó: la clase del body es `page-webs`. Ver el aviso del 1-sep. */
.page-webs .cta h2,
.page-webs .cta .lead { max-width: none; white-space: nowrap; }
@media (max-width: 700px) {
  .page-webs .cta h2   { white-space: normal; max-width: 16ch; }
  .page-webs .cta .lead { white-space: normal; max-width: 620px; }
}

/* Formacion: el apoyo del CTA son 78 caracteres y su tope de 620px lo partia
   en dos.  El titular ya entraba en una linea. */
.page-formacion-ia .cta .lead { max-width: none; white-space: nowrap; }
@media (max-width: 820px) {
  .page-formacion-ia .cta .lead { white-space: normal; max-width: 620px; }
}

/* En e-commerce el titular del CTA es el mismo del hero y mide 62 caracteres:
   en una línea se saldría, y con el tope de 16ch caía a cuatro.  Se le da
   sitio para dos y se deja que `balance` reparta la tinta entre ellas.
   `min(…, 100%)` porque 34ch de serifa grande no caben en un móvil. */
.page-ecommerce .cta .cta-title { max-width: min(34ch, 100%); text-wrap: balance; }

/* ---- Fondo áureo de los heroes de servicio ---------------------------
   NO es sólo de SEO aunque viva en el bloque de SEO: lo usan las SEIS páginas
   de servicio, con el marcado en template-parts/fondo-aureo.php.
   Puerto del FONDO de hero-01 (ncdai).  Sustituye a las tres manchas
   desenfocadas; el degradado del hero queda tapado, que el dibujo pide fondo
   plano.  `--grad-hero` NO se toca: lo comparten seis secciones más.

   La caja tiene que ser un rectángulo áureo EXACTO o los cuadrantes de la
   espiral salen elípticos: por eso `aspect-ratio` con los mismos números que
   el viewBox, y `meet`, nunca `none`.  Las diagonales de puntos se salen del
   marco a propósito (`overflow: visible` en el SVG); quien recorta es `.oro`,
   y por eso ahí sí hay `overflow: hidden` — sin él las rayas de sangrado se
   llevarían la página al desbordamiento horizontal. */
/* El fondo plano lo pone la propia capa, no una regla por página: `.oro` es
   opaca y cubre el degradado del hero, así que basta con poner el parcial.
   Antes iba con `.page-seo .svc-hero { background }`, y eso obligaba a añadir
   un selector por cada servicio nuevo — y a acertar con la clase de body, que
   no es evidente: la de webs.php es `page-disenoweb`. */
.oro {
  position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg);
  /* El techo deja pasar la cabecera.  El hero arranca 120px por DEBAJO del
     borde inferior de la barra (`margin-top: -120px` en `.svc-hero`), así que
     sin este hueco la caja se centra contando ese trozo tapado y la barra se
     come la esquina de arriba con los cuadrados pequeños — que es la parte que
     más se mira.  Medido: la barra acaba a 120px del techo del hero en todas
     las alturas de ventana, porque es pegajosa. 16px más de aire. */
  --oro-techo: 136px;
  padding: var(--oro-techo) 24px 24px;
  container-type: size;   /* para que la caja pueda consultar el hueco que le queda */
}
/* La caja se topa por los DOS lados: por ancho y por alto.  Antes sólo por
   ancho, y en una pantalla baja —un portátil de 830px— la caja medía 791 de
   alto y no cabía debajo de la barra por mucho techo que se pusiera.
   `100cqh * 340 / 210` es el ancho que tendría si el alto fuese el límite; gana
   el menor de los tres.  Las unidades `cq*` van contra el CONTENIDO de `.oro`,
   o sea ya descontado el techo. */
.oro-caja {
  position: relative;
  width: min(100cqw, 1280px, 100cqh * 340 / 210);
  aspect-ratio: 340 / 210;
  border-left: 1px solid var(--line);
  border-right: 1px solid var(--line);
}
/* Las dos horizontales sangran hasta el borde de la pantalla, como en el
   original: es lo que hace que la caja se lea como un corte de la página y no
   como una tarjeta suelta. */
.oro-caja::before, .oro-caja::after {
  content: ""; position: absolute; left: calc(50% - 50vw); right: calc(50% - 50vw);
  height: 1px; background: var(--line);
}
.oro-caja::before { top: -1px; }
.oro-caja::after { bottom: -1px; }

.oro-trazo {
  position: absolute; inset: 0; width: 100%; height: 100%;
  overflow: visible; color: var(--line);
}
.oro-espiral { color: var(--ink-faint); opacity: .55; }
.oro-v { display: none; }

/* El halo del cursor: la MISMA geometría, en naranja, tapada entera salvo por
   un agujero redondo que sigue al ratón.  Se tiñen las formas y sólo las
   formas — el fondo no se toca, que es lo que lo separa del típico foco de luz
   sobre la sección.  El disco lleva un 45% macizo y de ahí se desvanece: con
   borde duro se ve el círculo, y ver el círculo mata el efecto.
   La posición la escribe el JS del parcial en `--oro-x` / `--oro-y`. */
.oro-halo {
  position: absolute; inset: 0;
  opacity: 0; transition: opacity .4s ease;
  -webkit-mask-image: radial-gradient(circle var(--oro-r, 120px) at var(--oro-x, -999px) var(--oro-y, -999px), #000 0%, #000 45%, transparent 100%);
          mask-image: radial-gradient(circle var(--oro-r, 120px) at var(--oro-x, -999px) var(--oro-y, -999px), #000 0%, #000 45%, transparent 100%);
}
.oro-caja.oro-on .oro-halo { opacity: 1; }
.oro-halo .oro-trazo { color: var(--accent); }
.oro-halo .oro-espiral { color: var(--accent); opacity: .9; }
@media (prefers-reduced-motion: reduce) { .oro-halo { display: none; } }
@media (max-width: 767px) {
  .oro { --oro-techo: 120px; padding: var(--oro-techo) 16px 16px; }
  .oro-caja { aspect-ratio: 210 / 340; width: min(100cqw, 520px, 100cqh * 210 / 340); }
  .oro-h { display: none; }
  .oro-v { display: block; }
}

/* ---- S2 · SEO en Galicia · escaparate ---- */
.seo-window { padding: var(--sp-sec) 0; }
.seo-window-grid { display: grid; grid-template-columns: .95fr 1.05fr; gap: clamp(32px,5vw,72px); align-items: center; }
/* Visual a la izquierda, texto a la derecha (2026-07-08) */
.seo-window-grid .seo-window-text { order: 2; }
.seo-window-grid .seo-window-visual { order: 1; }
.seo-window-text h2 { font-family: var(--font-sans); font-size: var(--fs-eyebrow); font-weight: 500; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); line-height: 1.4; margin: 0 0 16px; }
.seo-window-big { font-size: var(--fs-section); font-weight: 500; line-height: 1.1; color: var(--ink); margin: 0 0 20px; max-width: 26ch; text-wrap: balance; }   /* 2 líneas */
.seo-window-text .lead { margin: 0; }
.seo-window-visual { display: flex; flex-direction: column; gap: 14px; }
.seo-serp { position: relative; padding: 18px; border-radius: 20px; background: var(--bg-2); border: 1px solid var(--line); }
html[data-theme="dark"] .seo-serp { background: rgba(255,255,255,.04); }
.srp-bar { display: flex; align-items: center; gap: 10px; padding: 11px 16px; border-radius: 999px; background: var(--bg); border: 1px solid var(--line); font-family: var(--font-sans); font-size: 14px; color: var(--ink-soft); margin-bottom: 14px; }
.srp-bar svg { width: 16px; height: 16px; color: var(--ink-faint); flex: 0 0 auto; }
.srp-list { display: flex; flex-direction: column; gap: 10px; }
.srp-res { display: flex; align-items: flex-start; gap: 12px; padding: 14px 15px; border-radius: 14px; background: var(--bg); border: 1px solid var(--line); transition: opacity .3s ease; }
html[data-theme="dark"] .srp-res { background: rgba(255,255,255,.03); }
.srp-res:not(.srp-you) { opacity: .45; }
.srp-you { border-color: var(--accent); animation: srpClick 3.6s ease-in-out infinite; }
.srp-rank { flex: 0 0 auto; width: 26px; height: 26px; border-radius: 7px; background: var(--accent); color: #fff; font-family: var(--font-sans); font-weight: 700; font-size: 14px; display: flex; align-items: center; justify-content: center; }
.srp-meta { flex: 1; min-width: 0; }
.srp-title { font-family: var(--font-sans); font-weight: 600; font-size: 15px; color: var(--ink); margin: 0 0 3px; }
.srp-url { font-family: var(--font-mono); font-size: 11.5px; color: #1a8a4a; margin: 0 0 8px; }
.srp-line { display: block; height: 7px; width: 90%; border-radius: 999px; background: var(--line); }
.srp-l { display: block; height: 7px; border-radius: 999px; background: var(--line); }
.srp-l1 { width: 55%; margin-bottom: 7px; }
.srp-l2 { width: 82%; }
.srp-cursor { position: absolute; left: 50%; top: 96px; color: var(--ink); pointer-events: none; animation: srpCursor 3.6s ease-in-out infinite; }
.srp-cursor svg { width: 22px; height: 22px; filter: drop-shadow(0 2px 4px rgba(0,0,0,.28)); }
html[data-theme="dark"] .srp-cursor { color: #fff; }
@keyframes srpCursor { 0% { transform: translate(95px,72px); } 34% { transform: translate(0,0); } 42% { transform: translate(0,5px); } 50% { transform: translate(0,0); } 72% { transform: translate(0,0); } 100% { transform: translate(95px,72px); } }
@keyframes srpClick { 0%,38% { box-shadow: none; } 44% { box-shadow: 0 0 0 4px rgba(247,86,43,.2); transform: scale(.99); } 54% { transform: scale(1); } 72% { box-shadow: 0 8px 22px rgba(247,86,43,.16); } 100% { box-shadow: none; } }

/* contenidos · snippet de Google optimizado */
.sv-snippet { flex-direction: column; align-items: stretch; justify-content: center; gap: 5px; text-align: left; }
.snp-title { font-family: var(--font-sans); font-weight: 600; font-size: 15px; line-height: 1.3; color: #1a4fb5; margin: 0; }
.snp-title span { color: #1a4fb5; }
html[data-theme="dark"] .snp-title, html[data-theme="dark"] .snp-title span { color: #6f9bff; }
.snp-url { font-family: var(--font-mono); font-size: 11.5px; color: #1a8a4a; margin: 2px 0 6px; }
.snp-desc { font-family: var(--font-sans); font-size: 13px; line-height: 1.5; color: var(--ink-soft); margin: 0; }
.snp-desc b { font-weight: 600; color: var(--ink); box-shadow: inset 0 -7px 0 rgba(247,86,43,.22); animation: snpMark 3s ease-in-out infinite; }
@keyframes snpMark { 0%,100% { box-shadow: inset 0 -3px 0 rgba(247,86,43,.2); } 50% { box-shadow: inset 0 -9px 0 rgba(247,86,43,.3); } }

/* contenidos · marcador que resalta una frase clave (animado) */
.sv-mark { flex-direction: column; align-items: stretch; justify-content: center; gap: 12px; }
.mk-l { display: block; height: 8px; border-radius: 999px; background: var(--bg-2); }
html[data-theme="dark"] .mk-l { background: rgba(255,255,255,.08); }
.mk-hl { position: relative; display: flex; align-items: center; height: 18px; }
.mk-fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; border-radius: 5px; background: rgba(247,86,43,.30); animation: mkSweep 3s ease-in-out infinite; }
.mk-txt { position: relative; z-index: 1; height: 8px; width: 74%; border-radius: 999px; background: var(--ink-faint); }
.mk-pen { position: absolute; top: 50%; left: 0; width: 7px; height: 22px; border-radius: 2px; background: var(--accent); transform: translate(-2px,-50%) rotate(8deg); box-shadow: 0 3px 9px rgba(247,86,43,.4); animation: mkPen 3s ease-in-out infinite; }
@keyframes mkSweep { 0% { width: 0; } 55% { width: 78%; } 82% { width: 78%; } 100% { width: 0; } }
@keyframes mkPen { 0% { left: 0; } 55% { left: 78%; } 82% { left: 78%; } 100% { left: 0; } }

/* contenidos · artículo estructurado para SEO (H1/H2/¶ + palabra clave) */
.sv-article { flex-direction: column; align-items: stretch; justify-content: center; gap: 9px; }
.art-row { display: flex; align-items: center; gap: 9px; }
.art-tag { flex: 0 0 auto; font-family: var(--font-mono); font-size: 9px; font-weight: 600; letter-spacing: .04em; color: var(--accent); background: rgba(247,86,43,.12); border-radius: 5px; padding: 3px 7px; }
.art-bar { display: block; height: 8px; border-radius: 999px; background: var(--bg-2); }
html[data-theme="dark"] .art-bar { background: rgba(255,255,255,.08); }
.art-head { height: 11px; background: var(--ink-faint); }
.art-line-kw { display: flex; align-items: center; gap: 6px; }
.art-kw { display: block; height: 11px; width: 30%; border-radius: 4px; background: rgba(247,86,43,.3); animation: artKw 2.8s ease-in-out infinite; }
@keyframes artKw { 0%,100% { background: rgba(247,86,43,.22); box-shadow: 0 0 0 0 rgba(247,86,43,0); } 50% { background: rgba(247,86,43,.5); box-shadow: 0 0 0 3px rgba(247,86,43,.13); } }

/* ---- S3 · Servicios de SEO ---- */
/* sin padding-bottom: el hueco tras el CTA lo dan su margin-top y el padding-top de .seo-team (simétrico) */
.seo-svc { padding: var(--sp-sec) 0 0; }
.seo-svc-head { margin: 0 0 50px; }
.seo-svc-head h2 { font-family: var(--font-sans); font-size: var(--fs-eyebrow); font-weight: 500; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); line-height: 1.4; margin: 0 0 14px; }
.seo-svc-head .svc-sub { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-section); line-height: 1.1; color: var(--ink); margin: 0; max-width: 22ch; }
.seo-h3 { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-h3); line-height: 1.2; margin: 0; color: var(--ink); }

/* Variante A · índice fijo + visual */
.seo-idx { display: grid; grid-template-columns: 1fr 1.1fr; gap: 28px; align-items: start; }
.seo-idx-list { display: flex; flex-direction: column; gap: 6px; position: sticky; top: 96px; }
.sil-row { display: flex; align-items: center; gap: 14px; text-align: left; padding: 16px 16px; border-radius: 14px; background: transparent; border: 1px solid transparent; cursor: pointer; transition: background .25s ease, border-color .25s ease, transform .25s ease; }
.sil-row:hover { background: var(--bg-2); }
.sil-row.is-on { background: var(--bg-2); border-color: var(--line); }
html[data-theme="dark"] .sil-row.is-on, html[data-theme="dark"] .sil-row:hover { background: rgba(255,255,255,.05); }
.sil-row.is-on .seo-h3 { color: var(--accent); }
.seo-idx-panel { position: relative; min-height: 320px; }
.sip-card { position: absolute; inset: 0; opacity: 0; visibility: hidden; transform: translateY(10px); transition: opacity .4s ease, transform .4s ease; display: flex; flex-direction: column; }
.sip-card.is-on { opacity: 1; visibility: visible; transform: none; position: relative; }
.sip-d { color: var(--ink-soft); font-size: var(--fs-body); line-height: 1.55; margin: 20px 0 0; }
.sip-link { color: var(--accent); font-weight: 600; white-space: nowrap; }

/* Variante B · bento de 8 */
.seo-bento { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.sb-card { display: flex; flex-direction: column; background: var(--bg-2); border: 1px solid var(--line); border-radius: 20px; padding: 22px 22px 24px; transition: transform .25s ease, box-shadow .25s ease; }
html[data-theme="dark"] .sb-card { background: rgba(255,255,255,.03); }
.sb-card:hover { transform: translateY(-3px); box-shadow: 0 16px 38px rgba(22,19,15,.08); }
.sb-wide { grid-column: span 1; }
.sb-h { margin: 0 0 8px; }
.sb-d { color: var(--ink-soft); font-size: var(--fs-body); line-height: 1.58; margin: 0; }

/* Variante B · línea de tiempo central en zigzag */
.seo-timeline { position: relative; max-width: 940px; margin: 42px auto 0; }
.seo-timeline::before { content: ''; position: absolute; left: 50%; top: 8px; bottom: 8px; width: 2px; background: var(--line); transform: translateX(-50%); }
.tl-item { position: relative; width: 50%; padding: 0 44px; margin-bottom: 0; opacity: 0; transform: translateY(28px); transition: opacity .6s ease, transform .6s ease; }
/* zigzag solapado: cada hito (lado opuesto) arranca a media altura del anterior → menos scroll */
.tl-item + .tl-item { margin-top: -120px; }
.tl-item.is-in { opacity: 1; transform: none; }
.tl-left { left: 0; }
.tl-right { left: 50%; }
.tl-node { position: absolute; top: 28px; width: 16px; height: 16px; border-radius: 50%; background: var(--accent); border: 3px solid var(--bg); box-shadow: 0 0 0 3px rgba(247,86,43,.18); z-index: 1; }
.tl-left .tl-node { right: -8px; }
.tl-right .tl-node { left: -8px; }
.tl-card { background: var(--bg-2); border: 1px solid var(--line); border-radius: 20px; padding: 22px 22px 24px; }
html[data-theme="dark"] .tl-card { background: rgba(255,255,255,.03); }
.tl-card .sv { min-height: 150px; }
@media (max-width: 760px) {
  .seo-timeline::before { left: 19px; }
  .tl-item { width: 100%; left: 0; padding: 0 0 0 50px; margin-bottom: 22px; }
  .tl-item + .tl-item { margin-top: 0; }
  .tl-right { left: 0; }
  .tl-left .tl-node, .tl-right .tl-node { left: 11px; right: auto; }
}

/* visuales reutilizables de servicio (.sv) */
.sv { position: relative; border-radius: 14px; background: var(--bg); border: 1px solid var(--line); overflow: hidden; display: flex; align-items: center; justify-content: center; padding: 18px; margin-bottom: 16px; }
html[data-theme="dark"] .sv { background: rgba(255,255,255,.04); }
.seo-idx-panel .sv { min-height: 215px; }
.sb-card .sv { min-height: 132px; }
/* auditoría */
.sv-audit { flex-direction: column; align-items: stretch; gap: 10px; }
.sv-audit i { display: block; height: 8px; border-radius: 999px; background: var(--bg-2); }
html[data-theme="dark"] .sv-audit i { background: rgba(255,255,255,.08); }
.sv-scan { position: absolute; left: 14px; right: 14px; top: 18px; height: 2px; background: var(--accent); box-shadow: 0 0 12px 2px rgba(247,86,43,.4); animation: svScan 2.6s ease-in-out infinite; }
@keyframes svScan { 0%,100% { top: 18px; } 50% { top: calc(100% - 18px); } }
/* palabras clave */
.sv-kw { flex-direction: column; align-items: stretch; gap: 12px; }
.kw-bar { display: flex; align-items: center; gap: 8px; padding: 9px 13px; border-radius: 999px; background: var(--bg-2); border: 1px solid var(--line); font-family: var(--font-sans); font-size: 12.5px; color: var(--ink-soft); overflow: hidden; min-height: 36px; }
.kw-bar svg { width: 14px; height: 14px; color: var(--ink-faint); flex: 0 0 auto; }
.kw-type { white-space: nowrap; }
.kw-caret { display: inline-block; width: 2px; height: 14px; margin-left: 1px; background: var(--accent); vertical-align: -2px; animation: kwBlink 1s steps(1) infinite; }
@keyframes kwBlink { 0%,50% { opacity: 1; } 50.01%,100% { opacity: 0; } }
.kw-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.kw-chips b { font-family: var(--font-mono); font-size: 10.5px; font-weight: 500; padding: 4px 9px; border-radius: 999px; background: var(--bg-2); color: var(--ink-soft); }
html[data-theme="dark"] .kw-chips b { background: rgba(255,255,255,.08); }
.kw-chips b.on { background: var(--accent); color: #fff; }
/* SEO técnico (medidor de velocidad) */
.sv-tech { flex-direction: column; gap: 16px; }
.gauge { position: relative; width: 78%; height: 12px; border-radius: 999px; background: var(--bg-2); }
html[data-theme="dark"] .gauge { background: rgba(255,255,255,.08); }
.gauge-fill { position: absolute; left: 0; top: 0; height: 100%; width: 0; border-radius: 999px; background: linear-gradient(90deg, var(--accent), #ff8a5c); animation: gaugeLoad 2.4s ease-in-out infinite; }
.gauge-needle { position: absolute; top: 50%; right: -7px; width: 15px; height: 15px; border-radius: 50%; background: #fff; border: 3px solid var(--accent); transform: translateY(-50%); box-shadow: 0 2px 8px rgba(0,0,0,.16); }
.gauge-lbl { font-family: var(--font-mono); font-size: 11px; letter-spacing: .03em; color: var(--ink-soft); }
@keyframes gaugeLoad { 0% { width: 0; } 70% { width: 100%; } 100% { width: 100%; } }
/* contenidos */
.sv-content { flex-direction: column; align-items: stretch; gap: 9px; }
.sv-content i { display: block; height: 7px; border-radius: 999px; background: var(--bg-2); }
html[data-theme="dark"] .sv-content i { background: rgba(255,255,255,.08); }
.sv-content i.accent { background: var(--accent); }
.doc-pen { position: absolute; right: 16px; bottom: 14px; width: 20px; height: 20px; border-radius: 4px 4px 4px 9px; background: var(--accent); transform: rotate(45deg); box-shadow: 0 4px 12px rgba(247,86,43,.3); }
/* SEO local */
.sv-local { overflow: hidden; padding: 0; }
.city { position: absolute; inset: 0; width: 100%; height: 100%; }
.ct-block { fill: var(--bg-2); }
html[data-theme="dark"] .ct-block { fill: rgba(255,255,255,.06); }
.ct-road { stroke: var(--line); stroke-width: 3; }
.ct-ave { stroke-width: 4; opacity: .85; }
.map-pin { position: relative; z-index: 2; color: var(--accent); animation: pinBob 2.4s ease-in-out infinite; }
.map-pin::after { content: ''; position: absolute; left: 50%; bottom: -7px; transform: translateX(-50%); width: 30px; height: 10px; border-radius: 50%; background: radial-gradient(ellipse, rgba(247,86,43,.4), transparent 70%); }
.map-pin svg { width: 42px; height: 42px; filter: drop-shadow(0 7px 11px rgba(247,86,43,.38)); }
@keyframes pinBob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
/* off page (grafo de enlaces) */
.sv-links svg { width: 100%; max-width: 270px; height: auto; }
.sv-links line { stroke: var(--line); stroke-width: 2; }
.sv-links .lk-2 { opacity: .55; stroke-dasharray: 3 4; }
.sv-links .nd { fill: var(--ink-faint); transform-box: fill-box; transform-origin: center; animation: ndPulse 2.4s ease-in-out infinite; animation-delay: var(--d, 0s); }
.sv-links .nd-c { fill: var(--accent); }
@keyframes ndPulse { 0%,100% { opacity: .5; transform: scale(1); } 50% { opacity: 1; transform: scale(1.18); } }
/* GEO */
.sv-geo { gap: 14px; }
.geo-spark { flex: 0 0 auto; display: flex; align-items: center; justify-content: center; }
.geo-spark svg { width: 42px; height: 42px; filter: drop-shadow(0 4px 11px rgba(120,90,255,.38)); animation: gemTwinkle 2.6s ease-in-out infinite; }
@keyframes gemTwinkle { 0%,100% { transform: scale(1) rotate(0deg); } 50% { transform: scale(1.12) rotate(10deg); } }
.geo-bubble { font-family: var(--font-serif); font-style: italic; font-size: 14.5px; color: var(--ink); padding: 10px 14px; border-radius: 14px 14px 14px 4px; background: var(--bg-2); border: 1px solid var(--line); }
html[data-theme="dark"] .geo-bubble { background: rgba(255,255,255,.06); }
.geo-bubble b { font-style: normal; color: var(--accent); }
/* mejora continua (línea ascendente) */
.sv-grow { position: relative; }
.grow-svg { width: 100%; height: 100%; position: absolute; inset: 0; }
.grow-area { fill: rgba(247,86,43,.13); }
.grow-line { fill: none; stroke: var(--accent); stroke-width: 2.8; stroke-linecap: round; stroke-linejoin: round; }
.grow-pt { position: absolute; width: 9px; height: 9px; border-radius: 50%; background: var(--accent); transform: translate(-50%,-50%); opacity: .3; animation: growPt 3s ease-in-out infinite; }
@keyframes growPt { 0%,100% { opacity: .3; box-shadow: 0 0 0 0 rgba(247,86,43,0); } 45% { opacity: 1; box-shadow: 0 0 0 5px rgba(247,86,43,.2); } }

/* párrafo destacado · diseño web SEO */
/* CTA → diseño web · tarjeta oscura: texto ancho (mín. líneas) izq. + botón a la derecha + destello naranja */
.seo-webcta { position: relative; display: flex; align-items: center; justify-content: space-between; gap: clamp(32px,5vw,72px); margin-top: 92px; padding: clamp(40px,4.5vw,60px); border-radius: 24px; background: #15151b; border: 1px solid rgba(247,86,43,.30); box-shadow: 0 30px 80px rgba(0,0,0,.42); text-decoration: none; overflow: hidden; transition: transform .3s ease, box-shadow .3s ease; }
/* destello naranja (estilo variante A) ocupando el lado derecho */
.seo-webcta::before { content: ''; position: absolute; right: 2%; top: -32%; width: 560px; height: 560px; border-radius: 50%; background: radial-gradient(circle, rgba(247,86,43,.34), transparent 64%); pointer-events: none; }
.seo-webcta:hover { transform: translateY(-3px); box-shadow: 0 36px 92px rgba(0,0,0,.5); }
.swc-text { position: relative; z-index: 1; }   /* sin tope de ancho: el texto se ensancha → menos líneas */
.swc-title { font-size: var(--fs-section); font-weight: 500; line-height: 1.1; color: #FAFAFA; margin: 0 0 14px; }
.swc-desc { font-family: var(--font-sans); font-size: var(--fs-body); line-height: 1.6; color: rgba(255,255,255,.74); margin: 0; }
.swc-btn { position: relative; z-index: 1; flex: 0 0 auto; display: inline-flex; align-items: center; gap: 9px; padding: 16px 30px; border-radius: 999px; background: var(--accent); color: #fff; font-family: var(--font-sans); font-weight: 600; font-size: 16px; white-space: nowrap; transition: gap .25s ease, box-shadow .25s ease; }
.seo-webcta:hover .swc-btn { gap: 14px; box-shadow: 0 10px 26px rgba(247,86,43,.4); }
.swc-arrow { font-size: 18px; line-height: 1; }
@media (max-width: 720px) { .seo-webcta { flex-direction: column; align-items: flex-start; gap: 28px; } }

/* ---- S4 · Agencia · sinergia Iván + Aitor ---- */
.seo-team { padding: var(--sp-sec) 0; }
.seo-team .container { max-width: 940px; }
.seo-team-h2 { font-family: var(--font-sans); font-size: var(--fs-eyebrow); font-weight: 500; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); line-height: 1.4; margin: 0 0 14px; text-align: center; }
.seo-team-h3 { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-section); line-height: 1.1; color: var(--ink); margin: 0 auto 20px; max-width: 24ch; text-align: center; }
/* `.seo-team-intro` («Somos una agencia de marketing y desarrollo…») se quitó
   el 1-sep: el bloque entra directo en «Nos involucramos…». */
.seo-team-intro2 { text-align: center; color: var(--ink-soft); font-size: var(--fs-body); line-height: 1.6; margin: 0 auto 40px; max-width: 64ch; }
.seo-synergy { display: grid; grid-template-columns: 1fr auto 1fr; gap: 22px; align-items: stretch; }
.syn-card { background: var(--bg-2); border: 1px solid var(--line); border-radius: 20px; padding: 28px 26px; text-align: center; }
html[data-theme="dark"] .syn-card { background: rgba(255,255,255,.03); }
.syn-av { width: 70px; height: 70px; border-radius: 50%; margin: 0 auto 16px; background: linear-gradient(150deg, var(--accent), #c23d18); color: #fff; display: flex; align-items: center; justify-content: center; font-family: var(--font-serif); font-size: 28px; }
.syn-name { font-family: var(--font-serif); font-weight: 600; font-size: 21px; color: var(--ink); margin: 0 0 4px; }
.syn-role { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .04em; text-transform: uppercase; color: var(--accent); margin: 0 0 14px; }
.syn-bio { color: var(--ink-soft); font-size: var(--fs-body); line-height: 1.6; margin: 0; }
.syn-link { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; min-width: 110px; }
.syn-from, .syn-to { font-family: var(--font-mono); font-size: 11px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-soft); }
.syn-flow { position: relative; width: 4px; flex: 1; min-height: 60px; border-radius: 999px; background: linear-gradient(180deg, var(--accent), rgba(247,86,43,.25)); overflow: visible; }
.syn-dot { position: absolute; left: 50%; top: 0; width: 12px; height: 12px; border-radius: 50%; background: var(--accent); transform: translateX(-50%); box-shadow: 0 0 0 4px rgba(247,86,43,.2); animation: synFlow 2.6s ease-in-out infinite; }
@keyframes synFlow { 0% { top: 0; } 100% { top: 100%; } }
.seo-team-close { text-align: center; font-size: var(--fs-body); font-weight: 500; color: var(--ink); margin: 40px auto 0; max-width: 46ch; text-wrap: balance; }   /* 2 líneas */

/* ---- responsive SEO ---- */
@media (max-width: 920px) {
  .seo-window-grid { grid-template-columns: 1fr; }
  .seo-window-grid .seo-window-text { order: 1; }   /* en una columna el texto va primero */
  .seo-window-grid .seo-window-visual { order: 2; }
  .seo-idx { grid-template-columns: 1fr; }
  .seo-idx-list { position: static; }
  .seo-idx-panel { min-height: 0; }
  .sip-card { position: relative; opacity: 1; visibility: visible; transform: none; display: none; }
  .sip-card.is-on { display: flex; }
  .seo-bento { grid-template-columns: 1fr 1fr; }
  .seo-synergy { grid-template-columns: 1fr; }
  /* El conector, tumbado.  Tres arreglos y los tres eran silenciosos:

     · `min-height: 0` en el CARRIL.  En vertical lleva `min-height: 60px` para
       que el hilo no se quede en un palito; tumbado, ese suelo le GANA al
       `height: 4px` —`min-height` siempre gana a `height`— y la línea salía
       como un pastillón naranja de 60px de alto. Medido: 226×60 a 390.
     · El punto necesita `translate(-50%, -50%)`, no sólo el `-50%` horizontal
       que trae de la versión vertical: con `top: 50%` sobre una barra de 4px
       colgaba por debajo en vez de ir montado en ella.
     · Tope de ancho. A 810 el conector medía los 762 de la columna y los dos
       rótulos se iban a los extremos de la pantalla, tan lejos de la barra que
       dejaban de leerse como sus extremos. */
  .syn-link { flex-direction: row; min-height: 0; padding: 12px 0;
    width: 100%; max-width: 420px; margin-inline: auto; }
  .syn-flow { width: auto; height: 4px; flex: 1; min-height: 0; min-width: 60px;
    background: linear-gradient(90deg, var(--accent), rgba(247,86,43,.25)); }
  .syn-dot { animation: synFlowH 2.6s ease-in-out infinite; top: 50%; transform: translate(-50%, -50%); }
  @keyframes synFlowH { 0% { left: 0; } 100% { left: 100%; } }
}
@media (max-width: 600px) {
  .seo-bento { grid-template-columns: 1fr; }
}

/* respeta reduced-motion: detiene los bucles decorativos de SEO */
@media (prefers-reduced-motion: reduce) {
  .srk-bar, .srk-line path, .srk-dot, .gauge-fill, .grow-pt,
  .sv-scan, .map-pin, .walker, .walker-in, .syn-dot, .seo-surface,
  .kw-caret, .geo-spark svg, .sv-links .nd, .srp-cursor, .srp-you, .snp-desc b,
  .mk-fill, .mk-pen, .art-kw { animation: none !important; }
  .gauge-fill { width: 86%; }
  .mk-fill { width: 78%; } .mk-pen { left: 78%; }
  .srk-line path { stroke-dashoffset: 0; }
  .srk-dot, .grow-pt { opacity: 1; }
  .tl-item { opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* ==========================================================================
   PÁGINAS LEGALES (aviso legal, privacidad, cookies, términos área cliente)
   ========================================================================== */
.legal { padding: clamp(56px,7vw,104px) 0 88px; }
.legal .container { max-width: 820px; }
.legal > .container > .eyebrow { margin: 0 0 14px; }
.legal h1 { font-size: var(--fs-hero); line-height: 1.08; margin: 0 0 12px; }
.legal-meta { font-family: var(--font-mono); font-size: 12.5px; letter-spacing: .02em; color: var(--ink-faint); margin: 0 0 4px; }
.legal-doc { color: var(--ink-soft); font-size: 16px; line-height: 1.7; }
.legal-doc h2 { font-family: var(--font-serif); font-weight: 500; font-size: clamp(22px,2.4vw,28px); color: var(--ink); line-height: 1.2; margin: 46px 0 14px; letter-spacing: -.01em; }
.legal-doc h3 { font-family: var(--font-sans); font-weight: 600; font-size: 16.5px; color: var(--ink); margin: 30px 0 10px; }
.legal-doc p { margin: 0 0 16px; }
.legal-doc ul, .legal-doc ol { margin: 0 0 18px; padding-left: 22px; }
.legal-doc li { margin: 0 0 9px; }
.legal-doc li::marker { color: var(--ink-faint); }
.legal-doc a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; word-break: break-word; }
.legal-doc strong { color: var(--ink); font-weight: 600; }
.legal-doc hr { border: 0; border-top: 1px solid var(--line); margin: 38px 0; }
.legal-table-wrap { overflow-x: auto; margin: 0 0 20px; border-radius: 12px; }
.legal-doc table { width: 100%; border-collapse: collapse; font-size: 14px; min-width: 520px; }
.legal-doc th, .legal-doc td { text-align: left; padding: 10px 13px; border: 1px solid var(--line); vertical-align: top; line-height: 1.5; }
.legal-doc th { background: var(--bg-2); color: var(--ink); font-weight: 600; font-family: var(--font-sans); }
html[data-theme="dark"] .legal-doc th { background: rgba(255,255,255,.05); }
.legal-doc address { font-style: normal; line-height: 1.7; }

/* footer · fila de enlaces legales */
.footer-legal { display: flex; flex-wrap: wrap; gap: 6px 16px; justify-content: center; }
.footer-legal a { color: var(--ink-faint); text-decoration: none; transition: color .2s ease; }
.footer-legal a:hover { color: var(--accent); }
@media (max-width: 760px) { .footer-bottom { flex-direction: column; gap: 12px; text-align: center; } }

/* ======================= PÁGINA E-COMMERCE (tienda online) ======================= */
/* S1 · hero (mismo tratamiento que SEO: ancho completo, alineado izq., centrado vertical) */
.page-ecommerce .svc-hero .container { grid-template-columns: 1fr; width: 100%; }
.page-ecommerce .svc-hero { padding-top: clamp(120px, calc(50vh - 186px), 186px); }
.page-ecommerce .svc-hero-text { max-width: 760px; }

/* S2 · mockup de tienda: entrada escalonada al hacer scroll + hover que agranda la card bajo el ratón */
.page-ecommerce .shop-card { position: relative; opacity: 0; transform: translateY(18px) scale(.97); transition: opacity .5s ease, transform .5s cubic-bezier(.22,.61,.36,1), border-color .25s ease; }
.page-ecommerce .shop-mock.is-in .shop-card { opacity: 1; transform: none; }
.page-ecommerce .shop-mock.is-in .shop-card:nth-child(1) { transition-delay: .04s; }
.page-ecommerce .shop-mock.is-in .shop-card:nth-child(2) { transition-delay: .16s; }
.page-ecommerce .shop-mock.is-in .shop-card:nth-child(3) { transition-delay: .28s; }
.page-ecommerce .shop-mock.is-in .shop-card:hover { transform: scale(1.05); border-color: var(--accent); transition-delay: 0s; z-index: 1; }
@media (prefers-reduced-motion: reduce) {
  .page-ecommerce .shop-card { opacity: 1; transform: none; transition: border-color .25s ease; }
  .page-ecommerce .shop-mock.is-in .shop-card:hover { transform: none; }
}

/* ---- S2 · el escaparate, sin difuminados --------------------------------
   Se van los tres desenfoques de golpe: el lavado de degradado del marco
   (`--grad-hero`), la sombra ancha de 60px del navegador y los rellenos
   pastel de las fotos —que además traían un `#eef3fb` escrito a mano, fuera
   de la paleta—.  Queda el filete del navegador y nada más.

   Dentro de cada ficha va la misma geometría del hero: el rectángulo áureo
   descompuesto en cuadrados de Fibonacci, cortado a tres profundidades —2, 4
   y 5 cortes—.  Las tres son la misma pieza mirada más de cerca, que es justo
   lo que dice la sección: la misma casa, una tienda distinta para cada uno.
   El naranja marca en cada una el cuadrado más pequeño —34, 13 y 8—, así que
   el acento encoge de izquierda a derecha y lleva la vista por la serie.

   Todo con tokens: en oscuro cambia `--line` y `--accent-soft` y el dibujo se
   da la vuelta solo, sin una segunda regla. */
.page-ecommerce .feat-visual { background: var(--bg); border: none; }
.page-ecommerce .shop-mock { background: var(--bg); box-shadow: none; }
html[data-theme="dark"] .page-ecommerce .shop-mock { background: var(--bg); }
/* Los dos selectores porque el degradado de la ficha del medio lo pone
   `.shop-card:nth-child(2) .shop-img`, que empata en especificidad. */
.page-ecommerce .shop-img,
.page-ecommerce .shop-card:nth-child(2) .shop-img {
  background: none;
  display: flex; align-items: center; justify-content: center; padding: 9% 11%;
  /* La foto deja de ser cuadrada y pasa a ser el propio rectangulo aureo: el
     dibujo la llena y desaparece la franja muerta que quedaba debajo. */
  aspect-ratio: 89 / 55;
}
/* `overflow: visible` para que el filete exterior del dibujo, que va centrado
   en el borde del viewBox, no se corte por la mitad al escalar. */
.shop-geo { display: block; width: 100%; height: auto; overflow: visible; }
.shop-geo-l rect, .shop-geo-l path { fill: none; stroke: var(--line); }
.shop-geo-ac { fill: var(--accent-soft); stroke: var(--accent); }
.shop-geo rect, .shop-geo path { stroke-width: 1; vector-effect: non-scaling-stroke; }

/* S3 · iconos de servicio dentro del visual .sv */
.ec-ico { width: 84px; height: 84px; color: var(--accent); }

/* S4 · plataformas (logos reales, monocromo igual que email-marketing: negro pleno en claro / blanco en oscuro) */
/* Alturas afinadas por logo para que se vean del MISMO tamaño visual (cada marca tiene proporciones distintas) */
.ec-plat-row { margin-top: 40px; }
.ec-plat-logo { display: block; width: auto; filter: brightness(0); }
html[data-theme="dark"] .ec-plat-logo { filter: brightness(0) invert(1); }
.ec-plat-ps { height: clamp(19px,2.45vw,28px); }
.ec-plat-sh { height: clamp(24px,3vw,34px); }
.ec-plat-wc { height: clamp(22px,2.7vw,30px); }

/* S5 · caso de éxito */
.ec-case { padding: 64px 0 112px; }
.ec-case-desc { color: var(--ink-soft); line-height: 1.6; margin: 0 0 26px; max-width: 46ch; }

/* Resaltado del bloque · panel off-white redondeado */
.eca-panel { border-radius: 28px; padding: clamp(28px,4vw,52px); }
.eca-panel-neutral { background: var(--bg-2); border: 1px solid var(--line); box-shadow: 0 30px 70px rgba(22,19,15,.07); }
.ec-ba-tag { position: absolute; top: 11px; left: 11px; z-index: 1; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; color: #fff; background: rgba(22,19,15,.55); padding: 4px 10px; border-radius: 999px; }

/* Placeholder "captura de web" reutilizable (hasta tener imágenes reales del socio) */
.ec-faux { position: relative; overflow: hidden; color: var(--ink-faint); }
.ec-faux::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 15%; background: currentColor; opacity: .12; }
.ec-faux::after { content: ""; position: absolute; inset: 0; background-image: linear-gradient(currentColor 0 0), linear-gradient(currentColor 0 0), linear-gradient(currentColor 0 0); background-size: 24% 52%; background-position: 12% 72%, 50% 72%, 88% 72%; background-repeat: no-repeat; opacity: .16; }
.ec-faux-after { color: var(--accent); background: linear-gradient(135deg, var(--accent-soft), #eef3fb); }
.ec-faux-before { color: var(--ink-soft); background: var(--bg-2); filter: grayscale(1) brightness(.97); }

/* --- Mezcla: texto izq. (arriba) + caja comparador deslizante dcha. a toda altura --- */
.eca-grid { display: grid; grid-template-columns: minmax(0,0.82fr) minmax(0,1.18fr); gap: clamp(28px,4vw,56px); align-items: stretch; }
.eca-left { display: flex; flex-direction: column; align-self: stretch; }   /* el texto fluye desde arriba (top-aligned) */
.eca-left .eyebrow { display: block; margin-bottom: 12px; }
.eca-left h2 { font-size: var(--fs-section); line-height: 1.1; margin: 0 0 14px; }
.eca-left .ec-case-desc { margin: 0; max-width: 48ch; }
.eca-compare { position: relative; width: 100%; min-height: 360px; border-radius: 18px; overflow: hidden; border: 1px solid var(--line); box-shadow: 0 30px 60px rgba(22,19,15,.14); user-select: none; }
.eca-pane { position: absolute; inset: 0; }
.eca-before { clip-path: inset(0 calc(100% - var(--pos)) 0 0); }
.eca-handle { position: absolute; top: 0; bottom: 0; left: var(--pos); width: 0; border-left: 2px solid #fff; box-shadow: 0 0 0 1px rgba(22,19,15,.12); transform: translateX(-1px); pointer-events: none; z-index: 3; }
.eca-grip { position: absolute; top: 50%; left: 0; transform: translate(-50%,-50%); width: 42px; height: 42px; border-radius: 50%; background: #fff; color: var(--accent); display: flex; align-items: center; justify-content: center; font-size: 18px; box-shadow: 0 6px 18px rgba(22,19,15,.25); }
.eca-range { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: ew-resize; z-index: 4; }
.eca-tag { position: absolute; top: 12px; z-index: 2; }
.eca-tag-before { left: 12px; }
.eca-tag-after { right: 12px; left: auto; }

/* Servicios complementarios · tarjetas-enlace (estático) */
.eca-related { padding-top: 30px; }
.eca-related-label { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); margin: 0 0 14px; }
.eca-rel { display: flex; align-items: center; gap: 14px; padding: 14px 16px; border: 1px solid var(--line); border-radius: 14px; background: var(--bg); text-decoration: none; color: var(--ink); transition: border-color .2s ease, background .2s ease; }
.eca-rel + .eca-rel { margin-top: 10px; }
.eca-rel:hover { border-color: var(--accent); background: var(--accent-soft); }
.eca-rel-ico { flex: 0 0 auto; width: 40px; height: 40px; border-radius: 11px; display: flex; align-items: center; justify-content: center; background: var(--accent-soft); color: var(--accent); transition: background .2s ease, color .2s ease; }
.eca-rel:hover .eca-rel-ico { background: var(--accent); color: #fff; }
.eca-rel-ico svg { width: 20px; height: 20px; }
.eca-rel-txt { flex: 1; font-weight: 600; font-size: 15px; line-height: 1.3; }
.eca-rel-arrow { flex: 0 0 auto; color: var(--accent); font-size: 18px; line-height: 1; }

@media (max-width: 820px) {
  .eca-grid { grid-template-columns: 1fr; }
  .eca-compare { min-height: 0; aspect-ratio: 16/10; }
}

/* S6 · expertos (citas) */
.ec-experts-sec { padding: 30px 0 96px; }
.ec-experts { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; margin-top: 38px; }
.ec-expert { display: flex; flex-direction: column; gap: 18px; background: var(--bg-2); border: 1px solid var(--line); border-radius: 20px; padding: 30px 28px; }
html[data-theme="dark"] .ec-expert { background: rgba(255,255,255,.03); }
.ec-expert-top { display: flex; align-items: center; gap: 13px; }
.ec-expert .syn-av { width: 46px; height: 46px; margin: 0; font-size: 20px; flex: 0 0 auto; }
.ec-expert .syn-name { margin: 0; font-weight: 600; font-size: 16px; color: var(--ink); }
.ec-expert .syn-role { margin: 2px 0 0; font-size: 13px; color: var(--ink-soft); }
.ec-quote { margin: 0; font-style: italic; font-weight: 500; font-size: clamp(18px,1.9vw,22px); line-height: 1.42; color: var(--ink); }
.ec-expert-link { margin-top: auto; color: var(--accent); font-weight: 600; font-size: 15px; text-decoration: none; }
.ec-expert-link:hover { text-decoration: underline; }

@media (max-width: 820px) {
  .ec-experts { grid-template-columns: 1fr; }
}

/* ======================= PÁGINA CONSULTORÍA IA ======================= */
/* S1 · hero (mismo trato que SEO/Ecommerce: ancho completo, alineado izq., centrado vertical) */
.page-consultoria-ia .svc-hero .container { grid-template-columns: 1fr; width: 100%; }
.page-consultoria-ia .svc-hero { padding-top: clamp(120px, calc(50vh - 186px), 186px); }
.page-consultoria-ia .svc-hero-text { max-width: 880px; }
/* S1 · frase del hero en 2 líneas */
.ci-hero-phrase { font-size: var(--fs-hero); font-weight: 500; line-height: 1.12; max-width: 880px; margin: 0 0 28px; }

/* Espaciado entre secciones más amplio (scopeado a esta página; S2/S6/S7 comparten componente) */
.page-consultoria-ia .feature { padding: 100px 0; }
.page-consultoria-ia .faq-wrap { padding: 100px 0; }
.page-consultoria-ia .cta { padding: 120px 24px; }
/* CTA de cierre: misma frase y tratamiento que el hero, en 2 líneas (anula el max-width:16ch global) */
.page-consultoria-ia .cta-title { max-width: 900px; font-size: var(--fs-section); }

/* S2 · frase destacada + visual "de tareas a resultados" (núcleo IA · sparkle) */
/* La jerarquia de S2 va al reves a proposito: el H2, que es el que lleva la
   palabra clave, se queda arriba en pequeno y como rotulo, y la frase de
   debajo es la que manda.  Es el mismo reparto que en los heroes de servicio
   —el H1 hace de rotulo y el mensaje va grande debajo—: el buscador lee el
   encabezado igual y quien mira se queda con la frase.
   Las etiquetas NO se tocan: sigue siendo H2 seguido de un parrafo. */
.ci-rotulo {
  font-family: var(--font-sans); font-size: 15px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft);
  line-height: 1.4; max-width: none;
}
.feature .ci-rotulo { font-size: 15px; margin: 0 0 14px; }   /* gana a `.feature h2` */
/* `.feature p` (0,2,0) le ganaba el color y salia en gris de parrafo. */
.feature .ci-lead {
  font-family: var(--font-serif); font-size: var(--fs-section); font-weight: 500;
  line-height: 1.12; margin: 0 0 22px; color: var(--ink);
}
/* El SVG va directo sobre el recuadro con degradado (.feat-visual); ocupa todo el recuadro */
.page-consultoria-ia .feat-visual { padding: clamp(14px, 2.5%, 28px); }
.ci-p3 { width: 100%; height: auto; max-width: none; }
.p3-halo { transform-box: fill-box; transform-origin: center; animation: p-halo 3.6s ease-in-out infinite; }
@keyframes p-halo { 0%,100% { opacity: .12; transform: scale(1); } 50% { opacity: .28; transform: scale(1.05); } }
/* El flujo va en dos tiempos: el punto de entrada recorre 0-40% del ciclo y se
   mete debajo del nucleo —que se pinta despues y lo tapa—, y a partir del 42%
   salen tres, uno por cada resultado.  Antes era un solo punto que cruzaba de
   lado a lado y la lectura era «una tarea, un resultado».

   Los tres caminos son ortogonales (recto, codo, recto), asi que basta con
   encadenar `translate` entre los vertices: el punto sigue la guia exactamente,
   sin `offset-path`.  Los porcentajes son la longitud de cada tramo repartida
   sobre el 58% de ciclo que les toca —26, 56 y 22 de 104 en las ramas— para que
   los tres lleguen a la vez.  `linear` y no `ease`: en un recorrido con codos,
   acelerar y frenar dentro de cada tramo se ve como tirones. */
.p3-dot { animation: p3-dot 3.6s ease-in-out infinite; }
@keyframes p3-dot { 0% { transform: translateX(0); opacity: 0; } 8% { opacity: 1; } 34% { opacity: 1; } 40%, 100% { transform: translateX(80px); opacity: 0; } }
.p3-sale { animation-duration: 3.6s; animation-timing-function: linear; animation-iteration-count: infinite; }
.p3-arriba { animation-name: p3-sale-arriba; }
.p3-medio  { animation-name: p3-sale-medio; }
.p3-abajo  { animation-name: p3-sale-abajo; }
@keyframes p3-sale-arriba {
  0%, 42% { transform: translate(0, 0); opacity: 0; }
  47%     { opacity: 1; }
  56%     { transform: translate(26px, 0); }
  88%     { transform: translate(26px, -56px); }
  95%     { opacity: 1; }
  100%    { transform: translate(48px, -56px); opacity: 0; }
}
@keyframes p3-sale-medio {
  0%, 42% { transform: translateX(0); opacity: 0; }
  47%     { opacity: 1; }
  95%     { opacity: 1; }
  100%    { transform: translateX(48px); opacity: 0; }
}
@keyframes p3-sale-abajo {
  0%, 42% { transform: translate(0, 0); opacity: 0; }
  47%     { opacity: 1; }
  56%     { transform: translate(26px, 0); }
  88%     { transform: translate(26px, 56px); }
  95%     { opacity: 1; }
  100%    { transform: translate(48px, 56px); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .p3-halo, .p3-dot, .p3-sale { animation: none; }
  .p3-dot, .p3-sale { display: none; }
}

/* Iconos y tipografía compartidos de la página */
.ci-ico { display: inline-flex; align-items: center; justify-content: center; width: 52px; height: 52px; border-radius: 14px; background: var(--accent-soft); color: var(--accent); flex: 0 0 auto; }
.ci-ico svg { width: 26px; height: 26px; }
.ci-h { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-h3); line-height: 1.2; margin: 14px 0 8px; color: var(--ink); }
.ci-d { color: var(--ink-soft); font-size: var(--fs-body); line-height: 1.58; margin: 0; }
.ci-link { display: inline-block; margin-top: 12px; color: var(--accent); font-weight: 600; font-size: 14px; text-decoration: none; }
.ci-link:hover { text-decoration: underline; }

/* S3 · sección servicios · la ruta en tres fases
   ------------------------------------------------------------------
   Puerto del Timeline de manuarora700 (21st.dev).  De la referencia se
   queda SOLO la columna izquierda: el carril con el nombre de la fase en
   grande, pegado mientras pasa su tramo, y la barra que se rellena con el
   scroll.  El lado derecho —dibujo de fase y fichas— es propio.
   Sustituye al bento asimétrico de 7 tarjetas, que enseñaba los servicios
   como un catálogo suelto en vez de como un proceso con orden. */
.ci-svc { padding: var(--sp-sec) 0 0; }
.ci-tile { background: var(--bg-2); border: 1px solid var(--line); border-radius: 18px; padding: 22px; min-width: 0; transition: transform .25s ease, border-color .25s ease, box-shadow .25s ease; }
/* Columna flexible para que el enlace naranja caiga al fondo de la ficha y no
   justo debajo del texto: las fichas de una fila miden lo mismo, asi que los
   enlaces quedan alineados entre si aunque las descripciones no lo esten.
   `flex-start` porque estirado ocuparia todo el ancho y el subrayado del hover
   se iria hasta el borde. */
.ci-tile { display: flex; flex-direction: column; }
.ci-tile .ci-link { margin-top: auto; padding-top: 14px; align-self: flex-start; }
html[data-theme="dark"] .ci-tile { background: rgba(255,255,255,.03); }
.ci-tile:hover { transform: translateY(-4px); border-color: var(--accent); box-shadow: 0 18px 40px rgba(22,19,15,.10); }

.ruta { position: relative; margin: 30px 0 60px; padding-left: 0; }
/* El carril arranca y muere en el primer y el último punto, no en los bordes
   del bloque: una raya que sale de la nada y se va a la nada se lee como un
   corte.  De ahí la máscara de los extremos. */
.ruta-carril {
  position: absolute; left: 15px; top: 10px; bottom: 90px; width: 2px;
  background: var(--line);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 5%, #000 92%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0, #000 5%, #000 92%, transparent 100%);
}
/* La barra es naranja macizo y no un degradado que se apaga hacia arriba: el
   carril YA se difumina en los extremos con su mascara, y las dos cosas juntas
   dejaban muerto todo el tramo de arriba, el que ya se ha recorrido.
   Lo que se ablanda es la CABEZA —los ultimos 36px—, que es donde la barra se
   corta en el aire; el mask va en px y no en %, para que la caida mida igual
   con la barra recien empezada que casi llena. */
.ruta-avance {
  position: absolute; left: 0; top: 0; width: 2px; height: 0;
  background: var(--accent); border-radius: 2px;
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 36px), transparent 100%);
          mask-image: linear-gradient(to bottom, #000 calc(100% - 36px), transparent 100%);
}
.ruta-paso {
  position: relative;
  display: grid; grid-template-columns: minmax(0, 380px) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 56px);
  /* El aire entre fases va PARTIDO en dos, y no es un capricho: el rotulo
     pegado solo se puede mover dentro de su fila de la rejilla.
       · Todo en `.ruta-paso` (fuera de la fila): el rotulo nunca se separa de
         sus fichas, pero en una fase de una sola ficha se para a media altura
         y se va casi de inmediato.
       · Todo en `.ruta-cuerpo` (dentro): recorrido de sobra, pero el rotulo
         acaba flotando en el hueco vacio de debajo de sus fichas.
     La mitad en cada sitio da aguante sin que se descuelgue mas de 55px. */
  padding: 0 0 clamp(40px, 6vh, 80px);
}
.ruta-cuerpo { padding-bottom: 55px; }
.ruta-paso:last-child { padding-bottom: 20px; }
.ruta-paso:last-child .ruta-cuerpo { padding-bottom: 0; }
/* El rotulo se para A MEDIA PANTALLA, no pegado a la barra: es lo unico que
   hay en su columna y arriba del todo quedaba descolgado de las fichas a las
   que acompaña.  Los 44px son medio rotulo —numero mas nombre, una o dos
   lineas— para que lo que quede centrado sea la pieza, no su borde de arriba.
   Desde ahi se desvanece al acabar su tramo; la opacidad la escribe main.js,
   que es quien sabe cuanto le queda de recorrido pegado. */
.ruta-rotulo { position: sticky; top: calc(50vh - 44px); align-self: start; padding-left: 72px; }
/* El punto va colgado del PASO y no del rotulo.  Dentro del rotulo se movia
   con el —hasta el centro de la pantalla— y, desde que el rotulo se desvanece,
   se apagaba con el: el carril se quedaba sin marcas justo donde importa.
   Colgado del paso marca donde empieza su fase y no se mueve, que es lo que se
   le pide a una linea de tiempo. */
.ruta-punto {
  position: absolute; left: 4px; top: 2px; width: 24px; height: 24px;
  border-radius: 50%; background: var(--bg); border: 1px solid var(--line);
  display: grid; place-items: center; z-index: 1;
}
.ruta-punto::after {
  content: ""; width: 9px; height: 9px; border-radius: 50%;
  background: var(--ink-faint); transition: background .3s ease, transform .3s ease;
}
/* Se enciende cuando la barra lo ha pasado y SE QUEDA encendido: si solo se
   pintaba el de la fase viva, la barra naranja seguia por debajo de puntos
   grises y las dos piezas contaban cosas distintas. */
.ruta-paso.es-pasado .ruta-punto { border-color: var(--accent); }
.ruta-paso.es-pasado .ruta-punto::after { background: var(--accent); }
.ruta-paso.es-ahora .ruta-punto::after { transform: scale(1.2); }
.ruta-num { display: block; font-family: var(--font-mono, var(--font-sans)); font-size: 13px; font-weight: 600; letter-spacing: .1em; color: var(--ink-faint); margin-bottom: 6px; }
.ruta-nombre {
  margin: 0; font-family: var(--font-serif); font-weight: 500; line-height: 1.05;
  /* Topado en 44: «Diagnóstico» es una palabra sola de once letras y a 54px
     se salía de su columna por debajo del dibujo. */
  font-size: clamp(28px, 3.4vw, 44px); color: var(--ink-faint);
  transition: color .35s ease;
}
.ruta-paso.es-ahora .ruta-nombre { color: var(--ink); }
.ruta-cuerpo { display: grid; gap: 20px; align-content: start; }
.ruta-fichas { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; }
/* Una fase puede traer una sola ficha —el plan de accion—.  Se topa la FICHA
   y no su texto: a lo ancho de la columna el renglon se iria a noventa
   caracteres, y topando solo el texto queda media tarjeta vacia a la derecha. */
.ruta-fichas > .ci-tile:only-child { max-width: 660px; }
@media (max-width: 900px) {
  .ruta-paso { grid-template-columns: minmax(0, 1fr); gap: 22px; }
  .ruta-rotulo { position: static; padding-left: 56px; }
  .ruta-carril { left: 11px; bottom: 40px; }
  .ruta-punto { left: 0; width: 22px; height: 22px; }
  .ruta-cuerpo { padding-left: 56px; }
}
@media (max-width: 560px) {
  .ruta-rotulo, .ruta-cuerpo { padding-left: 40px; }
  .ruta-carril { left: 8px; }
  .ruta-punto { width: 18px; height: 18px; }
  .ruta-punto::after { width: 7px; height: 7px; }
}
/* Tarjeta con énfasis (Formación) */
.ci-tile.is-accent { border-color: var(--accent); background: linear-gradient(150deg, var(--accent-soft), var(--bg-2)); }
html[data-theme="dark"] .ci-tile.is-accent { background: linear-gradient(150deg, rgba(247,86,43,.12), rgba(255,255,255,.03)); }
.ci-tile.is-accent .ci-ico { background: var(--accent); color: #fff; }

/* S4 · tecnología */
.ci-tech { padding: var(--sp-sec) 0; }
.ci-tech-intro { text-align: center; max-width: 1180px; margin: 0 auto; }
.ci-tech-intro .eyebrow { display: block; margin-bottom: 14px; }
.ci-tech-lead { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-section); line-height: 1.12; text-wrap: balance; margin: 0; color: var(--ink); }   /* igual a los títulos grandes de sección */
/* muro de logos · MARQUEE deslizable (mismo patrón que el ticker .stD de quienes-somos):
   track con los logos ×2 que se desplaza -50% en bucle; wordmarks reales del cliente en B/N theme-aware */
.ci-tech-wall { overflow: hidden; margin-top: 48px;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent); }
.ci-logo-track { display: inline-flex; align-items: center; gap: clamp(44px,5vw,76px); white-space: nowrap;
  animation: ci-logo-marq 40s linear infinite; }
.ci-tech-wall:hover .ci-logo-track { animation-play-state: paused; }
/* Los 26px de antes se quedaban cortos en un monitor grande: la tira parecia
   un pie de pagina.  El alto va en una variable para que la correccion optica
   de VS Code —su asset trae el icono grande y el texto chico— siga siendo
   proporcional y no haya que retocar dos numeros. */
.ci-logo-img { --logo-alto: clamp(30px, 2.4vw, 38px);
  height: var(--logo-alto); width: auto; flex: none; opacity: .82; filter: brightness(0); transition: opacity .2s ease; }
.ci-logo-img[src*="vscode"] { height: calc(var(--logo-alto) * 1.27); }
html[data-theme="dark"] .ci-logo-img { filter: brightness(0) invert(1); }
@keyframes ci-logo-marq { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .ci-logo-track { animation: none; transform: none; } }

/* S5 · públicos · acordeón horizontal */
.ci-aud { padding: var(--sp-sec) 0; }
/* «Para empresas que quieren empezar con la inteligencia artificial» son 63
   caracteres, y el tope de 22ch que traen todas las cabeceras de seccion lo
   partia en tres.  Solo aqui: en las demas el subtitulo es mas corto y 22ch
   les viene bien.  `balance` para que los dos renglones midan parecido. */
.ci-aud .seo-svc-head .svc-sub { max-width: 34ch; text-wrap: balance; }
.ci-aud-acc { display: flex; gap: 12px; margin: 38px 0 0; min-height: 300px; }
.ci-aa-panel { flex: 1; min-width: 0; overflow: hidden; position: relative; background: var(--bg-2); border: 1px solid var(--line); border-radius: 18px; padding: 26px 22px; cursor: pointer; transition: flex .45s cubic-bezier(.22,.61,.36,1), background .3s ease; }
html[data-theme="dark"] .ci-aa-panel { background: rgba(255,255,255,.03); }
.ci-aa-panel .ci-h { white-space: normal; }
.ci-aa-panel .ci-d { opacity: 0; transition: opacity .35s ease .1s; }
.ci-aud-acc:hover .ci-aa-panel { flex: .7; }
/* `is-open` solo manda cuando el raton NO esta en el acordeon.  Sin esa
   condicion, la tarjeta abierta seguia estirada y con su tinte naranja
   mientras pasabas por otra: se encendian dos a la vez.  Es la misma cautela
   que ya tenia la linea de abajo para la opacidad del texto, que se quedo sin
   aplicar aqui. */
.ci-aud-acc:hover .ci-aa-panel:hover,
.ci-aud-acc:not(:hover) .ci-aa-panel.is-open { flex: 2.6; background: linear-gradient(150deg, var(--accent-soft), var(--bg-2)); }
html[data-theme="dark"] .ci-aud-acc:hover .ci-aa-panel:hover,
html[data-theme="dark"] .ci-aud-acc:not(:hover) .ci-aa-panel.is-open { background: linear-gradient(150deg, rgba(247,86,43,.12), rgba(255,255,255,.03)); }
.ci-aud-acc:hover .ci-aa-panel:hover .ci-d, .ci-aud-acc:not(:hover) .ci-aa-panel.is-open .ci-d { opacity: 1; }
.ci-aa-ico { display: inline-flex; align-items: center; justify-content: center; width: 50px; height: 50px; border-radius: 14px; background: rgba(247,86,43,.12); color: var(--accent); margin-bottom: 8px; }
.ci-aa-ico svg { width: 26px; height: 26px; }
/* aparición escalonada de los paneles al entrar en pantalla (delay vía JS) */
.ci-aa-panel { opacity: 0; }
.ci-aa-panel.is-in { animation: ci-rise .5s ease forwards; }
@keyframes ci-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .ci-aa-panel { opacity: 1; } .ci-aa-panel.is-in { animation: none; } }

/* Responsive consultoría IA */
@media (max-width: 860px) {
  .ci-aud-acc { flex-direction: column; min-height: 0; }
  .ci-aa-panel, .ci-aud-acc:hover .ci-aa-panel { flex: auto; }
  .ci-aa-panel .ci-d { opacity: 1; }
}


/* ======================= PÁGINA HOME / LANDING ======================= */
/* CTA de cierre: 2 líneas (anula el max-width:16ch global) */
.page-home .cta-title { max-width: 880px; font-size: var(--fs-section); }
/* S1 · HERO (centrado, a pantalla completa, fondo sutil) */
.home-hero { position: relative; padding: 40px 0; overflow: hidden; }
/* ocupa el viewport completo (menos topbar 41 + nav 94 = 135px); texto centrado vertical */
/* Topado igual que los heros de servicio: en un monitor de 1440 de alto,
   calc(100vh - 135px) daba 1.195px de hero y el texto flotaba en el vacío. */
.home-hero.hh-c { min-height: clamp(560px, calc(100vh - 135px), 900px); display: flex; flex-direction: column; justify-content: center; }
.hh-kicker { font-family: var(--font-sans); font-size: 15px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); margin: 0 0 16px; }
/* kicker de los heros de servicio: mismo rol y tamaño que el de la home
   (antes iba con estilos inline a 16px repetidos en cada plantilla) */
.hero-kicker { font-family: var(--font-sans); font-size: 15px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); max-width: none; margin: 0 0 16px; line-height: 1.4; }
.hh-phrase { font-size: var(--fs-hero); font-weight: 500; line-height: 1.1; letter-spacing: -.01em; margin: 0 0 24px; max-width: none; }
.hh-desc { font-size: var(--fs-body); line-height: 1.6; color: var(--ink-soft); margin: 0 0 30px; }
.hh-cta .btn { white-space: normal; text-align: center; }
.hh-c .container { max-width: 1040px; margin: 0 auto; text-align: center; position: relative; z-index: 2; }
.hh-c .hh-desc { max-width: 640px; margin-left: auto; margin-right: auto; }
.hh-c .hh-cta { display: flex; justify-content: center; }

/* ===== HERO DE LA HOME · cortes de línea SÓLO EN MÓVIL (2-sep) ============
   A 390 el rótulo partía en «…MARKETING DIGITAL EN / GALICIA» y la frase en
   «Que te encuentren y te / elijan:», dejando una palabra suelta en las dos.
   Medido: rótulo 317 + 64px, frase 327 + 88 + 245 + 309.  Con `balance`:
   rótulo 227 + 154, frase 269 + 147 + 245 + 309.

   Por qué `text-wrap: balance` y NO un `<br>` de móvil, que es lo que pide el
   cuerpo: un `<br>` cuadra el ancho para el que se puso y se rompe en el de al
   lado —a 430 sobra sitio y a 360 falta—, y luego hay que deshacerlo a cada
   corte. `balance` reparte solo, en cualquier teléfono.

   Se probó también quitar el `<br>` de la frase en móvil para que balance
   repartiera las cuatro líneas libremente: NO VALE.  El `<br>` es el único
   separador entre «elijan:» y «en Google», así que al ocultarlo las dos
   palabras salen pegadas: «elijan:en Google».

   Va a 600px y no a 810 porque es un arreglo de TELÉFONO: en tablet el rótulo
   entra en una línea y la frase en dos, y ahí está bien.  600 es un corte que
   el fichero ya usaba (el interruptor del justificado); no se abre uno nuevo.
   ========================================================================= */
@media (max-width: 600px) {
  .hh-kicker, .hh-phrase { text-wrap: balance; }
}
/* Fondo del hero de la home: retícula de puntos que reacciona al cursor.
   (Sustituye a las manchas de color, que siguen en los heros de servicio.)
   El canvas lo pinta main.js leyendo --ink-faint y --accent, así que el modo
   oscuro y cualquier cambio de token se reflejan sin tocar nada aquí. */
/* Un solo lienzo, fijo al viewport, detrás de todo el contenido. Así la
   rejilla nunca se corta en la costura entre secciones y sólo hay un foco.
   Las secciones que la enseñan van transparentes; el resto la tapa con su
   propio fondo, que es lo que ya hacían. */
.dots-bg { position: fixed; inset: 0; z-index: 0; pointer-events: none; }
.dots-bg .hero-dots { display: block; width: 100%; height: 100%; }
/* SÓLO estas tres enseñan la retícula: hero, servicios y el CTA final. */
.page-home .home-hero,
.page-home .svc-scroll,
.page-home .cta { background: transparent; position: relative; z-index: 1; }

/* Las de en medio la tapan. Con darles fondo NO basta: el lienzo es `fixed`, y
   un elemento posicionado pinta por encima de todo lo que esté en `static`
   aunque su z-index sea 0. Hay que POSICIONARLAS también.
   (Este tema no tiene <main>: las secciones cuelgan directas de <body>, así
   que cualquier regla que dependa de `main >` no casa con nada.) */
/* Estas tapan la retícula. Hacen falta las DOS cosas: fondo opaco y estar
   POSICIONADAS. El lienzo es `fixed` y pinta por encima de todo lo que esté
   en `static`, tenga el fondo que tenga. (El tema no tiene <main>: las
   secciones cuelgan directas de <body>.)

   S3, S4, S5, S6 y el pie no declaraban fondo en producción: se veía el del
   <body>, que es --bg. Declararlo aquí no cambia cómo se ven; es lo que
   impide que se transparente el lienzo. */
.page-home .home-geo,
.page-home .home-why,
.page-home .home-team,
.page-home .home-reviews,
.page-home .footer   { background: var(--bg);   position: relative; z-index: 1; }

/* La FAQ sí llevaba fondo propio (--bg-2). Se mantiene, un tono más claro. */
.page-home .faq-wrap { background: var(--bg-3); position: relative; z-index: 1; }

/* Costuras: la retícula no termina en seco, se desvanece contra el fondo.
   Arriba del hero (bajo la barra) y al final de los servicios, antes de S3. */
.page-home .svc-scroll::after,
.page-home .cta::before,
.page-home .cta::after {
  content: ''; position: absolute; left: 0; right: 0;
  height: clamp(90px, 14vh, 180px);
  pointer-events: none; z-index: 0;
}
/* Arriba del hero NO se difumina: con la barra ya translúcida no hay corte,
   y el degradado apagaba el halo justo donde está la barra. */
.page-home .svc-scroll::after { bottom: 0; background: linear-gradient(180deg, transparent 0%, var(--bg) 100%); }
.page-home .cta::before       { top: 0;    background: linear-gradient(180deg, var(--bg) 0%, transparent 100%); }
.page-home .cta::after        { bottom: 0; background: linear-gradient(180deg, transparent 0%, var(--bg) 100%); }
/* Y el contenido POR ENCIMA de los dos degradados.  Sin esta línea se los come
   parte del CTA, y no por ser altos: un pseudoelemento `position: absolute` con
   `z-index: 0` pinta ENCIMA del contenido en flujo sin posicionar, que es lo
   que era este `.container`.  O sea que el `z-index: 0` no lo mandaba detrás,
   como parece leyendo el número.

   Medido lo que se comía: 48px arriba y abajo a 390, **78 a 810** —el peor, por
   ser 14vh de una pantalla alta— y 16 a 1440, donde casi no se notaba.  Por eso
   se veía en el móvil y en el tablet y no en el escritorio.

   Es la misma línea que ya tenía `.cta:has(.cta-dots) > .container` para las
   seis páginas de servicio: a la home le faltaba, porque su CTA no lleva
   `.cta-dots` —la retícula se la pone la página entera— y no entraba en ese
   selector. */
.page-home .cta > .container { position: relative; z-index: 2; }

/* Visual "Google + IA" (compartido B / S3) */
.hvx { display: flex; flex-direction: column; gap: 16px; }
.hvx-card { background: var(--bg); border: 1px solid var(--line); border-radius: 16px; padding: 16px 18px; box-shadow: 0 22px 50px rgba(22,19,15,.10); }
html[data-theme="dark"] .hvx-card { background: var(--bg-2); }
.hvx-bar { display: flex; align-items: center; gap: 10px; padding: 8px 14px; border: 1px solid var(--line); border-radius: 999px; margin-bottom: 12px; }
.hvx-g { flex: 0 0 auto; width: 18px; height: 18px; display: block; }
.hvx-q { color: var(--ink-soft); font-size: 14px; }
.hvx-res { padding: 11px 6px; }
.hvx-res.is-you { background: var(--accent-soft); border: 1px solid rgba(247,86,43,.25); border-radius: 12px; padding: 13px; }
.hvx-pill { display: inline-block; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .05em; text-transform: uppercase; color: #fff; background: var(--accent); border-radius: 999px; padding: 3px 10px; margin-bottom: 9px; }
.hvx-l { display: block; height: 7px; border-radius: 4px; background: var(--ink); opacity: .12; margin: 7px 0; }
.hvx-res.is-you .hvx-l { background: var(--accent); opacity: .28; }
.w80{width:80%}.w70{width:70%}.w65{width:65%}.w60{width:60%}.w50{width:50%}.w45{width:45%}
.hvx-ai { display: flex; gap: 10px; align-items: flex-start; width: 82%; margin-left: auto; }
.hvx-ai-tag { flex: 0 0 auto; width: 32px; height: 32px; border-radius: 9px; background: #fff; border: 1px solid var(--line); display: flex; align-items: center; justify-content: center; }
.hvx-ai-tag img { width: 21px; height: 21px; object-fit: contain; display: block; }
html[data-theme="dark"] .hvx-ai-tag { background: #fff; border-color: rgba(255,255,255,.14); }
.hvx-ai-msg { margin: 0; background: var(--bg); border: 1px solid var(--line); border-radius: 14px; border-top-left-radius: 4px; padding: 12px 15px; font-size: 14.5px; line-height: 1.45; color: var(--ink); box-shadow: 0 12px 26px rgba(22,19,15,.08); }
html[data-theme="dark"] .hvx-ai-msg { background: var(--bg-2); }
.hvx-ai-msg b { color: var(--accent); }

/* S2 · Servicios = scroller horizontal con pin (.hservices/.hcard, CSS heredado más arriba) */

/* S3 · Especialistas en IA (statement + visual) */
.home-geo { padding: var(--sp-sec) 0; }
.home-geo-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px,5vw,64px); align-items: center; }
.home-geo-text .eyebrow { display: block; margin-bottom: 14px; }
.home-geo-text h2 { font-size: var(--fs-section); line-height: 1.12; margin: 0 0 18px; }
.home-geo-text p { color: var(--ink-soft); line-height: 1.7; margin: 0 0 16px; max-width: 52ch; }
/* enlace SEO de la home: resalta un pelín más (pastilla sutil, scoped — no afecta a otras páginas) */
.home-geo-text .ci-link {
  margin-top: 16px;
  background: var(--accent-soft);
  padding: 10px 18px;
  border-radius: 100px;
  transition: background .18s ease, transform .18s ease;
}
.home-geo-text .ci-link span { display: inline-block; transition: transform .18s ease; }
.home-geo-text .ci-link:hover { background: #fbdccd; text-decoration: none; }
.home-geo-text .ci-link:hover span { transform: translateX(3px); }
html[data-theme="dark"] .home-geo-text .ci-link { background: rgba(247,86,43,.16); }
html[data-theme="dark"] .home-geo-text .ci-link:hover { background: rgba(247,86,43,.24); }
.home-geo-visual { display: flex; flex-direction: column; gap: 16px; }

/* --------------------------------------------------------------------------
   S4 · ¿Por qué GRAFS? — RETÍCULA BENTO
   Referencia: 21st.dev/@manuarora700/components/bento-grid (Aceternity UI).
   Traducido a CSS vanilla — sin React, sin Tailwind, sin más tipografías que
   las tres de la web. De la referencia se conservan las tres señas:
     · retícula asimétrica (3 columnas, tarjetas que ocupan dos)
     · al pasar por encima: la tarjeta se levanta y el bloque de texto se
       desplaza a la derecha
     · un visual animado propio por tarjeta ("skeleton" en el original)
   Todo el color sale de tokens, así que el modo oscuro se resuelve solo.
   La sección NO lleva fondo propio: se ve el del body, como la S3.
   -------------------------------------------------------------------------- */
.home-why { padding: var(--sp-sec) 0; }
.home-why-head { max-width: 940px; margin: 0 0 38px; }
.home-why-head h2 { font-size: var(--fs-section); line-height: 1.18; }

.bento-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  /* minmax(...,auto): la fila crece si el texto lo pide. Con una altura fija
     se cortarían los párrafos largos en cuanto la columna se estrecha. */
  grid-auto-rows: minmax(300px, auto);
}
.bento-card {
  display: flex; flex-direction: column; gap: 18px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 20px;
  transition: transform .3s cubic-bezier(.2,.7,.2,1), box-shadow .3s ease, border-color .3s ease;
}
.bento-card.is-wide { grid-column: span 2; }
.bento-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 18px 40px rgba(25,26,30,.10);
  border-color: rgba(247,86,43,.28);   /* el acento con alfa, como .hvx-res.is-you */
}
html[data-theme="dark"] .bento-card { background: rgba(255,255,255,.03); }
html[data-theme="dark"] .bento-card:hover { box-shadow: 0 18px 40px rgba(0,0,0,.45); }

/* El bloque de texto se desplaza al pasar por encima (el gesto de la referencia) */
.bento-body { transition: transform .3s cubic-bezier(.2,.7,.2,1); }
.bento-card:hover .bento-body { transform: translateX(8px); }
/* Sin iconito: el visual de arriba ya cuenta la idea (decisión del 28-ago). */
.bento-card h3 { font-family: var(--font-serif); font-weight: 500; font-size: 20px; line-height: 1.25; margin: 0 0 10px; }
.bento-card p { color: var(--ink-soft); line-height: 1.6; font-size: var(--fs-body); margin: 0; }

/* Caja del visual. Crece para llenar lo que sobre, con un mínimo. */
.bento-fx {
  position: relative; overflow: hidden;
  flex: 1 1 120px; min-height: 120px;
  border-radius: 14px;
  background: var(--bg);
  border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
}
html[data-theme="dark"] .bento-fx { background: rgba(255,255,255,.02); }

/* 1 · Un método claro — una ruta con pasos hasta la meta.
   El avance recorre la línea y va encendiendo cada hito a su paso; el último
   es la bandera. Los retardos de los hitos están calzados con el recorrido. */
.fx-metodo { padding: 20px clamp(26px, 5%, 54px); }
.mt-ruta { position: relative; width: 100%; display: flex; align-items: center; justify-content: space-between; }
.mt-ruta::before {
  content: ''; position: absolute; left: 0; right: 0; top: 50%;
  height: 0; border-top: 2px dashed var(--ink); opacity: .16;
}
.mt-avance {
  position: absolute; left: 0; right: 0; top: 50%; height: 2px; margin-top: -1px;
  background: var(--accent); transform-origin: left center; transform: scaleX(0);
  /* LINEAL a propósito: con una curva de aceleración no hay forma de calzar el
     encendido de cada hito con el momento en que la línea pasa por él, y el
     color iba con retraso. A velocidad constante los porcentajes salen solos:
     los hitos están al 0, 1/3, 2/3 y 1 del ancho, y la línea tarda hasta el
     62% del ciclo en recorrerlo → 0%, 20,7%, 41,3% y 62%. */
  animation: mt-avance 6s linear infinite;
}
.mt-paso, .mt-meta {
  position: relative; z-index: 1; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; background: var(--hito-bg); border: 2px solid var(--ink-faint);
  color: var(--ink-faint);
  /* El fondo apagado va por variable para que el modo oscuro pueda cambiarlo:
     dentro de un @keyframes gana la animación a cualquier regla de fuera. */
  --hito-bg: var(--bg);
  animation-duration: 6s; animation-timing-function: ease-in-out; animation-iteration-count: infinite;
}
html[data-theme="dark"] .mt-paso, html[data-theme="dark"] .mt-meta { --hito-bg: #1F2025; }
.mt-paso { width: 17px; height: 17px; }
.mt-meta { width: 44px; height: 44px; border-radius: 13px; }
/* Sin color propio: hereda el del hito, así la bandera sale BLANCA en cuanto
   la meta se pone naranja. */
.mt-meta svg { width: 23px; height: 23px; }
.mt-paso:nth-of-type(1) { animation-name: mt-h1; }
.mt-paso:nth-of-type(2) { animation-name: mt-h2; }
.mt-paso:nth-of-type(3) { animation-name: mt-h3; }
.mt-meta               { animation-name: mt-h4; }
/* NADA de tocar el reloj de una animación al pasar el cursor.
   Cambiar `animation-duration` no reinicia la animación, pero sí remapea el
   tiempo transcurrido sobre la nueva duración: el fotograma salta de golpe, y
   otra vez al salir. Con `animation: none` es peor, porque además se pierde la
   posición. Los bucles siguen a lo suyo; el gesto de la tarjeta —levantarse y
   correr el texto— ya es la respuesta al cursor. */
@keyframes mt-avance {
  0%        { transform: scaleX(0); opacity: 1; }
  62%, 88%  { transform: scaleX(1); opacity: 1; }
  100%      { transform: scaleX(1); opacity: 0; }
}
/* Un juego de fotogramas por hito, no un retardo: con retardos cada hito se
   apagaba en un momento distinto al del reinicio de la línea. */
@keyframes mt-h1 {
  0%              { border-color: var(--ink-faint); background: var(--hito-bg); color: var(--ink-faint); transform: scale(1); }
  2.2%, 92%      { border-color: var(--accent); background: var(--accent); color: var(--white); transform: scale(1.12); }
  100%            { border-color: var(--ink-faint); background: var(--hito-bg); color: var(--ink-faint); transform: scale(1); }
}
@keyframes mt-h2 {
  0%, 18.7%      { border-color: var(--ink-faint); background: var(--hito-bg); color: var(--ink-faint); transform: scale(1); }
  21.7%, 92%     { border-color: var(--accent); background: var(--accent); color: var(--white); transform: scale(1.12); }
  100%            { border-color: var(--ink-faint); background: var(--hito-bg); color: var(--ink-faint); transform: scale(1); }
}
@keyframes mt-h3 {
  0%, 38.2%      { border-color: var(--ink-faint); background: var(--hito-bg); color: var(--ink-faint); transform: scale(1); }
  41.2%, 92%     { border-color: var(--accent); background: var(--accent); color: var(--white); transform: scale(1.12); }
  100%            { border-color: var(--ink-faint); background: var(--hito-bg); color: var(--ink-faint); transform: scale(1); }
}
@keyframes mt-h4 {
  0%, 58.8%      { border-color: var(--ink-faint); background: var(--hito-bg); color: var(--ink-faint); transform: scale(1); }
  61.8%, 92%     { border-color: var(--accent); background: var(--accent); color: var(--white); transform: scale(1.12); }
  100%            { border-color: var(--ink-faint); background: var(--hito-bg); color: var(--ink-faint); transform: scale(1); }
}

/* 2 · Trato cercano — un departamento más.
   Cuatro personas juntas; se abren para hacer sitio y entra la quinta, en
   naranja. Es la frase del texto de la tarjeta, dibujada.
   La fila NO cambia de tamaño: los cinco huecos están siempre ahí y son los
   grises los que se corren sobre el sitio de la nueva. Así no baila el ancho. */
.fx-cercano { padding: 18px; }
.dp-fila { display: flex; align-items: center; justify-content: center; gap: 10px; }
.dp-p, .dp-nuevo {
  flex: 0 0 auto; width: 42px; height: 42px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-2); border: 1px solid var(--line); color: var(--ink-faint);
  transition: transform .45s cubic-bezier(.2,.7,.2,1), opacity .45s ease;
}
.dp-p svg, .dp-nuevo svg { width: 22px; height: 22px; }
.dp-nuevo { background: var(--accent); border-color: var(--accent); color: var(--white); }
/* 42 de ancho + 10 de hueco = 52; media plaza a cada lado son 26. */
.dp-izq { animation: dp-izq 5.5s ease-in-out infinite; }
.dp-der { animation: dp-der 5.5s ease-in-out infinite; }
.dp-nuevo { animation: dp-entra 5.5s ease-in-out infinite; }
@keyframes dp-izq {
  0%, 12%   { transform: translateX(26px); }
  32%, 86%  { transform: translateX(0); }
  100%      { transform: translateX(26px); }
}
@keyframes dp-der {
  0%, 12%   { transform: translateX(-26px); }
  32%, 86%  { transform: translateX(0); }
  100%      { transform: translateX(-26px); }
}
@keyframes dp-entra {
  0%, 14%   { transform: translateY(15px) scale(.4); opacity: 0; }
  34%, 84%  { transform: translateY(0) scale(1);     opacity: 1; }
  100%      { transform: translateY(15px) scale(.4); opacity: 0; }
}

/* 3 · Google e IA — simulacro de buscador.
   Se teclea la consulta y, entre los resultados, el recomendado es Tu marca.
   Todo con fotogramas propios en vez de retardos: con retardos cada trozo se
   apaga en un momento distinto al del reinicio y el bucle da un salto. */
.fx-buscar { padding: 16px 18px; }
.bs-pantalla { width: 100%; display: flex; flex-direction: column; gap: 9px; }
.bs-caja {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 11px; border-radius: 999px;
  background: var(--bg-2); border: 1px solid var(--line);
  overflow: hidden;
}
html[data-theme="dark"] .bs-caja { background: rgba(255,255,255,.05); }
.bs-lupa { width: 14px; height: 14px; flex: 0 0 auto; color: var(--ink-faint); }
/* El tecleo se hace con el ANCHO, no cambiando el texto: así no hace falta JS.
   31 caracteres → steps(31); en Poppins el ch no calza exacto con la letra,
   pero a este tamaño no se nota y evita cortes a mitad de glifo. */
.bs-consulta { flex: 0 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; }
.bs-consulta b {
  display: block; width: 0; max-width: 100%; overflow: hidden; white-space: nowrap;
  font-family: var(--font-sans); font-size: 12px; font-weight: 500; line-height: 1.5;
  color: var(--ink);
  /* El cursor es el BORDE del recorte, no un elemento aparte: así está siempre
     en la punta de lo tecleado. Con un <i> detrás quedaba un hueco, porque el
     ancho final se mide en ch y el ch de Poppins no calza con la letra real. */
  border-right: 1.5px solid var(--accent);
  animation: bs-teclea 7s steps(31) infinite, bs-parpadeo .9s steps(1) infinite;
}
.bs-res { list-style: none; margin: 0; padding: 0 2px; display: flex; flex-direction: column; gap: 7px; }
.bs-r { display: flex; align-items: center; gap: 8px; opacity: 0; }
.bs-l { display: block; height: 8px; border-radius: 4px; background: var(--ink); opacity: .13; }
.bs-top {
  padding: 5px 9px; margin: -3px -7px;
  border-radius: 8px; background: var(--accent-soft);
  border: 1px solid rgba(247,86,43,.28);
}
.bs-marca { font-family: var(--font-sans); font-size: 12.5px; font-weight: 700; color: var(--accent-700); line-height: 1; }
html[data-theme="dark"] .bs-marca { color: var(--accent); }
.bs-sello {
  font-family: var(--font-sans); font-size: 9px; font-weight: 600; line-height: 1;
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--white); background: var(--accent);
  padding: 3px 6px; border-radius: 999px; margin-left: auto;
}
.bs-top { animation: bs-e1 7s ease-out infinite; }
.bs-r2  { animation: bs-e2 7s ease-out infinite; }
.bs-r3  { animation: bs-e3 7s ease-out infinite; }
@keyframes bs-teclea  { 0% { width: 0; } 30%, 95% { width: 199px; } 100% { width: 0; } }
@keyframes bs-parpadeo{ 0%, 49% { border-right-color: var(--accent); } 50%, 100% { border-right-color: transparent; } }
@keyframes bs-e1 { 0%, 33% { opacity: 0; transform: translateY(5px) scale(.97); } 40%, 94% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(5px) scale(.97); } }
@keyframes bs-e2 { 0%, 39% { opacity: 0; transform: translateY(5px); } 46%, 94% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(5px); } }
@keyframes bs-e3 { 0%, 45% { opacity: 0; transform: translateY(5px); } 52%, 94% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(5px); } }

/* 4 · Predicamos con el ejemplo — de lo nuestro a lo tuyo.
   Dos paneles CON NOMBRE: en «grafs.es» sale el tic de que ya está probado, y
   entonces la pieza cruza y enciende «tu negocio». Los rótulos son la pieza
   clave: la versión anterior eran rectángulos abstractos y no había forma de
   deducir qué contaban. Aquí se lee el orden que dice la frase — primero lo
   nuestro, después lo tuyo — que es justo lo que un sello no decía. */
.fx-ejemplo { padding: 18px; }
/* Ancho explícito: sin él la escena se ajusta al contenido, el camino se queda
   en su min-width (54px) y el viaje no se lee como viaje. */
.ex-escena { display: flex; align-items: center; justify-content: center; width: min(100%, 640px); }
.ex-caja {
  position: relative; flex: 0 0 auto;
  width: clamp(148px, 17vw, 208px);
  padding: 13px 15px 15px; border-radius: 13px;
  background: var(--bg-2); border: 1px solid var(--line);
}
.ex-rotulo {
  display: block; margin-bottom: 11px;
  font-family: var(--font-sans); font-size: 11.5px; font-weight: 600; line-height: 1;
  letter-spacing: .03em; color: var(--ink-soft); white-space: nowrap;
}
/* En versales el texto se apelmaza: un punto más de espaciado entre letras. */
.ex-casa .ex-rotulo { letter-spacing: .06em; }
.ex-l { display: block; height: 7px; border-radius: 4px; background: var(--ink); opacity: .13; margin-top: 7px; }
/* El tic de «ya lo hemos probado nosotros» */
.ex-tic {
  position: absolute; top: -9px; right: -9px;
  width: 24px; height: 24px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: var(--white);
  border: 2px solid var(--bg);
  transform: scale(0);
  animation: ex-tic 7s cubic-bezier(.3,1.5,.5,1) infinite;
}
html[data-theme="dark"] .ex-tic { border-color: #1F2025; }
.ex-tic svg { width: 12px; height: 12px; }
/* El camino entre los dos */
.ex-via { position: relative; flex: 1 1 auto; min-width: 54px; height: 28px; }
.ex-via::before {
  content: ''; position: absolute; left: 6px; right: 6px; top: 50%;
  height: 0; border-top: 2px dashed var(--ink); opacity: .16;
}
/* margin-left de media pieza: así `left` es su CENTRO y el viaje de 0 a 100%
   la lleva de borde a borde sin cuentas raras. */
.ex-pieza {
  position: absolute; top: 50%; left: 0; margin: -13px 0 0 -13px;
  width: 26px; height: 26px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: var(--white); opacity: 0;
  animation: ex-viaja 7s cubic-bezier(.45,0,.4,1) infinite;
}
.ex-pieza svg { width: 13px; height: 13px; }
/* El panel de la derecha se enciende cuando llega la pieza. El color vivo va
   por variable porque dentro de un @keyframes gana la animación a cualquier
   regla de fuera, y en oscuro el --accent-700 se apaga demasiado. */
.ex-tuyo { --vivo: var(--accent-700); animation: ex-enciende 7s ease-in-out infinite; }
html[data-theme="dark"] .ex-tuyo { --vivo: var(--accent); }
.ex-tuyo .ex-rotulo { animation: ex-rotulo 7s ease-in-out infinite; }
@keyframes ex-tic {
  0%, 17%   { transform: scale(0); opacity: 0; }
  25%, 86%  { transform: scale(1); opacity: 1; }
  100%      { transform: scale(0); opacity: 0; }
}
@keyframes ex-viaja {
  0%, 31%   { left: 0%;   opacity: 0; transform: scale(.5); }
  38%       { left: 12%;  opacity: 1; transform: scale(1); }
  57%       { left: 88%;  opacity: 1; transform: scale(1); }
  64%, 100% { left: 100%; opacity: 0; transform: scale(.5); }
}
@keyframes ex-enciende {
  0%, 57%   { border-color: var(--line);   background: var(--bg-2); }
  66%, 86%  { border-color: var(--accent); background: var(--accent-soft); }
  100%      { border-color: var(--line);   background: var(--bg-2); }
}
@keyframes ex-rotulo {
  0%, 57%   { color: var(--ink-soft); }
  66%, 86%  { color: var(--vivo); }
  100%      { color: var(--ink-soft); }
}

/* 5 · Siempre al día — la campana.
   Llega un aviso (el punto naranja), la campana se agita, se pulsa y se abre
   el cuadro con la noticia. Ciclo de 6,5 s, cada pieza con sus fotogramas
   calzados al mismo ciclo. */
.fx-aldia { padding: 18px; }
.cm-zona { display: flex; align-items: center; justify-content: center; gap: 20px; }
.cm-campana {
  position: relative; flex: 0 0 auto;
  width: 62px; height: 62px; border-radius: 18px;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-2); border: 1px solid var(--line); color: var(--ink-soft);
  transform-origin: 50% 22%;
  animation: cm-campana 6.5s ease-in-out infinite;
}
html[data-theme="dark"] .cm-campana { background: rgba(255,255,255,.05); }
.cm-campana svg { width: 30px; height: 30px; }
.cm-punto {
  position: absolute; top: 9px; right: 11px;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--bg-2);
  transform: scale(0);
  animation: cm-punto 6.5s cubic-bezier(.3,1.5,.5,1) infinite;
}
html[data-theme="dark"] .cm-punto { border-color: #232429; }
.cm-aviso {
  flex: 0 0 auto; width: clamp(160px, 20vw, 230px);
  padding: 12px 14px; border-radius: 13px;
  background: var(--bg-2); border: 1px solid var(--line);
  transform-origin: left center; transform: scale(.9); opacity: 0;
  animation: cm-aviso 6.5s cubic-bezier(.2,.9,.3,1) infinite;
}
html[data-theme="dark"] .cm-aviso { background: rgba(255,255,255,.05); }
.cm-tit { display: block; font-family: var(--font-sans); font-size: 12px; font-weight: 700; color: var(--accent-700); line-height: 1; margin-bottom: 9px; }
html[data-theme="dark"] .cm-tit { color: var(--accent); }
.cm-l { display: block; height: 7px; border-radius: 4px; background: var(--ink); opacity: .13; margin-top: 6px; }
/* La campana: quieta → se agita al llegar el aviso → el pulsado (se hunde) */
@keyframes cm-campana {
  0%, 14%          { transform: rotate(0) scale(1); }
  18%              { transform: rotate(13deg) scale(1); }
  22%              { transform: rotate(-11deg) scale(1); }
  26%              { transform: rotate(8deg) scale(1); }
  30%              { transform: rotate(-5deg) scale(1); }
  34%, 41%         { transform: rotate(0) scale(1); }
  45%              { transform: rotate(0) scale(.9); }   /* clic */
  50%, 92%         { transform: rotate(0) scale(1); }
  100%             { transform: rotate(0) scale(1); }
}
@keyframes cm-punto {
  0%, 11%   { transform: scale(0); }
  18%, 41%  { transform: scale(1); }
  49%, 100% { transform: scale(0); }   /* al abrir el aviso, el punto se va */
}
@keyframes cm-aviso {
  0%, 44%   { transform: scale(.9) translateX(-8px); opacity: 0; }
  52%, 94%  { transform: scale(1) translateX(0);     opacity: 1; }
  100%      { transform: scale(.9) translateX(-8px); opacity: 0; }
}

/* 6 · Equipo local — mapa de España con las divisiones autonómicas.
   Galicia va sólida en naranja (la casa); las seis ciudades se van encendiendo
   una tras otra para decir que se trabaja en todo el país sin escribirlo.
   Aviso: el contorno y las divisiones están trazados a mano desde coordenadas
   (proyección plana), no vienen de cartografía oficial. A este tamaño la
   diferencia no se ve, pero no sirve para nada que no sea decorativo. */
.fx-galicia { padding: 10px; }
.ga-mapa { width: auto; height: 100%; max-height: 168px; max-width: 92%; overflow: visible; }
.ga-es { fill: var(--ink); opacity: .13; transition: opacity .4s ease; }
html[data-theme="dark"] .ga-es { opacity: .19; }
/* Las divisiones van en el color del FONDO, no en gris: así se leen como
   cortes en la mancha y no como una segunda maraña de líneas. */
.ga-div { fill: none; stroke: var(--bg); stroke-width: .5; stroke-linejoin: round; stroke-linecap: round; opacity: .85; }
html[data-theme="dark"] .ga-div { stroke: var(--bg); opacity: .6; }
.ga-ga { fill: var(--accent); opacity: .9; transition: opacity .4s ease; }
/* Galicia, la única en naranja, sí lleva sus cuatro provincias: es la que
   se mira de cerca. El resto se queda en comunidades. */
.ga-prov { fill: none; stroke: var(--white); stroke-width: .5; stroke-linecap: round; stroke-linejoin: round; opacity: .5; transition: opacity .4s ease; }
.bento-card:hover .ga-prov { opacity: .78; }
.ga-ciudad {
  fill: var(--ink); opacity: .3;
  transform-box: fill-box; transform-origin: center;
  animation: ga-ciudad 7s ease-in-out infinite;
}
.ga-c1 { animation-delay: 0s;   } .ga-c2 { animation-delay: 1.1s; }
.ga-c3 { animation-delay: 2.2s; } .ga-c4 { animation-delay: 3.3s; }
.ga-c5 { animation-delay: 4.4s; } .ga-c6 { animation-delay: 5.5s; }
.ga-punto { fill: var(--white); stroke: var(--accent-700); stroke-width: .7; }
html[data-theme="dark"] .ga-punto { fill: var(--ink); }
.ga-onda {
  fill: none; stroke: var(--accent-700); stroke-width: .9;
  transform-box: fill-box; transform-origin: center;
  animation: ga-radar 2.8s ease-out infinite;
}
.bento-card:hover .ga-es { opacity: .2; }
html[data-theme="dark"] .bento-card:hover .ga-es { opacity: .27; }
.bento-card:hover .ga-ga { opacity: 1; }
@keyframes ga-radar {
  0%   { transform: scale(1);   opacity: .6; }
  100% { transform: scale(2.6); opacity: 0; }
}
@keyframes ga-ciudad {
  0%, 2%    { fill: var(--ink);    opacity: .3; transform: scale(1); }
  6%, 13%   { fill: var(--accent); opacity: 1;  transform: scale(1.5); }
  22%, 100% { fill: var(--ink);    opacity: .3; transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .bento-card, .bento-body, .dp-p, .dp-nuevo,
  .ta-panel, .ta-panel img, .ta-oculto, .ta-li { transition: none; }
  /* Sin desfile: se enseñan las tres reseñas quietas y se quita el recorte. */
  .rev-col { animation: none; }
  .rev-col-2 { display: none; }
  .rev-cols { height: auto; max-width: 620px; -webkit-mask-image: none; mask-image: none; }
  .rev-card[aria-hidden="true"] { display: none; }
  .ex-tic { transform: scale(1); opacity: 1; }
  .ex-pieza { left: 50%; opacity: 1; transform: scale(1); }
  .ex-tuyo { border-color: var(--accent); background: var(--accent-soft); }
  .ex-tuyo .ex-rotulo { color: var(--vivo); }
  .mt-avance, .mt-paso, .mt-meta, .dp-izq, .dp-der, .dp-nuevo,
  .ex-tic, .ex-pieza, .ex-tuyo, .ex-tuyo .ex-rotulo,
  .bs-consulta b, .bs-top, .bs-r2, .bs-r3,
  .cm-campana, .cm-punto, .cm-aviso, .ga-onda { animation: none; }
  .mt-paso, .mt-meta { color: var(--white); }
  .dp-izq, .dp-der, .dp-nuevo { transform: none; opacity: 1; }
  .bs-consulta b { width: 199px; border-right-color: transparent; }
  .bs-r { opacity: 1; transform: none; }
  .cm-punto { transform: scale(1); }
  .cm-aviso { transform: none; opacity: 1; }
  /* Sin animación hay que dejar cada pieza en un estado que se entienda solo. */
  .mt-avance { transform: scaleX(1); }
  .mt-paso, .mt-meta { border-color: var(--accent); background: var(--accent); }
}

/* S5 · Quiénes somos (3 variantes) */
.home-team { padding: var(--sp-sec) 0; }
.home-team-head { text-align: center; max-width: 680px; margin: 0 auto; }
.home-team-head .eyebrow { display: block; margin-bottom: 14px; }
.home-team-head h2 { font-size: var(--fs-section); line-height: 1.12; margin: 0; white-space: nowrap; }
.home-team-lead { color: var(--ink-soft); font-size: var(--fs-body); margin: 14px 0 0; }
/* Acordeón de imágenes (referencia: 21st.dev/@uilayout.contact, adaptado a 2).
   El nombre se ve siempre; el puesto y el botón de LinkedIn están escondidos y
   salen al abrirse el panel. Con dos paneles el gesto es más sutil que con
   cinco: se pasa de 50/50 a 64/36, lo justo para que se note quién manda.
   `focus-within` además del hover: si no, con teclado el botón de LinkedIn es
   inalcanzable, porque vive dentro de lo que está escondido. */
.team-acordeon { display: flex; gap: 14px; max-width: 920px; margin: 34px auto 0; }
.ta-panel {
  position: relative; flex: 1 1 0; min-width: 0;
  height: clamp(360px, 44vw, 540px);
  border-radius: 20px; overflow: hidden;
  background: var(--bg-2);
  transition: flex-grow .55s cubic-bezier(.2,.7,.2,1);
}
.ta-panel:hover, .ta-panel:focus-within { flex-grow: 1.78; }
.ta-panel img {
  width: 100%; height: 100%; object-fit: cover; object-position: center 22%;
  display: block; border-radius: inherit;
  transition: transform .7s cubic-bezier(.2,.7,.2,1);
}
.ta-panel:hover img, .ta-panel:focus-within img { transform: scale(1.045); }
/* El velo no se anima (un degradado no interpola): se queda fijo y lo bastante
   oscuro abajo para que el blanco se lea con o sin panel abierto. */
.ta-velo {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(20,21,24,0) 38%, rgba(20,21,24,.5) 66%, rgba(20,21,24,.86) 100%);
}
.ta-info { position: absolute; left: 0; right: 0; bottom: 0; padding: 22px 24px; z-index: 1; }
.ta-info h3 {
  font-family: var(--font-serif); font-weight: 500;
  font-size: clamp(19px, 1.9vw, 26px); line-height: 1.15;
  margin: 0; color: var(--white);
  text-shadow: 0 1px 12px rgba(0,0,0,.35);
}
.ta-oculto {
  overflow: hidden; max-height: 0; opacity: 0; transform: translateY(9px);
  transition: max-height .5s cubic-bezier(.2,.7,.2,1), opacity .34s ease,
              transform .5s cubic-bezier(.2,.7,.2,1), margin-top .5s cubic-bezier(.2,.7,.2,1);
}
.ta-panel:hover .ta-oculto, .ta-panel:focus-within .ta-oculto {
  max-height: 130px; opacity: 1; transform: none; margin-top: 9px;
}
.ta-puesto {
  font-family: var(--font-sans); font-size: 13.5px; font-weight: 500;
  letter-spacing: .02em; color: rgba(255,255,255,.84); margin: 0 0 15px;
}
/* Variante de Nosotros: el mismo acordeón, con una línea más al abrirse —
   lo que hace cada uno. Va aparte porque `max-height` tiene que ser un número
   concreto para que la transición funcione, y con la línea de más no cabe en
   los 130px de la home. Ojo: NO subir el 130 general; el sobrante se nota al
   cerrar, porque la transición recorre el hueco vacío. */
.ta-mas .ta-puesto { margin-bottom: 4px; }
.ta-hace {
  font-family: var(--font-serif); font-style: italic;
  font-size: clamp(15px, 1.35vw, 18px); line-height: 1.3;
  color: var(--white); margin: 0 0 15px;
  text-shadow: 0 1px 12px rgba(0,0,0,.35);
}
.team-acordeon.ta-mas .ta-panel:hover .ta-oculto,
.team-acordeon.ta-mas .ta-panel:focus-within .ta-oculto { max-height: 190px; }
/* Botón de LinkedIn: pastilla blanca sobre la foto, naranja al pasar por
   encima. El logotipo va en el color del texto, no en el azul de LinkedIn:
   un punto azul en una paleta naranja canta, y aquí manda la marca de casa. */
.ta-li {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 10px 17px 10px 14px; border-radius: 999px;
  /* El texto NO puede ir a --ink: este botón vive sobre una foto, no sobre el
     fondo de la página, y --ink se vuelve blanco en modo oscuro — quedaba
     blanco sobre la pastilla blanca. Literal a propósito. */
  background: var(--white); color: #191A1E;
  font-family: var(--font-sans); font-size: 13px; font-weight: 600; line-height: 1;
  text-decoration: none; white-space: nowrap;
  box-shadow: 0 8px 22px rgba(0,0,0,.24);
  transition: background-color .25s ease, color .25s ease, transform .25s cubic-bezier(.2,.7,.2,1), box-shadow .25s ease;
}
.ta-li svg { width: 17px; height: 17px; flex: 0 0 auto; display: block; }
.ta-li:hover { background: var(--accent); color: var(--white); transform: translateY(-2px); box-shadow: 0 12px 26px rgba(247,86,43,.4); }
.ta-li:focus-visible { outline: 2px solid var(--white); outline-offset: 3px; }

/* S6 · Opinan de nosotros (placeholder de reseñas Google) */
.home-reviews { padding: var(--sp-sec) 0; }
.home-reviews-head { text-align: center; max-width: 680px; margin: 0 auto; }
.home-reviews-head .eyebrow { display: block; margin-bottom: 14px; }
.home-reviews-head h2 { font-size: var(--fs-section); line-height: 1.12; margin: 0; }
.faq-wrap h2 { font-size: var(--fs-section); } /* FAQ: título = rol sección (global) */
 /* home: respuestas FAQ a 15px, como las tarjetas "Por qué" */
/* Columnas que suben solas (referencia: 21st.dev/@sshahaider). Sólo se toma
   de ahí el movimiento y el estilo de tarjeta: el contenido de las reseñas y
   las estrellas se quedan tal cual estaban. */
.rev-cols {
  display: flex; justify-content: center; gap: 18px;
  max-width: 880px; margin: 34px auto 0;
  /* 470 y no 540: medido, a 540 se leen 3,8 tarjetas de media y a ratos una
     está repetida; a 470 se leen 3,3 y la repetición es la misma pero mucho
     menos frecuente. Con sólo tres reseñas no hay altura que la evite del todo
     —el bucle tiene que repetir—, pero justo encima pone "3 reseñas en
     Google", así que nadie se lleva una idea equivocada. Cuando haya seis o
     más, esto se puede subir y hasta poner una tercera columna. */
  height: clamp(380px, 42vw, 470px);
  overflow: hidden;
  /* Las tarjetas no se cortan en seco arriba y abajo, se desvanecen. */
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 13%, #000 87%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 13%, #000 87%, transparent 100%);
}
.rev-col {
  flex: 1 1 0; min-width: 0;
  /* align-self: flex-start es imprescindible. Por defecto el hijo de un flex
     en fila se estira al alto del contenedor (540px), y entonces el -50% del
     bucle salta 270px en vez de una vuelta entera (832px): la lista se movía
     un tercio y volvía atrás de golpe. Así la columna mide lo que mide su
     contenido y el 50% es exactamente una vuelta. */
  align-self: flex-start;
  display: flex; flex-direction: column;
  will-change: transform;
  animation: rev-sube 34s linear infinite;
}
.rev-col-2 { animation-duration: 42s; animation-delay: -9s; }
/* Al pasar el cursor se para: si no, no hay forma de leer una reseña entera. */
.rev-cols:hover .rev-col { animation-play-state: paused; }
/* El hueco va en margin, NO en gap: la columna lleva la lista DOS veces y el
   bucle salta al -50% de su alto. Con gap, ese 50% cae en mitad de un hueco y
   se ve el salto; con margin-bottom en cada tarjeta, las dos vueltas miden
   exactamente lo mismo y el corte es invisible. */
.rev-card {
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 18px;
  padding: 24px; margin-bottom: 18px; flex: 0 0 auto;
  box-shadow: 0 10px 26px rgba(25,26,30,.05);
}
@keyframes rev-sube { to { transform: translateY(-50%); } }
html[data-theme="dark"] .rev-card { background: rgba(255,255,255,.04); box-shadow: 0 10px 26px rgba(0,0,0,.3); }
.rev-card.is-ph { border-style: dashed; }
.rev-top { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.rev-g { font-family: var(--font-serif); font-weight: 700; color: var(--accent); font-size: 20px; }
.rev-stars { color: #f5a623; letter-spacing: 2px; }
.rev-ph-text { color: var(--ink-faint); font-style: italic; font-size: 14px; margin: 0; }
.rev-author { display: flex; align-items: center; gap: 10px; margin-top: 18px; }
.rev-av { width: 34px; height: 34px; border-radius: 50%; background: var(--line); }
.rev-line { height: 8px; width: 90px; border-radius: 4px; background: var(--line); }
/* Tarjetas de reseña reales (Google) */
.rev-text { color: var(--ink); font-size: 15px; line-height: 1.62; margin: 0; }
.rev-agg { margin-top: 10px; color: var(--ink-soft); font-size: 14px; }
.rev-agg .rev-stars { margin-right: 4px; }
.rev-agg strong { color: var(--ink); font-weight: 700; }
.rev-author .rev-av { width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 15px; color: var(--accent-700); background: var(--accent-soft); flex: 0 0 auto; }
.rev-who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.rev-name { font-weight: 600; font-size: 14px; color: var(--ink); }
.rev-meta { font-size: 12px; color: var(--ink-faint); }

/* Responsive Home */
/* Sin cursor no hay acordeón: los paneles se apilan y enseñan todo. */
@media (max-width: 760px) {
  .team-acordeon { flex-direction: column; gap: 16px; max-width: 460px; }
  .ta-panel, .ta-panel:hover, .ta-panel:focus-within { flex: none; flex-grow: 0; height: clamp(300px, 80vw, 420px); }
  .ta-oculto, .ta-panel:hover .ta-oculto { max-height: none; opacity: 1; transform: none; margin-top: 9px; }
}
/* Bento (S4): 3 columnas → 2 → 1. A dos columnas, una tarjeta ancha ocupa la
   fila entera; a una, todas valen lo mismo y las filas dejan de tener suelo. */
@media (max-width: 1080px) {
  .bento-grid { grid-template-columns: repeat(2, 1fr); }
  /* "Siempre al día" deja de ser ancha: si no, la última tarjeta se queda
     sola y la retícula termina con un hueco. Así queda 1 / 2+3 / 4 / 5+6. */
  .bento-grid > .bento-card:nth-child(5) { grid-column: span 1; }
}
@media (max-width: 640px) {
  .bento-grid { grid-template-columns: 1fr; grid-auto-rows: auto; }
  .bento-card.is-wide { grid-column: span 1; }
  .bento-fx { min-height: 112px; }
}
@media (max-width: 920px) {
  .home-geo-grid { grid-template-columns: 1fr; }
  .rev-cols { max-width: 620px; }
}
@media (max-width: 700px) {
  /* en pantallas estrechas la frase vuelve a poder partir (evita desborde horizontal) */
  .home-team-head h2 { white-space: normal; }
}
@media (max-width: 600px) {
  /* Una sola columna: con dos, en el móvil las tarjetas quedan ilegibles. */
  .rev-cols { max-width: 380px; }
  .rev-col-2 { display: none; }
}

/* ==========================================================================
   CONSISTENCIA MÓVIL (2026-07-08) — mismo aire bajo el header en todas las
   páginas. En escritorio los heros centran su contenido (min-height 100vh);
   en móvil eso producía huecos de 0 a 194px según el contenido de cada página.
   Regla: hueco visual = padding-top − 120px (por el margin-top:-120px del hero).
   ========================================================================== */
@media (max-width: 900px) {
  .svc-hero,
  .page-seo .svc-hero,
  .page-ecommerce .svc-hero,
  .page-consultoria-ia .svc-hero {
    min-height: 0;
    align-items: flex-start;
    padding-top: 192px;    /* ≈72px de aire bajo la píldora en todas */
    padding-bottom: 64px;
  }
  .blog-intro { padding-top: 30px; }   /* el blog llevaba ~104px de hueco */

  /* Titular del blog centrado en tablet y móvil (11-sep). Va la cabecera
     ENTERA —miga, titular y bajada—: centrar sólo el titular y dejar la miga
     pegada a la izquierda justo encima se lee como un descuadre, no como una
     decisión. En escritorio se queda alineada a la izquierda.
     La bajada (la que usan los archivos de categoría, que sí la tienen) lleva
     `max-width: 56ch`: sin `margin-inline: auto` el texto se centraría dentro
     de una caja que sigue pegada a la izquierda. */
  .blog-intro { text-align: center; }
  .blog-crumb { justify-content: center; }
  .blog-intro .lead { margin-inline: auto; }

  /* Y lo mismo en la cabecera del ARTÍCULO: miga, titular, autor y los botones
     de Escuchar y Compartir, todo al centro en tablet y móvil. En escritorio no
     se toca.
     El `margin-inline: auto` del titular no es de adorno: lleva `max-width:
     18ch`, y un bloque más estrecho que su hueco no se centra por mucho que el
     texto vaya centrado. Y la barra de autor va en columna porque su reparto es
     `space-between`: centrarla en fila dejaría al autor y a los botones
     pegados el uno al otro en medio. */
  .post-hero { text-align: center; }
  .post-hero .blog-crumb { justify-content: center; }
  .post-hero h1 { margin-inline: auto; }
  .post-meta-bar { flex-direction: column; align-items: center; gap: 16px; }
  .post-actions { justify-content: center; }

  /* LA FICHA DEL AUTOR, EN COLUMNA (12-sep). En fila no cabe: el nombre lleva
     detrás la descripción corta y se va a dos o tres renglones, con lo que el
     bloque de texto se comía todo el ancho y el retrato quedaba descolgado a
     la izquierda, pegado al borde, contra un texto centrado. Retrato arriba y
     firma debajo, los dos al centro, que es como está el resto de la cabecera. */
  .post-author-card { flex-direction: column; gap: 10px; }
  /* Una medida más corta que la caja: el nombre y el oficio parten en dos o
     tres renglones parejos en vez de barrer la pantalla de lado a lado. */
  .post-author-card .pa-name { max-width: 32ch; margin-inline: auto; }
  .post-meta-line { justify-content: center; }
}

/* ==========================================================================
   SIN LÍNEAS SEPARADORAS ENTRE SECCIONES (2026-07-08)
   El diseño ya delimita las secciones con fondos y aire; la línea sobraba.
   (Las líneas internas de tarjetas, FAQ y footer no se tocan.)
   ========================================================================== */
.statement, .cta, .pipeline-wrap, .feature, .principles, .feat-block,
.next-steps, .faq-wrap, .post-grid-wrap, .gallery-wrap, .newsletter,
.why-grafs, .seo-svc, .seo-team, .seo-window, .eml-svc, .eml-spec-e,
.eml-tools, .ec-case, .ec-experts-sec, .ci-svc, .ci-tech, .ci-aud,
.home-geo, .home-why, .home-team, .home-reviews, .contact-wrap,
main > section, body > section { border-top: 0; }

/* ==========================================================================
   HEROS DE SERVICIO SIN IMAGEN DECORATIVA (2026-07-08) — en escritorio y móvil.
   El texto pasa a columna única centrada en el ancho de lectura.
   ========================================================================== */
.svc-hero .svc-visual { display: none; }
.svc-hero .container { grid-template-columns: 1fr; }
.svc-hero .svc-hero-text { max-width: 880px; }

/* Método (Quiénes somos) en móvil: reveals secuenciales del apilado (mismo
   proceso e información que el scrollytelling de escritorio). */
@media (max-width: 900px) {
  .mfx-anim { opacity: 0; transform: translateY(22px); transition: opacity .6s ease, transform .6s cubic-bezier(.16,1,.3,1); }
  .mfx-anim.in { opacity: 1; transform: none; }
}

/* Índice de servicios SEO como acordeón en móvil (2026-07-08).
   El JS de page-seo recoloca cada .sip-card bajo su título (.sil-row)
   dentro de un envoltorio .sip-acc que se pliega con grid 0fr→1fr. */
.seo-idx--acc .seo-idx-list { gap: 10px; }
.seo-idx--acc .sil-row {
  width: 100%; justify-content: space-between;
  background: var(--bg-2); border: 1px solid var(--line);
}
html[data-theme="dark"] .seo-idx--acc .sil-row { background: rgba(255,255,255,.04); }
.seo-idx--acc .sil-row::after {
  content: '+'; flex: 0 0 auto; margin-left: 12px;
  font-size: 24px; font-weight: 300; line-height: 1; color: var(--ink-soft);
  transition: transform .3s ease, color .3s ease;
}
.seo-idx--acc .sil-row.is-on { background: var(--bg-2); }
.seo-idx--acc .sil-row.is-on::after { transform: rotate(45deg); color: var(--accent); }
.sip-acc { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .38s cubic-bezier(.4,0,.2,1); }
.sip-acc.is-open { grid-template-rows: 1fr; }
.sip-acc > .sip-card {
  display: flex; position: relative; inset: auto;
  opacity: 0; visibility: visible; transform: none;
  overflow: hidden; min-height: 0; padding: 0 4px;
  transition: opacity .3s ease;
}
.sip-acc.is-open > .sip-card { opacity: 1; transition-delay: .12s; }
.sip-acc .sv { min-height: 180px; margin-top: 14px; }
.sip-acc .sip-d { margin: 0 0 18px; }

/* Fotos reales de equipo (2026-07-08) — sustituyen los huecos de iniciales.
   Assets en img/equipo/: ivan|aitor.webp (4:5, 800x1000) y *-cara.webp (320²). */
.syn-av, .ese-avatar { overflow: hidden; }
.syn-av img, .ese-avatar img {
  width: 100%; height: 100%; object-fit: cover; border-radius: inherit; display: block;
}
.flip-front .fdr-photo {
  width: 100%; flex: 1 1 auto; min-height: 0; object-fit: cover;
  border-radius: 12px; margin-bottom: 16px;
}

/* Heros de servicio centrados como el de la landing (2026-07-08) */
.svc-hero .svc-hero-text { margin-left: auto; margin-right: auto; text-align: center; }
.svc-hero h1.serif { margin-left: auto; margin-right: auto; }
.svc-hero .svc-hero-text .lead { margin-left: auto; margin-right: auto; }
.svc-hero .svc-hero-text .serif { margin-left: auto; margin-right: auto; }
.svc-hero .svc-actions { justify-content: center; }

/* En modo oscuro los blobs ya destacan sobre el fondo: se mantiene la intensidad previa */
html[data-theme="dark"] .hero-blob.b1 { background: radial-gradient(circle, rgba(247,86,43,.50), transparent 70%); }
html[data-theme="dark"] .hero-blob.b2 { background: radial-gradient(circle, rgba(74,144,226,.42), transparent 70%); }
html[data-theme="dark"] .hero-blob.b3 { background: radial-gradient(circle, rgba(255,125,82,.38), transparent 70%); }
html[data-theme="dark"] .page-home .hero-blob.b1 { background: radial-gradient(circle, rgba(247,86,43,.20), transparent 70%); }
html[data-theme="dark"] .page-home .hero-blob.b2 { background: radial-gradient(circle, rgba(74,144,226,.13), transparent 70%); }
html[data-theme="dark"] .page-home .hero-blob.b3 { background: radial-gradient(circle, rgba(255,125,82,.16), transparent 70%); }

/* Método móvil: escenario del morph del coil (nace como la figura y se
   despliega).  Lo que era `display: flex` EN FILA con `min-height: 250px` se
   fue al bloque de «MÉTODO EN MÓVIL Y TABLET»: en fila, los dos textos se
   colocaban al lado de la espiral en vez de encima y debajo. */
@media (max-width: 900px) {
  .mfx-bigwrap.mfx-morph .mfx-big { will-change: transform; }
}

/* Grafismo "¿Por qué Grafs?" (webs) — la web por capas, en axonometría.
   Cuarta versión.  Cayeron la ilustración literal, la malla de bandas y la
   trenza; las tres últimas eran abstracciones mínimas y lo que se pedía era lo
   contrario.  La geometría se genera en page-webs.php: aquí sólo color y ritmo.

   Los planos llevan relleno `--bg` a propósito.  Es lo que tapa las guías de
   despiece por dentro y las deja ver sólo en los huecos entre capas — sin eso
   las tres verticales cruzan el dibujo entero y parece un marco. */
.wg-art { width: 100%; height: 100%; display: block; }

/* ===== formacion-ia · «¿Para quien es?» · tres tarjetas con escala =====
   El glifo de persona es el MISMO y del mismo tamano en las tres tarjetas; lo
   unico que cambia es cuantos hay.  Eso es lo que hace que 18, 6 y 1 se lean
   como una escala —el tamano del equipo— y no como tres dibujos distintos.
   Elegida entre tres el 2026-09-02; las otras dos (acordeon y fila sin cajas)
   se descartaron.

   OJO: este bloque se borro por accidente el 2026-09-02 al limpiar las
   variantes descartadas, y la seccion salio con las personas a pantalla
   completa y en negro macizo —sin el, el SVG cae al `fill` negro por defecto
   y `.pq-art` no tiene quien le ponga tope de ancho—.  No lo quites al podar
   CSS muerto: el `page-formacion-ia.php` lo usa entero. */
.pq-persona circle, .pq-persona path { fill: none; stroke: var(--ink-faint); stroke-width: 1.5;
  stroke-linecap: round; vector-effect: non-scaling-stroke; }
.pq-persona.es-acento circle, .pq-persona.es-acento path { stroke: var(--accent); }
.pq-art svg { display: block; width: 100%; height: auto; overflow: visible; }

.pq-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 44px; }
.pq-card { border: 1px solid var(--line); border-radius: 18px; background: var(--bg-2); padding: 26px 24px;
  transition: border-color .25s ease, transform .25s ease; }
html[data-theme="dark"] .pq-card { background: rgba(255,255,255,.03); }
.pq-card:hover { border-color: var(--accent); transform: translateY(-4px); }
.pq-card .pq-art { max-width: 190px; margin-bottom: 24px; }
.pq-card h3 { font-family: var(--font-serif); font-weight: 500; font-size: var(--fs-h3); margin: 0 0 8px; }
.pq-card p { color: var(--ink-soft); margin: 0; }

@media (max-width: 860px) { .pq-cards { grid-template-columns: 1fr; } }

/* ===== formacion-ia · S «Por que Grafs» · el mapa de conexiones =====
   Elegido entre tres el 2026-09-02.  Sustituye a la matriz de celdas: alli los
   huecos vacios se leian como carencias del equipo, un boletin de notas.

   No es un SVG entero.  Los logos son `img` y no caben dentro de un SVG, asi
   que van dos columnas de HTML y, en medio, un SVG que SOLO dibuja los hilos.
   `preserveAspectRatio="none"` para que el lienzo se estire a lo que sobre
   entre las dos columnas —de ahi las coordenadas en tanto por ciento— y
   `non-scaling-stroke` para que el estirado no engorde el trazo.
   Las filas miden todas lo mismo, asi que el centro de la fila k cae en el
   (k + 0,5) / n del alto y los extremos encajan sin medir nada en JS. */
.mx { display: grid; grid-template-columns: auto minmax(48px, 1fr) auto; align-items: stretch; }
.mx-col { list-style: none; margin: 0; padding: 0; }
.mx-col li { height: 46px; display: flex; align-items: center; }
.mx-izq { justify-items: end; }
.mx-izq li { justify-content: flex-end; padding-right: 14px; }   /* aire: sin el, el hilo salia pegado al logotipo */
/* Solo el simbolo, sin el nombre.  CAJA CUADRADA FIJA de 30x30 con `contain`,
   no alto libre: con el alto suelto cada marca ocupaba lo que le pedia su
   proporcion y NotebookLM —el unico que no es cuadrado, 1,36:1— salia un 36%
   mas ancho que los demas y cantaba.  Con la caja, el que no es cuadrado se
   encoge dentro de ella y los cinco se leen del mismo tamano. */
.mx-izq img { width: 30px; height: 30px; object-fit: contain; display: block;
  filter: brightness(0); opacity: .38; transition: opacity .35s ease; }
html[data-theme="dark"] .mx-izq img { filter: brightness(0) invert(1); }
.mx-izq li.es-vivo img { opacity: .95; }
.mx-der li { font-family: var(--font-sans); font-size: 15px; font-weight: 500;
  color: var(--accent); opacity: .5; padding-left: 14px; transition: opacity .35s ease; }
.mx-der li.es-vivo { opacity: 1; }
.mx-medio { position: relative; min-width: 0; }
.mx-hilos { position: absolute; inset: 0; width: 100%; height: 100%; display: block; overflow: visible; }
.mx-hilo { fill: none; stroke: var(--ink-faint); stroke-opacity: .38; stroke-width: 1.2;
  vector-effect: non-scaling-stroke; transition: stroke .35s ease, stroke-opacity .35s ease, stroke-width .35s ease; }
.mx-hilo.es-vivo { stroke: var(--accent); stroke-opacity: 1; stroke-width: 2; }
.mx-nota { font-size: 12.5px; line-height: 1.5; color: var(--ink-faint); margin: 18px 0 0; max-width: 42ch; }

/* El mapa ocupa TODO el alto de la seccion (2-sep).  Antes las filas median
   46px fijos y el dibujo se quedaba en un cuarto del alto del acordeon, con
   medio hueco vacio debajo.  Ahora las filas son `1fr` del alto disponible,
   asi que el mapa CRECE con la columna de la izquierda —que es la que manda
   el alto de la fila— y a cambio se estrecha: los hilos ganan recorrido
   vertical y el manojo se lee mucho mejor.

   Dos cosas que sostienen esto y no se pueden tocar por separado:
   · `align-items: stretch` en la rejilla.  Con el `start` de la regla general
     la columna derecha se queda con su alto intrinseco y no hay nada que
     repartir.
   · `grid-auto-rows: 1fr` —no `repeat(5, 1fr)`— para que siga valiendo si
     cambia el numero de filas.  Y tienen que ser IGUALES: la cuenta de los
     hilos da por hecho que el centro de la fila k cae en el (k + 0,5) / n del
     alto, y con filas desiguales los extremos se despegan de los logos.
   El `position: sticky` de `.wg-right` se va: con el dibujo tan alto como el
   acordeon no hay recorrido en el que pegarse. */
/* El titular cuelga de la rejilla y cruza las dos columnas, asi que la fila de
   contenido —acordeon y grafismo— empieza POR DEBAJO de el.  Colgado de
   .wg-left, el grafismo arrancaba a la altura del titulo, o sea por su mitad.
   `order: -2` es para el movil: ahi .wg-right lleva `order: -1` para subir el
   dibujo por encima del acordeon, y sin esto el titulo se quedaria debajo. */
.page-formacion-ia .wg-grid { align-items: stretch; }
/* `margin-bottom: 0` a proposito: el aire entre titulo y contenido lo pone ya
   el `gap: 64px` de la rejilla, y sumarle margen dejaba una banda muerta de
   100px. */
.page-formacion-ia .wg-titulo { grid-column: 1 / -1; order: -2;
  max-width: 30ch; text-wrap: balance; margin: 0; }
/* En móvil y tablet el orden es TÍTULO → ACORDEÓN → dibujo.  La regla general
   sube el visual por encima del texto (`.wg-right { order: -1 }`), que es lo
   que quiere webs; aquí Aitor lo pidió al revés: primero el porqué y el
   grafismo al final, cerrando.  Se anula sólo en esta página. */
@media (max-width: 900px) {
  .page-formacion-ia .wg-right { order: 1; }
}
.page-formacion-ia .wg-right { position: static; display: flex; flex-direction: column; }
.page-formacion-ia .mx { flex: 1 1 auto; min-height: 320px; max-width: 460px; width: 100%; margin-inline: auto; }
.page-formacion-ia .mx-col { display: grid; grid-auto-rows: 1fr; }
.page-formacion-ia .mx-col li { height: auto; }
/* El pie comparte tope de ancho con el mapa y el mismo centrado, pero alineado
   a la DERECHA y muy pegado: asi cae bajo la columna de tareas, que es a lo
   que se refiere, en vez de flotar debajo del dibujo entero.  Va mas apagado
   a proposito —es una nota al pie, no un texto que haya que leer— y por eso
   lleva `opacity` ademas del color: `--ink-faint` ya es el gris mas claro que
   hay y no queda tono por debajo al que bajar. */
.page-formacion-ia .mx-nota { max-width: 460px; width: 100%; margin: 8px auto 0;
  text-align: right; opacity: .55; }
@media (max-width: 900px) {
  .page-formacion-ia .mx { min-height: 260px; }
}
@media (max-width: 900px) {
  .mx-col li { height: 42px; }
  .mx-izq img { width: 25px; height: 25px; }
  .mx-der li { font-size: 14px; }
}

.wg-img-capas { aspect-ratio: 640 / 620; background: transparent; border: none; border-radius: 0; }

.wg-capas path { vector-effect: non-scaling-stroke; }
.wg-guias path { fill: none; stroke: var(--line); stroke-width: 1; stroke-dasharray: 3 5; }
.wg-plano { fill: var(--bg); stroke: var(--ink-faint); stroke-opacity: .45; stroke-width: 1.2; }
.wg-pieza { fill: none; stroke: var(--ink-faint); stroke-opacity: .5; stroke-width: 1; }
.wg-pieza-acento { stroke: var(--accent); stroke-opacity: 1; fill: var(--accent-soft); }
.wg-arbol path { fill: none; stroke: var(--ink-faint); stroke-opacity: .55; stroke-width: 1; }
/* La capa de arriba es la que se ve desde fuera: va teñida, y es la que hace
   que el ojo entre por ahí y baje. */
.wg-capa-viva .wg-plano { fill: var(--accent-soft); stroke: var(--accent); stroke-opacity: .55; }
.wg-rot {
  font-family: var(--font-sans); font-size: 13px; font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase; fill: var(--ink-faint);
}

/* Entrada: el despiece se ABRE desde el centro.  Cada capa arranca a medio
   camino de su sitio (`--d` es su distancia con signo a la capa central) y se
   separa.  La opacidad final va en `--o` y no en una clase por capa: la usa
   también la transición, y una clase la habría ganado por especificidad —el
   fallo que ya se comió el degradado de la malla. */
.wg-capa { opacity: 0; transform: translateY(calc(var(--d) * -46px)); }
.wg-img.in .wg-capa {
  opacity: var(--o); transform: none;
  transition: opacity .5s ease, transform .7s cubic-bezier(.2,.7,.2,1);
  transition-delay: calc(var(--i, 0) * 90ms);
}
@media (prefers-reduced-motion: reduce) {
  .wg-capa { opacity: var(--o); transform: none; }
  .wg-img.in .wg-capa { transition: none; }
}

/* Estado "Próximamente" (blog sin entradas / catálogos vacíos) */
.soon-panel { text-align: center; padding: clamp(40px, 8vw, 90px) 0; }
.soon-panel .eyebrow { margin-bottom: 12px; }
.soon-panel h2 { max-width: 22ch; margin: 0 auto; }

/* Título del post destacado clicable */
.fp-body h2 .fp-title-link { color: inherit; text-decoration: none; }
.fp-body h2 .fp-title-link:hover { color: var(--accent); }

/* ==========================================================================
   EL RÍO / MANIFIESTO, ESCONDIDO A LA ESPERA DE LAS FOTOS (2026-09-02)

   Aitor: esconderlo en los tres —móvil, tablet y escritorio— hasta que estén
   las fotos de trabajo real. Hoy el pasillo va con las SIETE fotos de stock de
   servicios, justo las que se decidió quitar de la home el 28-ago: enseñarlas
   aquí desmiente lo que dice la sección.

   SE ESCONDE, NO SE BORRA, y por eso va así y no quitando el marcado:
   · El bloque es caro de reconstruir. La proyección del pasillo la gobiernan
     nueve constantes de `$grafs_rio_ruta` en `page-quienes-somos.php` (fuga,
     ancho, alto, alto_nace, alto_sale, carril_nace, carril_sale, apertura,
     giro_nace, giro_sale) y los `@keyframes` se generan a partir de ellas.
   · El río es CSS puro, sin JS: con `display: none` las animaciones ni siquiera
     corren, así que esconderlo no cuesta nada en batería.
   · Volver a encenderlo es BORRAR ESTE BLOQUE. Nada más.

   Lo que hay que hacer antes de encenderlo: cambiar las siete rutas de
   `$grafs_rio` por las fotos reales. La tarjeta es VERTICAL (18×25): una foto
   horizontal se recorta fuerte por los lados.

   Y lo que se va con él, que conviene saber: el `h2` «Cuando ayudamos a tu
   empresa a crecer, también crecemos nosotros» —copy de Aitor— y su bajada.
   Mientras esté escondido, esa página no los tiene ni para quien lee ni para
   quien indexa.
   ========================================================================== */
#manifiesto { display: none; }

/* ==========================================================================
   MÉTODO EN MÓVIL Y TABLET (2026-09-02)
   Sustituye a la simplificación del 2026-07-08, que apagaba la espiral con un
   «queda para una versión futura». Esa versión es ésta: la espiral y los dos
   textos YA estaban montados y animados —incluido el morph de móvil, que hace
   nacer el bucle central y lo despliega—; sólo estaban tapados por un
   `display: none`. No se ha construido nada nuevo, se ha encendido.

   Lo que cambia respecto a escritorio:
   · Las cuatro fases van NUMERADAS 1-4 y SIN recuadro. El recuadro en una
     columna estrecha no separa nada que el aire no separe ya, y con cuatro
     bloques seguidos el número dice el orden mejor que una caja.
   · Los cuatro titulares, del MISMO cuerpo. En escritorio, Cimientos y
     Crecimiento van a 24px y Diagnóstico y Escalar a 20 (`.mA-card.emph h3`),
     porque allí son dos parejas colocadas en aspa y el tamaño distingue el par.
     Apiladas en una columna eso deja de significar nada y sólo parece un error.
   · «Mejora constante» ARRIBA de la espiral y «El análisis abre y cierra cada
     ciclo» DEBAJO, que es como se lee el dibujo: uno abre y el otro cierra.
     En escritorio van en diagonal porque hay sitio; aquí no.
   ========================================================================== */
@media (max-width: 900px) {
  /* El bucle pequeño y los conectores punteados siguen fuera: los conectores
     unen tarjetas a flechas en una composición en aspa que aquí no existe, y el
     bucle pequeño lo cuenta ya la espiral de abajo. */
  .mfx-graph, .mfx-links { display: none; }
  .method .m-head { margin-bottom: 28px; }   /* aire entre el título y Diagnóstico */
  .mfx-scene { margin-top: 0; }
  .mfx-stage { display: flex; flex-direction: column; gap: 16px; }
  .mfx-card.pos-tl { order: 1; }   /* Diagnóstico */
  .mfx-card.pos-br { order: 2; }   /* Cimientos */
  .mfx-card.pos-bl { order: 3; }   /* Crecimiento */
  .mfx-card.pos-tr { order: 4; }   /* Escalar */

  /* --- la fase: la MISMA tarjeta de escritorio, con el número dentro -------
     La caja se queda tal cual —`.mA-card`, `.light` y `.emph` siguen mandando
     el relleno, el borde y el fondo—: lo único que se añade es el número.  Se
     probó a quitarla y Aitor la quiso de vuelta.

     Rejilla de dos columnas en vez de número en `position: absolute`: así el
     número se alinea SOLO con la primera línea del titular pase lo que pase con
     el cuerpo de letra, y no hay que ir cuadrando un `top` a mano.
     El `::before` es un elemento de rejilla más; el resto del contenido se
     manda entero a la segunda columna. */
  .mfx-stage .mfx-card {
    position: static; width: auto; transform: none; margin: 0;
    min-height: 0;                                  /* los 184/290px de escritorio, fuera */
    display: grid; grid-template-columns: 26px 1fr; column-gap: 12px; row-gap: 8px;
  }
  .mfx-stage .mfx-card > * { grid-column: 2; }
  .mfx-stage .mfx-card::before {
    grid-column: 1; grid-row: 1;
    font-family: var(--font-serif); font-size: var(--fs-h3); font-weight: 500;
    line-height: 1.25; color: var(--accent); text-align: right;
  }
  /* El número va atado a la MISMA clase que el `order`, no a un contador: un
     contador cuenta en orden de marcado —tl, bl, tr, br— y saldría 1, 3, 4, 2. */
  .mfx-card.pos-tl::before { content: "1"; }
  .mfx-card.pos-br::before { content: "2"; }
  .mfx-card.pos-bl::before { content: "3"; }
  .mfx-card.pos-tr::before { content: "4"; }

  .mfx-stage .mfx-card h3,
  .mfx-stage .mfx-card.emph h3 { font-size: var(--fs-h3); line-height: 1.25; margin: 0; }
  .mfx-stage .mfx-card:hover { transform: none; box-shadow: none; border-color: transparent; }

  /* --- la espiral y sus dos textos ---------------------------------------
     `.mfx-morph` es la clase que pone el JS al arrancar el despliegue; las dos
     tienen que declarar lo mismo o el dibujo salta al empezar la animación. */
  .mfx-bigwrap,
  .mfx-bigwrap.mfx-morph {
    position: static; inset: auto; opacity: 1; pointer-events: auto;
    display: flex; flex-direction: column; align-items: stretch;
    /* Aire entre la fase 4 y «Mejora constante»: la separación entre tarjetas
       es de 16px y con 34 el salto de una lista a un dibujo no se leía como
       cambio de bloque. */
    gap: 6px; margin-top: 60px; min-height: 0; overflow: hidden;
  }
  /* Tope de ancho: el lienzo recortado tiene proporción 1,13, así que a 762 de
     ancho el dibujo se iba a 673px de alto y, como la tinta es una banda
     diagonal, casi todo eso era aire.  A 520 la espiral sigue leyéndose y la
     sección deja de tener un boquete. */
  .mfx-big { transform: none; width: 100%; max-width: 520px; margin-inline: auto;
    /* Los textos, más pegados.  El margen negativo NO recorta el dibujo: la
       tinta es una banda DIAGONAL, así que la esquina de arriba a la izquierda
       y la de abajo a la derecha están vacías, y ahí es donde entran los dos
       rótulos.  Medido: sólo hay 10px de caja muerta arriba y abajo; el resto
       de la distancia que se veía era ese triángulo vacío. */
    margin-block: -10px; }
  .mfx-tx { position: static; opacity: 1; max-width: none; text-align: center; margin: 0; }
  .mfx-tx-a { order: -1; }                         /* «Mejora constante», arriba */
  .mfx-tx .mfx-tx-s { margin-left: auto; margin-right: auto; }
  .mfx-tx-h { font-size: clamp(21px, 5.2vw, 26px); }
  /* El `nowrap` de escritorio, fuera: «El análisis abre y cierra cada ciclo» no
     entra en una línea por debajo de 900 y se salía por el borde. */
  .mfx-tx-b .mfx-tx-h { white-space: normal; }
  /* Los DOS márgenes en `auto`.  En escritorio esta bajada lleva
     `margin-left: auto` para pegarse a la derecha bajo su titular; con sólo
     anular ése se quedaba pegada a la izquierda, que es lo que se veía: el
     `max-width: 34ch` la hace más estrecha que la columna, y un bloque más
     estrecho que su hueco no se centra por mucho que el texto vaya centrado.
     Va DESPUÉS de la regla general de `.mfx-tx .mfx-tx-s` porque tienen la
     misma especificidad y gana la última. */
  .mfx-tx-b .mfx-tx-s { margin-left: auto; margin-right: auto; }

  /* --- TRES bucles, no cinco ----------------------------------------------
     A 342px de ancho, cinco copias dejan cada bucle en unos 56px: no se lee una
     espiral, se lee un garabato.  Se quitan las dos de los extremos y los dos
     empalmes que las unían —el primero y el último de los cuatro—, que si no
     quedan dos puentes saliendo hacia la nada.
     Quitar copias NO agranda el dibujo por sí solo: el `viewBox` sigue siendo
     el de cinco y lo que aparece son dos huecos a los lados. Recortarlo es
     cosa del JS de `page-quienes-somos.php`, que lo mide y lo ajusta. */
  .coil-svg .kk2, .coil-svg .kkn2 { display: none; }
  .coil-svg .mfx-joins path:first-child,
  .coil-svg .mfx-joins path:last-child { display: none; }
}

/* ==========================================================================
   TEXTO JUSTIFICADO (01-sep-2026)
   Pedido por Aitor sección a sección. Va en un bloque ÚNICO y no repartido por
   cada sección a propósito: es una decisión editorial, y así se ve de un golpe
   qué está justificado y se puede revisar o revertir en un solo sitio.

   `hyphens: auto` acompaña SIEMPRE al `text-align: justify`, nunca va suelto.
   Sin partir palabras el navegador estira los espacios para cuadrar el margen
   derecho, y en las columnas estrechas de aquí —336px en las tarjetas de
   e-commerce, 381 en las reseñas, 343 en el proceso de webs— se abren ríos
   blancos. Parte porque el documento declara `lang="es"`.

   NO se justifican los titulares ni los subtítulos de sección (`.svc-sub`,
   `.seo-window-big`, `.em-s`, `.em-h`): son de una o dos líneas, donde
   justificar no hace nada y sí estropea el remate. Justificar sólo cambia algo
   a partir del segundo renglón, porque el último de cada párrafo no se estira.

   Tampoco se justifica el TEXTO DE DENTRO DE UN MOCKUP (`.mi-q-text`, las
   preguntas del cuestionario de formación). No es prosa: es la interfaz que
   dibuja el grafismo, y a 269px de ancho el justificado le abría un río
   blanco en mitad de la pregunta. 2-sep. Si aparece más texto de maqueta
   dentro de una sección justificada, va aquí, no a la lista de abajo.
   ========================================================================== */

.home-why p,
.home-reviews .rev-text,
.home-reviews .rev-agg,
.faq-wrap .faq-a,
.contact-side .ci-card p,
.seo-window .lead,
.seo-window .ssa-txt,
.seo-svc .sip-d,
.seo-svc .sb-d,
.eml-why p:not(.em-s):not(.em-h),
.eml-svc .eb-d,
#proceso p,
#expertos .b-desc,
.ec-experts .ec-quote,
.ci-svc .ci-d,
#practica p:not(.mi-q-text),
#practica li {
  text-align: var(--just, justify);
  hyphens: auto;
}

/* Un solo interruptor para los diecisiete selectores de arriba. En móvil el
   justificado PIERDE: a 246px —las tarjetas de e-commerce— entran 3 o 4
   palabras por renglón y los huecos se ven a simple vista, incluso con los
   guiones puestos. Medido y mirado a 390px. Para justificar también en móvil,
   basta con borrar esta regla. */
@media (max-width: 600px) {
  :root { --just: left; }
}

/* ===== HOME · S4 «Por qué elegir a GRAFS» · titular centrado (2-sep) ======
   Móvil y tablet.  Va al corte de 900 —el principal del fichero— y no al 920 de
   la S3: allí el 920 no era una elección, era el ancho en el que la sección
   pasa a una columna y los dos cambios TENÍAN que coincidir.  Aquí el titular
   es un bloque a todo lo ancho, sin nada estructural que lo ate, así que va al
   corte de siempre.

   El `margin-inline: auto` no es de adorno: `.home-why-head` lleva
   `max-width: 940px`, y en tablet el hueco es más estrecho que eso... pero en
   cuanto alguien suba el tope o baje el titular, un bloque más angosto que su
   hueco se quedaría pegado a la izquierda con el texto centrado dentro. */
@media (max-width: 900px) {
  .home-why-head { text-align: center; margin-inline: auto; }
}

/* ===== HOME · CTA · el botón en DOS líneas, sólo en el teléfono (2-sep) ====
   «Cuéntanos qué hace tu empresa y te decimos por dónde empezar» salía en tres
   renglones de 178, 199 y 121px: el último, media línea suelta.

   Se arregla con el RELLENO, no con el cuerpo de letra.  El botón mide 294px
   pase lo que pase —lo fija el flex de `.cta-actions`—, así que bajar el
   relleno de los lados de 22 a 16 le da 12px más de caja al texto y con eso ya
   entra en dos.  Medido: dos renglones de 251px con los 15px de letra
   intactos.  Bajar a 14px también funcionaba, pero empequeñecer la llamada
   principal de la home para ganar un renglón es pagar de más.

   `balance` va con ello para que los dos renglones queden iguales; sin él
   salían 246 y 222.  Y queda 11px de holgura entre el texto (251) y la caja
   (262): si algún día se alarga el copy, esto vuelve a tres líneas — y la
   solución entonces es acortar el copy, no seguir raspando relleno. */
/* ===== HOME · CTA · el titular en TRES líneas, sólo en el teléfono (2-sep) =
   Salía en cuatro, con «elijan:» solo en la segunda.  La composición buena es
   la de escritorio: la primera frase entera en un renglón y la segunda en dos.
   Para eso la primera frase tiene que CABER de una vez, y ahí está todo.

   Lo que NO vale, comprobado:
   · Quitar el `<br>` en móvil para que reparta libre.  Da tres renglones y del
     tamaño bueno, pero ese `<br>` es el único separador entre «elijan:» y «en
     Google»: sin él salen pegados, «elijan:en Google».  Es el mismo tropiezo
     que en el titular del hero.
   · `text-wrap: balance` sin más.  Reparte DENTRO de cada trozo, pero no junta
     los dos renglones del primero en uno: seguían siendo cuatro.
   · Subir el `max-width` del titular.  No es el tope quien aprieta: los 294px
     salen de los rellenos —24 del `.cta` más 24 del `.container` a cada lado—,
     no del `16ch`.

   Lo que vale: bajar el relleno lateral del `.cta` de 24 a 16 —que le da 16px
   más de caja al titular Y al botón— y el cuerpo de 26 a 22.  Con eso la
   primera frase mide 300 en una caja de 310 y entra sola.  `pretty` remata: sin
   él, la segunda frase parte en «…y en la inteligencia / artificial.» y deja
   «artificial.» descolgada.

   Los 22px son el techo: a 23 la primera frase se pasa y vuelven las cuatro
   líneas.  Quedan **10px de holgura**; si se toca el copy, se recomprueba. */
@media (max-width: 600px) {
  .page-home .cta { padding-left: 16px; padding-right: 16px; }
  .page-home .cta .cta-title { font-size: 22px; text-wrap: pretty; }
  .page-home .cta .btn {
    padding-left: 16px; padding-right: 16px;
    text-wrap: balance;
  }
}

/* ===== HOME · S3 · párrafos justificados en el teléfono (2-sep) ============
   Lo pidió Aitor. Va con las dos cosas que el bloque de justificado del fichero
   declara obligatorias, y aquí hacen más falta que en ningún otro sitio:

   · `hyphens: auto` SIEMPRE con `justify`.  Sin partir palabras, el navegador
     estira los espacios para cuadrar el margen derecho, y en 342px se abren
     ríos blancos. Parte porque el documento declara `lang="es"`.
   · `text-align-last: center` para no perder el centrado.  El justificado sólo
     manda en los renglones que no son el último; el último sigue a
     `text-align-last`, que por omisión es el inicio.  Sin esta línea, la
     sección se queda centrada pero cada párrafo remata con un renglón pegado a
     la izquierda, que es peor que las dos cosas por separado.

   OJO con el contexto: el interruptor general `--just: left` apaga el
   justificado por debajo de 600 a propósito, porque en las tarjetas de
   e-commerce —246px— los huecos se ven a simple vista. Aquí la columna mide
   342, que es un caso distinto; por eso esta regla escribe `justify` a pelo en
   vez de tocar la variable, que se llevaría por delante los diecisiete
   selectores de aquella lista. */
@media (max-width: 600px) {
  .home-geo-text p:not(.eyebrow) {
    text-align: justify;
    text-align-last: center;
    hyphens: auto;
  }
}

/* ===== HOME · S3 «Especialistas en IA» · centrada en móvil y tablet (2-sep) =
   El corte es 920, el MISMO en el que la sección pasa de dos columnas a una.
   No es casualidad ni comodidad: centrado con las dos columnas todavía puestas,
   el texto se centraría dentro de su media rejilla y quedaría descolgado del
   dibujo de al lado.  Los dos cambios tienen que ir atados; si un día se mueve
   uno, se mueve el otro.

   El botón se centra solo con el `text-align` porque `.ci-link` es
   `inline-block`; no hace falta `margin: auto`, que además no funcionaría sin
   quitarle antes el `display` en línea.

   El `margin-inline: auto` de los párrafos sí hace falta: llevan `max-width:
   52ch`, y un bloque más estrecho que su hueco se queda pegado a la izquierda
   por mucho que el texto vaya centrado.  A 390 el tope no llega a morder, pero
   de 500 en adelante sí —y en tablet muerde siempre—. */
@media (max-width: 920px) {
  .home-geo-text { text-align: center; }
  .home-geo-text p { margin-inline: auto; }
}

/* --------------------------------------------------------------------------
   Fondo áureo de los S1 de servicio · un punto más al fondo (01-sep-2026)
   Aitor: «aumentar la transparencia de los fondos de todos los S1, que sea un
   poco más claro, más de fondo».

   Un SOLO número para las tres cosas que se ven —el trazo, la espiral y las
   rayas de la caja—, y no tres valores sueltos: si se separan, un día alguien
   afloja una y las otras dos se quedan atrás. El halo naranja del cursor NO
   entra aquí a propósito: es el realce, y aclararlo lo dejaría sin gracia.
   -------------------------------------------------------------------------- */
.oro { --oro-tinta: .55; }
.oro-caja > .oro-trazo { opacity: var(--oro-tinta); }
.oro-caja {
  border-left-color: color-mix(in srgb, var(--line) calc(var(--oro-tinta) * 100%), transparent);
  border-right-color: color-mix(in srgb, var(--line) calc(var(--oro-tinta) * 100%), transparent);
}
.oro-caja::before, .oro-caja::after {
  background: color-mix(in srgb, var(--line) calc(var(--oro-tinta) * 100%), transparent);
}
