/* ═══════════════════════════════════════════════════════════════════
   MATIICORE — componentes del sitio
   base.css trae los tokens. Acá viven las piezas que se repiten.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Saltar al contenido ───────────────────────────────────────────
   Para quien navega con teclado: sin esto hay que tabular por todo el
   menú en cada página. Invisible hasta que recibe foco. */
.saltar{
  position:absolute; left:-9999px; top:0; z-index:200;
  background:var(--lima); color:#000; padding:12px 20px;
  font-weight:700; border-radius:0 0 var(--r-1) 0;
}
.saltar:focus{ left:0 }

/* ── Navegación ─────────────────────────────────────────────────────
   FIJA. En el sitio viejo era `position:relative` y se iba con el scroll,
   así que había 6,4 pantallas seguidas sin ninguna forma de escribir. */
.nav{
  position:fixed; top:0; left:0; right:0; z-index:100;
  background:rgba(10,10,10,.82);
  border-bottom:1px solid transparent;
  transition:background-color var(--t-corta) var(--e-ui),
             border-color var(--t-corta) var(--e-ui);
}
/* El blur va solo en una barra de 68px, no en un área grande: en GPU móvil
   integrada un backdrop-filter grande tira los FPS al piso. */
@supports (backdrop-filter: blur(12px)){
  .nav{ backdrop-filter:blur(12px); background:rgba(10,10,10,.62) }
}
.nav.scrolleado{ background:rgba(10,10,10,.92); border-bottom-color:var(--linea) }

.nav-caja{
  max-width:var(--max); margin-inline:auto; padding:0 var(--gutter);
  height:68px; display:flex; align-items:center; gap:var(--s-6);
}
.nav-marca{ display:block; flex:none }
.nav-marca img{ width:132px; height:auto }

/* El gap baja de 32 a 16 porque cada enlace gana 14px de padding a cada
   lado: el aire entre palabras queda igual, pero ahora el halo tiene
   superficie donde encenderse. Sin padding, la luz sale del texto y se ve
   como una mancha, no como un botón iluminado. */
.nav-links{ display:flex; gap:var(--s-4); margin-left:auto; position:relative }
.nav-links a{
  color:var(--texto-2); text-decoration:none; font-size:var(--fs-small);
  font-weight:500; padding:8px 14px; position:relative; border-radius:10px;
  transition:color var(--t-micro) var(--e-ui);
}
.nav-links a::after{
  content:''; position:absolute; left:14px; right:14px; bottom:2px; height:2px;
  background:var(--lima); transform:scaleX(0); transform-origin:left;
  transition:transform var(--t-corta) var(--e-salida);
}

/* ── El halo ────────────────────────────────────────────────────────
   Portado de un componente de React con framer-motion: en CSS son dos
   pseudo-elementos y una transición, sin librería ni JS.

   Del original se toma la ESTÉTICA —la luz que se enciende debajo del
   botón— y se deja fuera el volteo 3D de la palabra sobre su propio eje:
   en un menú de navegación, el texto girando compite con la lectura justo
   cuando la persona está decidiendo a dónde ir.

   🔴 Y el color se cambió a propósito. El componente traía azul, naranja,
   verde y rojo, uno por ítem. Cuatro colores nuevos en un sitio que es
   negro + lima no se leen como diseño: se leen como plantilla descargada. */
.nav-links a::before{
  content:''; position:absolute; inset:0; z-index:-1; border-radius:12px;
  background:radial-gradient(circle,
    rgba(204,255,0,.20) 0%, rgba(204,255,0,.07) 50%, transparent 100%);
  opacity:0; transform:scale(.8);
  transition:opacity var(--t-media) var(--e-ui), transform var(--t-media) var(--e-salida);
  pointer-events:none;
}
/* El halo del grupo entero: se enciende al entrar al menú, no a un enlace.
   Es lo que hace que la barra se sienta viva antes de apuntar a nada. */
.nav-links::before{
  content:''; position:absolute; inset:-10px -6px; z-index:-1; border-radius:18px;
  background:radial-gradient(ellipse at center,
    transparent 0%, rgba(204,255,0,.10) 45%, transparent 80%);
  opacity:0; transition:opacity var(--t-media) var(--e-ui);
  pointer-events:none;
}

@media (hover:hover){
  .nav-links:hover::before{ opacity:1 }
  .nav-links a:hover{ color:var(--texto) }
  .nav-links a:hover::after{ transform:scaleX(1) }
  .nav-links a:hover::before{ opacity:1; transform:scale(1.9) }
  /* El botón del tema y el CTA se encienden igual: si solo se iluminan los
     enlaces, la mitad derecha de la barra queda muerta. */
  .tema-btn:hover{ box-shadow:0 0 0 1px var(--lima-dim), 0 0 22px rgba(204,255,0,.28) }
}
/* Con el teclado tiene que pasar lo mismo que con el mouse. Un efecto que
   solo existe al pasar el puntero deja fuera a quien navega con tabulador. */
.nav-links a:focus-visible::before{ opacity:1; transform:scale(1.9) }

.nav-links a[aria-current="page"]{ color:var(--texto) }
.nav-links a[aria-current="page"]::after{ transform:scaleX(1) }

/* 🔴 En celular no hay hover: el halo no se puede encender nunca y el
   `z-index:-1` sí se aplicaría igual. Se apagan los dos pseudo-elementos
   para no dejar capas invisibles pintando de más en la barra. */
@media (hover:none){
  .nav-links a::before, .nav-links::before{ display:none }
}
@media (prefers-reduced-motion:reduce){
  .nav-links a::before{ transition:opacity var(--t-corta) linear; transform:none }
  .nav-links a:hover::before, .nav-links a:focus-visible::before{ transform:none }
}

.nav-cta{ min-height:40px; padding:0 20px; font-size:var(--fs-small); flex:none }

/* Botón de hamburguesa: dos líneas, no tres. Tres es la convención vieja. */
.nav-abrir{
  display:none; width:44px; height:44px; margin-left:auto;
  background:none; border:0; cursor:pointer; padding:0;
  flex-direction:column; justify-content:center; align-items:flex-end; gap:6px;
}
.nav-abrir span{
  display:block; height:2px; background:var(--texto); border-radius:2px;
  transition:transform var(--t-corta) var(--e-salida), opacity var(--t-micro);
}
.nav-abrir span:nth-child(1){ width:22px }
.nav-abrir span:nth-child(2){ width:15px }
.nav-abrir[aria-expanded="true"] span:nth-child(1){ transform:translateY(4px) rotate(45deg) }
.nav-abrir[aria-expanded="true"] span:nth-child(2){ width:22px; transform:translateY(-4px) rotate(-45deg) }

.nav-movil{
  border-top:1px solid var(--linea); padding:var(--s-5) var(--gutter) var(--s-6);
  display:flex; flex-direction:column; gap:var(--s-2);
  background:rgba(10,10,10,.97);
}
/* 🔴 Sin esto el menú aparece ABIERTO y tapa el hero en celular. Un
   `display:flex` en CSS anula el atributo `hidden` del HTML, porque hidden
   solo aplica `display:none` desde la hoja de estilos del navegador y
   cualquier regla del autor le gana. */
.nav-movil[hidden]{ display:none }
.nav-movil a{
  color:var(--texto); text-decoration:none; font-size:var(--fs-lead);
  font-weight:600; padding:14px 0; border-bottom:1px solid var(--linea);
}
.nav-movil a:last-child{ border:0; margin-top:var(--s-4); justify-content:center }

@media (max-width:900px){
  .nav-links, .nav-cta{ display:none }
  .nav-abrir{ display:flex; margin-left:0 }
  /* Los dos botones juntos a la derecha. Con `margin-left:auto` en ambos
     quedaban uno en cada extremo y el logo perdido en el medio. */
  .tema-btn{ margin-left:auto }
  .nav-caja{ gap:var(--s-3) }
}
@media (min-width:901px){
  .nav-movil{ display:none !important }
}

/* Compensa la barra fija para que el contenido no quede debajo */
main{ padding-top:68px }

/* ── Botón flotante de WhatsApp ─────────────────────────────────────
   El sitio viejo no tenía ninguno, en ninguna de las dos páginas. */
.wa-flota{
  position:fixed; right:20px; bottom:20px; z-index:90;
  width:56px; height:56px; border-radius:50%;
  background:#25D366; display:grid; place-items:center;
  box-shadow:0 6px 24px rgba(0,0,0,.4);
  transition:transform var(--t-corta) var(--e-salida);
}
.wa-flota svg{ width:30px; height:30px; fill:#fff }
@media (hover:hover){ .wa-flota:hover{ transform:scale(1.06) } }
@media (max-width:640px){ .wa-flota{ right:16px; bottom:16px } }

/* ── Pie ────────────────────────────────────────────────────────────*/
.pie{ border-top:1px solid var(--linea); padding-block:var(--s-9) var(--s-7) }
.pie-grid{
  display:grid; gap:var(--s-7);
  grid-template-columns:repeat(auto-fit,minmax(180px,1fr));
}
.pie-marca{ grid-column:span 1 }
.pie-marca img{ width:150px; height:auto; margin-bottom:var(--s-4) }
.pie-marca p{ color:var(--texto-3); font-size:var(--fs-small); line-height:1.6 }
@media (min-width:900px){ .pie-marca{ grid-column:span 2; padding-right:var(--s-8) } }

.pie-col{ display:flex; flex-direction:column; gap:var(--s-3) }
.pie-col .label{ margin-bottom:var(--s-1) }
.pie-col a{
  color:var(--texto-2); text-decoration:none; font-size:var(--fs-small);
  transition:color var(--t-micro) var(--e-ui);
}
@media (hover:hover){ .pie-col a:hover{ color:var(--lima-tinta) } }

.pie-fin{
  margin-top:var(--s-9); padding-top:var(--s-5); border-top:1px solid var(--linea);
  display:flex; flex-wrap:wrap; gap:var(--s-4); justify-content:space-between;
  color:var(--texto-3); font-size:var(--fs-small);
}

/* ── Piezas que se repiten entre páginas ────────────────────────────*/

/* Numeración de sección: el lima como color de interfaz, no de superficie */
.num{
  font-family:'Archivo Black',sans-serif; color:var(--lima-tinta);
  font-size:var(--fs-small); letter-spacing:.08em;
}

.eyebrow{ display:flex; align-items:center; gap:var(--s-3); margin-bottom:var(--s-4) }
.eyebrow::after{ content:''; flex:1; height:1px; background:var(--linea); max-width:80px }

/* Tira de datos duros */
.tira{
  display:flex; flex-wrap:wrap; gap:var(--s-3) var(--s-6);
  margin-top:var(--s-7); padding-top:var(--s-5); border-top:1px solid var(--linea);
  font-size:var(--fs-small); color:var(--texto-2);
}
.tira b{ color:var(--texto); font-weight:600 }

/* ═══════════════════════════════════════════════════════════════════
   PÁGINAS DE SERVICIO — /automatizacion/ y /webs/

   Estas clases vivían dentro del <style> de automatizacion.html. Subidas acá
   porque las dos páginas de servicio comparten el mismo esqueleto: hero de
   dolor → cifras → casos con antes/después → planes → cierre. Duplicar 100
   líneas de CSS por página es lo que hace que dos páginas hermanas se vean
   distintas después del tercer cambio.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Hero de servicio ───────────────────────────────────────────────
   Abre con el DOLOR, no con lo que se vende: nadie busca "automatización",
   busca no seguir copiando pedidos a mano. */
.hero-serv{ padding-block:clamp(56px,9vh,110px) clamp(40px,6vh,72px); position:relative; overflow:hidden }
.hero-serv::before{
  content:''; position:absolute; inset:-30% -20% auto auto; width:min(700px,88vw); aspect-ratio:1;
  background:radial-gradient(circle at 60% 40%, rgba(204,255,0,.09), transparent 62%); pointer-events:none;
}
/* 🔴 Velo bajo el texto. Desde que el sitio tiene el panal de hexágonos con
   la luz paseándose, el párrafo del hero queda por momentos encima del
   brillo y pierde contraste. El velo se apoya en el lado donde vive el
   texto y deja el fondo limpio a la derecha, así que no se lee como una
   banda: se lee como profundidad. */
/* 🔴 Los tres colores salen del MISMO fondo del tema. Antes el primero usaba
   `var(--negro)` y los otros dos iban escritos `rgba(10,10,10,...)` a mano, así
   que en tema claro el velo empezaba en blanco y a los 40% se volvía NEGRO al
   66% sobre una página blanca: la franja gris sucia que se veía en las cuatro
   páginas, con el texto encima ilegible.
   📌 El error es fácil de cometer y difícil de ver: en el tema en que se
   diseñó, un velo negro sobre fondo negro es invisible aunque esté mal escrito. */
.hero-serv::after{
  content:''; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(100deg,
    rgba(var(--fondo-rgb), 1)   0%,
    rgba(var(--fondo-rgb), .66) 40%,
    rgba(var(--fondo-rgb), 0)   72%);
}
/* 🔴 TODO el contenido del hero va sobre el velo, no solo el texto.
   Cuando se escribió la regla de arriba el hero solo tenía `.caja`, así que
   con subir esa bastaba. Después llegó `.hero-doble` — el diagrama del flujo
   y el mockup del sitio — y nadie lo subió: quedó DEBAJO del velo.
   En escritorio no se veía, porque en dos columnas el diagrama cae en el 72%
   derecho, donde el degradado ya es transparente. En el celular las columnas
   se apilan, el diagrama baja al lado negro y se ve apagado.
   📌 La lección: un velo que tapa "el fondo" tiene que ir detrás de TODO el
   contenido. Protegerlo elemento por elemento se rompe con el siguiente que
   se agregue, y se rompe solo en el tamaño de pantalla que no estás mirando. */
.hero-serv > .envoltorio{ position:relative; z-index:2 }
.hero-serv .caja{ position:relative; z-index:2; max-width:900px }
/* `balance` reparte las líneas parejas. Sin él, el titular de /trabajos/
   dejaba la palabra "mismo." sola en la segunda línea, y una línea llena
   seguida de una palabra suelta se lee como un error de maquetación. */
.hero-serv h1{ font-size:clamp(2rem,1.1rem + 3.9vw, 4rem); line-height:1.06;
               letter-spacing:-.015em; text-wrap:balance }
.hero-serv .bajada{ margin-top:var(--s-5); max-width:58ch; font-size:var(--fs-lead); color:var(--texto-2) }

/* El hero ya trae su propio aire abajo. Sumado al padding normal de la
   sección siguiente daban 164px de vacío, y con el panal detrás ese hueco
   dejó de leerse como respiro y pasó a parecer contenido que falta. */
.hero-serv + section{ padding-top:clamp(28px,3.4vw,56px) }

/* ── El costo de no hacerlo ─────────────────────────────────────────
   Va de segunda, antes de decir qué se hace: el visitante tiene que
   reconocerse en el problema antes de escuchar la solución. */
.dolores{ display:grid; gap:var(--s-4); grid-template-columns:1fr }
@media (min-width:700px){ .dolores{ grid-template-columns:repeat(2,1fr) } }
@media (min-width:1060px){ .dolores{ grid-template-columns:repeat(4,1fr) } }
.dolor{
  border:1px solid var(--linea); border-radius:var(--r-2);
  background:var(--negro-elev); position:relative; overflow:hidden;
}
/* Con foto: la imagen ocupa el borde superior completo y el número se
   monta encima, sobre un velo. Acá SÍ va encima, al revés que en las
   tarjetas grandes de la portada, porque es una cifra de tres caracteres
   y no un párrafo: nada queda tapado. */
.dolor-foto{ position:relative; aspect-ratio:16/9; overflow:hidden; background:var(--negro) }
.dolor-foto img{ width:100%; height:100%; object-fit:cover; display:block }
.dolor-foto::after{
  content:''; position:absolute; inset:0;
  background:linear-gradient(to top, rgba(0,0,0,.82) 4%, rgba(0,0,0,.15) 62%);
}
.dolor-foto .horas{ position:absolute; z-index:2; left:var(--s-5); bottom:12px; color:#CCFF00 }
.dolor-cuerpo{ padding:var(--s-5) var(--s-6) var(--s-6) }
.dolor:has(.dolor-foto) > .dolor-cuerpo > p{ margin-top:0 }
.dolor > .horas{ padding:var(--s-6) var(--s-6) 0 }
.dolor > p{ padding:0 var(--s-6) var(--s-6) }
.dolor .horas{
  font-family:'Archivo Black',sans-serif; color:var(--lima-tinta);
  font-size:clamp(30px,3.6vw,44px); line-height:1; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;
}
.dolor .horas small{ font-size:14px; color:var(--texto-3); font-family:'Archivo',sans-serif; font-weight:500 }
.dolor p{ margin-top:var(--s-4); color:var(--texto-2); font-size:var(--fs-small); line-height:1.55 }

/* ── Casos con antes/después ────────────────────────────────────────
   Cada uno tiene que hacer que alguien diga "es justo lo mío". Por eso
   muestran la tarea concreta, no la categoría. */
.casos{ display:grid; gap:var(--s-4); grid-template-columns:1fr }
@media (min-width:820px){ .casos{ grid-template-columns:repeat(2,1fr); gap:var(--s-5) } }

.caso{
  border:1px solid var(--linea); border-radius:var(--r-2); overflow:hidden;
  background:var(--negro-elev); display:flex; flex-direction:column;
  transition:border-color var(--t-corta) var(--e-ui), transform var(--t-corta) var(--e-ui);
}
@media (hover:hover){ .caso:hover{ border-color:rgba(204,255,0,.32); transform:translateY(-4px) } }

.caso-top{ padding:var(--s-6) var(--s-6) 0; display:flex; align-items:flex-start; gap:var(--s-4) }
.caso-ico{
  width:44px; height:44px; flex:none; border-radius:var(--r-2);
  background:var(--lima-ghost); border:1px solid rgba(204,255,0,.24);
  display:grid; place-items:center;
}
.caso-ico svg{ width:22px; height:22px; stroke:var(--lima-tinta); fill:none; stroke-width:1.8;
               stroke-linecap:round; stroke-linejoin:round }
.caso h3{ font-size:var(--fs-h3); line-height:1.2 }
.caso-quien{ margin-top:6px; font-size:12px; color:var(--texto-3); letter-spacing:.04em; text-transform:uppercase }

/* El antes/después es lo que hace la venta: se ve la diferencia sin leer. */
.ad{ margin:var(--s-5) var(--s-6) var(--s-6); display:grid; gap:2px; border-radius:var(--r-2); overflow:hidden }
.ad-fila{ display:flex; align-items:flex-start; gap:12px; padding:14px 16px; font-size:var(--fs-small); line-height:1.5 }
.ad-antes{ background:rgba(255,255,255,.028); color:var(--texto-3) }
.ad-antes b{ color:var(--texto-2); font-weight:600 }
.ad-desp{ background:rgba(204,255,0,.055); color:var(--texto) }
.ad-desp b{ color:var(--lima-tinta); font-weight:700 }
.ad-et{
  flex:none; width:52px; font-size:10px; letter-spacing:.12em; text-transform:uppercase;
  font-weight:700; padding-top:2px;
}
.ad-antes .ad-et{ color:var(--texto-3) }
.ad-desp .ad-et{ color:var(--lima-tinta) }

/* ── Planes ─────────────────────────────────────────────────────────*/
.planes{ display:grid; gap:var(--s-4); grid-template-columns:1fr }
@media (min-width:900px){ .planes{ grid-template-columns:repeat(3,1fr); gap:var(--s-5); align-items:start } }

.plan{
  border:1px solid var(--linea); border-radius:var(--r-2); padding:var(--s-7) var(--s-6);
  background:var(--negro-elev); display:flex; flex-direction:column; height:100%;
  position:relative;
}
/* El del medio destacado: un plan marcado sube el ticket medio. */
.plan.destacado{
  border-color:rgba(204,255,0,.4);
  background:linear-gradient(180deg, rgba(204,255,0,.045), var(--negro-elev) 40%);
}
.plan-cinta{
  position:absolute; top:-1px; right:var(--s-6);
  background:var(--lima); color:#000; font-size:10px; font-weight:800;
  letter-spacing:.12em; text-transform:uppercase; padding:5px 12px;
  border-radius:0 0 var(--r-1) var(--r-1);
}
.plan-nom{ font-size:12px; letter-spacing:.14em; text-transform:uppercase; color:var(--texto-3); font-weight:600 }
.plan-val{
  margin-top:var(--s-3); font-family:'Archivo Black',sans-serif;
  font-size:clamp(30px,3.4vw,40px); line-height:1; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;
}
.plan.destacado .plan-val{ color:var(--lima-tinta) }
.plan-para{ margin-top:var(--s-4); color:var(--texto-2); font-size:var(--fs-small); line-height:1.55; min-height:66px }
.plan ul{ list-style:none; margin:var(--s-5) 0 var(--s-6); padding-top:var(--s-5);
          border-top:1px solid var(--linea); display:grid; gap:11px; flex:1 }
/* 🔴 El texto de un `li` con negrita VA ENVUELTO EN UN <span>. Como el li es
   flex, cada hijo suelto se vuelve un item propio: un `<b>` sin envolver
   queda en su propia columna y el resto de la frase en otra, partida.
   Ya pasó con "Chat con IA" y "Video que avanza con el scroll". */
.plan li{ display:flex; gap:10px; font-size:var(--fs-small); color:var(--texto-2); line-height:1.45 }
.plan li svg{ width:15px; height:15px; flex:none; margin-top:3px; stroke:var(--lima-tinta);
              fill:none; stroke-width:3; stroke-linecap:round; stroke-linejoin:round }
.plan li.no{ color:var(--texto-3) }
.plan li.no svg{ stroke:var(--texto-3); stroke-width:2 }
.plan-mant{ margin-bottom:var(--s-4); font-size:12px; color:var(--texto-3) }
.plan .btn{ width:100% }

/* ── Cierre de página de servicio ───────────────────────────────────*/
.cierre-serv{ border-top:1px solid var(--linea) }
.cierre-caja{ max-width:720px }
.cierre-caja h2{ font-size:clamp(1.8rem,1.1rem + 2.8vw,3rem) }
.cierre-botones{ margin-top:var(--s-6); display:flex; gap:var(--s-3); flex-wrap:wrap }

/* ── Hero con demostración visual ───────────────────────────────────
   El hero de /webs/ era puro texto. Quien entra a comprar una página web
   quiere VER una en los primeros tres segundos, no leer sobre ellas. El
   mockup lleva una captura real, no una foto de banco. */
.hero-doble{ display:grid; gap:var(--s-7); grid-template-columns:1fr; align-items:center }
@media (min-width:980px){
  .hero-doble{ grid-template-columns:1.05fr .95fr; gap:var(--s-8) }
}

/* Marco de navegador. Sin él, una captura de una web dentro de otra web se
   lee como parte del diseño y no como "esto es un sitio". */
.mockup{
  border:1px solid var(--linea-2); border-radius:var(--r-2); overflow:hidden;
  background:#0E0E0E; box-shadow:0 24px 60px rgba(0,0,0,.55);
  transform:perspective(1400px) rotateY(-4deg) rotateX(1.5deg);
}
@media (max-width:979px){ .mockup{ transform:none } }
@media (prefers-reduced-motion:reduce){ .mockup{ transform:none } }

.mockup-barra{
  display:flex; align-items:center; gap:7px;
  padding:11px 14px; border-bottom:1px solid var(--linea); background:#141414;
}
.mockup-barra i{ width:9px; height:9px; border-radius:50%; background:#2E2E2E; flex:none }
.mockup-url{
  margin-left:8px; flex:1; background:#0B0B0B; border-radius:100px;
  padding:5px 12px; font-size:11px; color:var(--texto-3);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
/* La imagen se cambia sola entre los sitios reales. Cada una lleva su
   dirección: el visitante ve que son sitios distintos, no una plantilla. */
/* 🔴 La proporción es la REAL de las capturas: 1424×600. Con 16/10 el
   `cover` recortaba el 36% del ancho y el hero de M2 GYM se leía "NTRENA TU
   RITMO", con el menú cortado. Una captura de web es panorámica; forzarla a
   la caja que uno quiere le come justo el titular. */
.mockup-vista{ position:relative; aspect-ratio:1424/600; background:#0B0B0B }
.mockup-vista img{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:top center;
  opacity:0; transition:opacity 700ms var(--e-ui);
}
.mockup-vista img.activa{ opacity:1 }

/* ── Beneficios en tarjeta ──────────────────────────────────────────
   Lo que GANA el cliente, no lo que el sitio tiene. "Solución en 24 h"
   vende; "atención técnica especializada" no dice nada. */
.benef{ display:grid; gap:var(--s-4); grid-template-columns:1fr }
@media (min-width:640px){ .benef{ grid-template-columns:repeat(2,1fr) } }
@media (min-width:1040px){ .benef{ grid-template-columns:repeat(4,1fr) } }
/* 🔴 Antes: un icono chico en una cajita, el título y el párrafo. Cuatro
   iguales en fila se leen como un formulario, no como cuatro razones, y
   el icono a 21px no aporta nada a esa distancia.
   Ahora cada una abre con un DATO en grande. Un número entra por el ojo
   antes de que empiece la lectura, y es lo que hace que se recorra la
   fila en vez de saltársela. El icono baja a marca de agua del fondo:
   sigue dando color y ya no compite con el dato. */
.ben{
  position:relative; overflow:hidden;
  border:1px solid var(--linea); border-radius:var(--r-2);
  background:var(--negro-elev); padding:var(--s-6);
  transition:border-color var(--t-corta) var(--e-ui), transform var(--t-corta) var(--e-ui);
}
@media (hover:hover){
  .ben:hover{ border-color:rgba(204,255,0,.3); transform:translateY(-4px) }
  .ben:hover .ben-ico{ opacity:.16; rotate:-4deg }
}
/* El icono, grande y apagado, asomando por la esquina. */
.ben-ico{
  position:absolute; top:-14px; right:-14px; width:104px; height:104px;
  opacity:.09; pointer-events:none;
  transition:opacity var(--t-media) var(--e-ui), rotate var(--t-media) var(--e-salida);
}
.ben-ico svg{ width:100%; height:100%; stroke:var(--lima-tinta); fill:none; stroke-width:1.2;
              stroke-linecap:round; stroke-linejoin:round }
:root[data-tema="claro"] .ben-ico{ opacity:.14 }

.ben-dato{
  position:relative; font-family:'Archivo Black',sans-serif; color:var(--lima-tinta);
  font-size:clamp(26px,3vw,34px); line-height:1; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums; margin-bottom:var(--s-4);
}
.ben-dato small{
  display:block; margin-top:7px; font-family:'Archivo',sans-serif; font-weight:600;
  font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--texto-3);
}
.ben h3{ position:relative; font-size:var(--fs-body); font-weight:700; line-height:1.25 }
.ben p{ position:relative; margin-top:10px; color:var(--texto-3); font-size:var(--fs-small); line-height:1.55 }
@media (prefers-reduced-motion:reduce){ .ben-ico{ transition:none } }

/* ── Formulario que termina en WhatsApp ─────────────────────────────
   Tres campos, ni uno más. Y no manda a ningún servidor: arma el mensaje
   y abre el chat. Sin backend que se caiga, sin correo que se pierda, y
   el visitante ve exactamente lo que va a enviar antes de enviarlo. */
.form-wa{
  border:1px solid rgba(204,255,0,.26); border-radius:var(--r-2);
  background:linear-gradient(180deg, rgba(204,255,0,.05), var(--negro-elev) 46%);
  padding:var(--s-7) var(--s-6); max-width:560px;
}
@media (min-width:900px){ .form-wa{ padding:var(--s-8) } }
.campo{ margin-bottom:var(--s-5) }
.campo label{ display:block; font-size:var(--fs-small); color:var(--texto-2); margin-bottom:9px; font-weight:600 }
.campo input, .campo textarea, .campo select{
  width:100%; background:#0B0B0B; color:var(--texto);
  border:1px solid var(--linea-2); border-radius:var(--r-1);
  padding:13px 15px; font:inherit; font-size:var(--fs-small);
  transition:border-color var(--t-micro) var(--e-ui);
}
.campo textarea{ resize:vertical; min-height:88px }
.campo input:focus, .campo textarea:focus, .campo select:focus{
  outline:none; border-color:var(--lima-tinta);
}
.campo input::placeholder, .campo textarea::placeholder{ color:#5A5A5A }
.form-wa .btn{ width:100% }
.form-nota{ margin-top:var(--s-4); font-size:12px; color:var(--texto-3); line-height:1.5; text-align:center }

/* ── Proceso en 3 pasos ─────────────────────────────────────────────
   Tres y no diez: a un negocio chico un proceso de diez pasos le suena a
   burocracia, no a rigor. El número lo pone un contador CSS. */
/* ── Ilustraciones ──────────────────────────────────────────────────
   Van en línea en el HTML y no como <img src="x.svg"> por un motivo
   concreto: un SVG cargado como imagen es un documento aparte y NO ve
   las variables de color de la página, así que en tema claro saldría
   con los colores del oscuro. En línea heredan el tema solas. */
.ilu{
  display:block; width:100%; height:auto; aspect-ratio:320/168;
  border-radius:var(--r-2); background:var(--negro-elev);
  border:1px solid var(--linea); margin-bottom:var(--s-5);
}
/* La misma clase sirve para una foto: mismo marco, misma proporción, así
   una tarjeta con dibujo y una con foto siguen midiendo igual en la fila. */
img.ilu{ object-fit:cover }

/* ── Los tres pasos (en /webs/ y en /automatizacion/) ───────────────
   🔴 ESTE BLOQUE NO EXISTÍA. El HTML de las dos páginas usaba
   `.pasos-3` y `.paso3` desde el primer día y nunca se escribió su CSS,
   así que eran dos `div` normales: los tres artículos se apilaban a ancho
   completo y cada foto salía del tamaño de la pantalla. No se veía como un
   error de estilo, se veía como una página con fotos gigantes.
   📌 Se detecta solo, sin ojo: cruzar las clases del HTML contra las
   definidas en los CSS. Una clase usada y nunca definida no da error en
   ningún lado — el navegador la ignora y la página se ve "casi bien". */
.pasos-3{
  display:grid; gap:var(--s-6);
  grid-template-columns:repeat(3, 1fr);
}

/* El título va SOBRE la foto y el párrafo debajo. Ponerlo todo encima se
   ve bien en una maqueta y se lee mal de verdad: el párrafo de un paso son
   tres líneas y compiten con la imagen. Arriba el titular, que es lo que
   se escanea; abajo el detalle, que se lee. */
.paso3{
  display:grid;
  grid-template-rows:auto auto 1fr auto;
  border:1px solid var(--linea); border-radius:var(--r-2);
  background:var(--negro-elev); overflow:hidden;
}
/* La foto y el h3 comparten la MISMA celda de la grilla: así se superponen
   sin necesidad de un div extra envolviéndolos en las dos páginas. */
.paso3 .ilu{
  grid-area:1/1; margin:0; border:0; border-radius:0;
  aspect-ratio:3/2; width:100%;
}
.paso3 h3{
  grid-area:1/1; align-self:end; z-index:1;
  margin:0; padding:56px var(--s-5) var(--s-4);
  font-size:var(--fs-h4); line-height:1.15; color:#fff;
  /* El degradado vive en el propio título, no en una capa aparte: sube solo
     lo necesario para que las letras se lean y deja ver la foto arriba. */
  background:linear-gradient(transparent, rgba(0,0,0,.55) 42%, rgba(0,0,0,.88));
}
/* El número del paso, marcado sobre la esquina de la foto. */
.pasos-3{ counter-reset:paso3 }
.paso3::before{
  counter-increment:paso3; content:counter(paso3);
  grid-area:1/1; justify-self:start; align-self:start; z-index:1;
  margin:var(--s-4); width:30px; height:30px; border-radius:50%;
  display:grid; place-items:center;
  font-family:'Archivo',sans-serif; font-weight:700; font-size:13px;
  color:#000; background:var(--lima);
  box-shadow:0 2px 10px rgba(0,0,0,.45);
}
.paso3 p{ grid-row:3; padding:var(--s-4) var(--s-5) 0; color:var(--texto-2) }
.paso3 .paso3-tiempo{
  grid-row:4; padding:var(--s-4) var(--s-5) var(--s-5);
  font-size:12px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--lima-dim); font-weight:600;
}

@media (max-width:900px){
  .pasos-3{ grid-template-columns:1fr 1fr }
}
@media (max-width:640px){
  /* En una sola columna la foto se vuelve el elemento más alto de la
     pantalla si se deja en 3:2. Se achata para que la tarjeta entera
     quepa de una mirada. */
  .pasos-3{ grid-template-columns:1fr; gap:var(--s-5) }
  .paso3 .ilu{ aspect-ratio:16/9 }
  .paso3 h3{ padding-top:44px }
}

/* ── Chat del asistente ─────────────────────────────────────────────
   No es una captura de pantalla: es HTML. Una captura se ve borrosa en
   pantallas grandes, no se puede leer con un lector de pantalla y hay
   que rehacerla entera para cambiar una palabra. Esto pesa 0 KB. */
.chat-marco{
  max-width:520px; border:1px solid var(--linea); border-radius:var(--r-2);
  background:var(--negro-elev); overflow:hidden; margin-bottom:var(--s-7);
}
.chat-barra{
  display:flex; align-items:center; gap:11px;
  padding:11px var(--s-5); border-bottom:1px solid var(--linea);
}
.chat-ava{
  width:30px; height:30px; border-radius:50%; flex:none;
  background:linear-gradient(140deg, var(--lima-dim), #24310A);
}
.chat-quien{ display:grid; line-height:1.25 }
.chat-quien b{ font-size:13.5px; font-weight:700 }
.chat-quien span{ font-size:11px; color:var(--lima-dim) }
.chat-hora{ margin-left:auto; font-size:11px; color:var(--texto-3) }

.chat{ list-style:none; padding:var(--s-5); display:grid; gap:9px }
.msg{
  max-width:82%; padding:9px 13px; border-radius:14px;
  font-size:13.5px; line-height:1.45; position:relative;
}
/* Los del cliente a la izquierda y en gris; los del asistente a la
   derecha y en verde, que es como se ve WhatsApp de verdad. Invertirlo
   haría que el lector crea que el negocio es el que pregunta. */
.msg.ellos{ justify-self:start; background:var(--fl-caja); border:1px solid var(--linea-2); border-bottom-left-radius:5px }
.msg.yo{
  justify-self:end; background:var(--lima-ghost); color:var(--texto);
  border:1px solid rgba(204,255,0,.22); border-bottom-right-radius:5px;
}
:root[data-tema="claro"] .msg.yo{ background:#E9FFB0; border-color:rgba(92,122,0,.3) }
.msg-t{ display:block; margin-top:5px; font-size:10.5px; color:var(--texto-3); text-align:right }
.chat-pie{
  border-top:1px solid var(--linea); padding:11px var(--s-5);
  font-size:12px; color:var(--texto-3);
}

/* Banda ancha de foto sobre un grupo de tarjetas. Se recorta a 24:7 a
   propósito: acompaña la sección sin robarle la pantalla a lo que hay
   que leer, que es lo de abajo. */
.reglas-foto{
  border-radius:var(--r-2); overflow:hidden; margin-bottom:var(--s-6);
  aspect-ratio:24/7; background:var(--negro);
}
@media (max-width:700px){ .reglas-foto{ aspect-ratio:16/9 } }
.reglas-foto img{ width:100%; height:100%; object-fit:cover; display:block }
.ilu .z{ fill:var(--lima-ghost) }                       /* superficie */
.ilu .l{ fill:none; stroke:var(--linea-2); stroke-width:2 }   /* trazo apagado */
.ilu .a{ fill:none; stroke:var(--lima-dim); stroke-width:2; stroke-linecap:round }
.ilu .s{ fill:var(--lima-dim) }                         /* macizo de acento */
.ilu .t{ fill:var(--texto-3) }                          /* barritas de texto */
.ilu .p{ fill:none; stroke:var(--lima-dim); stroke-width:2; stroke-dasharray:4 5 }

/* ── Abanico de teléfonos ───────────────────────────────────────────
   La promesa principal es "se ve bien en el celular". Eso no se afirma:
   se muestra. Son capturas reales de los cuatro sitios, tomadas a 390px,
   no maquetas dibujadas.

   Van en abanico y no en fila porque cuatro rectángulos idénticos
   alineados se leen como una tabla de especificaciones. Superpuestos y
   girados se leen como una MANO DE CARTAS: objetos que alguien sostiene,
   y que invitan a pasar el dedo por encima. */
.abanico{
  position:relative; display:flex; justify-content:center; align-items:center;
  min-height:clamp(340px, 44vw, 560px);
  /* El paso y la subida se calculan una vez acá y cada carta los multiplica
     por su distancia al centro. Cambiar la apertura del abanico entero es
     tocar estos dos números. */
  --paso:clamp(84px, 10.5vw, 168px);
  --sube:clamp(8px, 1.4vw, 22px);
}

.ab-carta{
  position:absolute; display:block; text-decoration:none; color:inherit;
  width:clamp(148px, 17.5vw, 244px); aspect-ratio:390/844;
  border-radius:24px; overflow:hidden;
  border:2px solid #2A2A2A; background:#0B0B0B;
  box-shadow:0 26px 60px rgba(0,0,0,.5);
  /* La posición del abanico va en `transform` y el empujón del hover en
     `translate`, que es una propiedad aparte. Se componen en vez de
     pisarse: si el empujón fuera otro transform, borraría el giro. */
  transform:translateX(var(--x)) translateY(var(--y)) rotate(var(--rot)) scale(var(--sc));
  translate:0 0;
  transition:transform 540ms var(--e-salida), translate 540ms var(--e-salida),
             scale 400ms var(--e-salida), box-shadow 400ms var(--e-ui),
             border-color var(--t-corta) var(--e-ui);
}
/* Cuatro cartas: distancias -1, -⅓, +⅓, +1 respecto del centro. */
.ab-carta:nth-child(1){ --rot:-15deg; --x:calc(var(--paso) * -1);      --y:var(--sube);              --sc:.87;  z-index:1 }
.ab-carta:nth-child(2){ --rot:-5deg;  --x:calc(var(--paso) * -0.333);  --y:calc(var(--sube) * .11);  --sc:.965; z-index:2 }
.ab-carta:nth-child(3){ --rot:5deg;   --x:calc(var(--paso) * 0.333);   --y:calc(var(--sube) * .11);  --sc:.965; z-index:2 }
.ab-carta:nth-child(4){ --rot:15deg;  --x:var(--paso);                 --y:var(--sube);              --sc:.87;  z-index:1 }

/* El notch. Sin él, un rectángulo redondeado es una tarjeta cualquiera;
   con él el cerebro ve un teléfono sin que nadie lo explique. */
.ab-carta::before{
  content:''; position:absolute; z-index:3; top:0; left:50%; translate:-50% 0;
  width:34%; height:15px; background:#0B0B0B; border-radius:0 0 11px 11px;
}
.ab-carta img{ width:100%; height:auto; display:block; aspect-ratio:390/844; object-fit:cover }

/* El nombre vive DENTRO de la carta y solo aparece al pasar por encima.
   Debajo no cabe: las cartas se superponen y los pies chocarían. */
.ab-pie{
  position:absolute; z-index:2; inset:auto 0 0 0; padding:34px 14px 14px;
  background:linear-gradient(transparent, rgba(0,0,0,.88) 58%);
  opacity:0; transition:opacity var(--t-corta) var(--e-ui);
}
.ab-pie strong{ display:block; font-size:13px; font-weight:700; color:#fff }
.ab-pie span{ display:block; margin-top:2px; font-size:11px; color:rgba(255,255,255,.62) }

@media (hover:hover){
  .ab-carta:hover{
    translate:0 -26px; scale:1.06; z-index:10;
    border-color:rgba(204,255,0,.5); box-shadow:0 34px 70px rgba(0,0,0,.6);
  }
  .ab-carta:hover .ab-pie{ opacity:1 }
  /* Las que quedan a la derecha de la levantada se corren hacia afuera. */
  .ab-carta:hover ~ .ab-carta{ translate:34px 0 }
  /* Y las de la izquierda, que no tienen selector de hermano anterior,
     se resuelven mirando desde el padre con :has(). */
  .abanico:has(.ab-carta:nth-child(2):hover) > :nth-child(1),
  .abanico:has(.ab-carta:nth-child(3):hover) > :nth-child(-n+2),
  .abanico:has(.ab-carta:nth-child(4):hover) > :nth-child(-n+3){ translate:-34px 0 }
}
/* Sin hover no hay forma de descubrir el nombre: en táctil va siempre. */
@media (hover:none){ .ab-pie{ opacity:1 } }

/* En un celular el abanico no cabe: cuatro cartas giradas dentro de 375px
   se tapan entre ellas y no se ve ninguna entera. Ahí vuelve a ser una
   fila que se desliza con el dedo, que es el gesto que ya conocen. */
@media (max-width:700px){
  .abanico{
    display:flex; justify-content:flex-start; align-items:flex-start;
    min-height:0; overflow-x:auto; gap:var(--s-4);
    padding-block:var(--s-3); scroll-snap-type:x mandatory;
    -webkit-overflow-scrolling:touch;
  }
  .ab-carta{
    position:static; flex:0 0 auto; width:min(58vw, 260px);
    transform:none; translate:0 0; scroll-snap-align:center;
  }
}

@media (prefers-reduced-motion:reduce){
  .ab-carta{ transition:none }
}

/* ── Lista con viñeta de punto ──────────────────────────────────────
   La usan /trabajos/ (los hechos de cada obra) y /webs/ ("cuándo no me
   contrates"). Vivía dentro del <style> de trabajos.html, así que en /webs/
   la misma lista salía sin estilo: viñetas colgando y los items pegados. */
.obra-hechos{ list-style:none; margin-top:var(--s-6); display:grid; gap:11px }
.obra-hechos li{ display:flex; gap:10px; font-size:var(--fs-small); color:var(--texto-2); line-height:1.5 }
.obra-hechos li::before{
  content:''; flex:none; width:7px; height:7px; margin-top:7px; border-radius:50%;
  background:var(--lima-dim);
}

/* ── Integraciones ──────────────────────────────────────────────────
   La primera barrera de una empresa no es el precio: es "¿se conecta con
   lo que ya uso?". Va antes de los planes. */
.integra{
  display:grid; gap:10px;
  grid-template-columns:repeat(auto-fill, minmax(112px, 1fr));
}
.integra li{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:9px; text-align:center;
  border:1px solid var(--linea); border-radius:var(--r-2);
  background:var(--negro-elev); padding:18px 10px 14px;
  font-size:12px; color:var(--texto-3); min-height:88px;
  transition:border-color var(--t-corta) var(--e-ui), color var(--t-corta) var(--e-ui),
             transform var(--t-corta) var(--e-ui);
}
/* Los SVG de Simple Icons son monocromos y vienen en negro. `brightness(0)`
   los aplana a negro puro y `invert(1)` los pasa a blanco: así el mismo
   archivo sirve para los dos temas sin duplicarlo. */
.integra img{
  width:26px; height:26px; display:block;
  filter:brightness(0) invert(1); opacity:.45;
  transition:opacity var(--t-corta) var(--e-ui);
}
:root[data-tema="claro"] .integra img{ filter:brightness(0); opacity:.55 }
@media (hover:hover){
  .integra li:hover{ border-color:rgba(204,255,0,.35); color:var(--texto); transform:translateY(-3px) }
  .integra li:hover img{ opacity:1 }
}
/* Las que no tienen logo disponible van como texto, en la misma caja. */
.integra li.solo-texto{ font-size:13px; color:var(--texto-2); padding-block:22px }

/* ── FAQ ────────────────────────────────────────────────────────────
   <details> nativo: abre sin JS, lo lee un lector de pantalla y Google lo
   indexa. Un acordeón hecho a mano no gana nada acá. */
.faq{ display:grid; gap:2px; max-width:820px }
.faq details{
  border:1px solid var(--linea); border-radius:var(--r-1);
  background:var(--negro-elev); overflow:hidden;
}
.faq details[open]{ border-color:var(--linea-2) }
.faq summary{
  cursor:pointer; list-style:none; padding:18px var(--s-5);
  font-size:var(--fs-body); font-weight:600; color:var(--texto);
  display:flex; align-items:center; justify-content:space-between; gap:var(--s-4);
}
.faq summary::-webkit-details-marker{ display:none }
.faq summary::after{
  content:''; flex:none; width:11px; height:11px;
  border-right:2px solid var(--lima); border-bottom:2px solid var(--lima);
  transform:rotate(45deg) translateY(-3px);
  transition:transform var(--t-corta) var(--e-salida);
}
.faq details[open] summary::after{ transform:rotate(-135deg) translateY(-3px) }
@media (hover:hover){ .faq summary:hover{ color:var(--lima-tinta) } }
.faq .resp{ padding:0 var(--s-5) 20px; color:var(--texto-2); font-size:var(--fs-small); line-height:1.65 }
.faq .resp b{ color:var(--texto); font-weight:600 }

/* ── Comparación: pago único contra suscripción anual ───────────────
   Es el argumento más fuerte que tiene y no estaba escrito en ninguna
   parte. La competencia cobra $159.000 AL AÑO y raciona los cambios. */
.versus{ display:grid; gap:var(--s-4); grid-template-columns:1fr }
@media (min-width:820px){ .versus{ grid-template-columns:1fr 1fr; gap:var(--s-5) } }
.vs-caja{
  border:1px solid var(--linea); border-radius:var(--r-2);
  background:var(--negro-elev); padding:var(--s-6);
}
.vs-caja.mio{
  border-color:rgba(204,255,0,.4);
  background:linear-gradient(180deg, rgba(204,255,0,.05), var(--negro-elev) 42%);
}
.vs-tit{ font-size:12px; letter-spacing:.14em; text-transform:uppercase; color:var(--texto-3); font-weight:600 }
.vs-caja.mio .vs-tit{ color:var(--lima-tinta) }
.vs-caja ul{ list-style:none; margin-top:var(--s-5); display:grid; gap:12px }
.vs-caja li{ display:flex; gap:10px; font-size:var(--fs-small); line-height:1.5; color:var(--texto-3) }
.vs-caja.mio li{ color:var(--texto-2) }
.vs-caja li::before{ content:'—'; flex:none; color:var(--texto-3) }
.vs-caja.mio li::before{ content:'✓'; color:var(--lima-tinta); font-weight:700 }
.vs-caja b{ color:var(--texto); font-weight:600 }

/* ── Micro-prueba social bajo el CTA del hero ───────────────────────*/
.micro-prueba{
  margin-top:var(--s-5); display:flex; flex-wrap:wrap; gap:10px var(--s-5);
  font-size:var(--fs-small); color:var(--texto-3); align-items:center;
}
.micro-prueba b{ color:var(--texto-2); font-weight:600 }
.micro-prueba .viva{
  display:inline-flex; align-items:center; gap:8px; color:var(--texto-2);
}
.micro-prueba .viva::before{
  content:''; width:7px; height:7px; border-radius:50%; background:var(--lima);
  box-shadow:0 0 0 0 rgba(204,255,0,.55); animation:latido 2.4s var(--e-ui) infinite;
}
@keyframes latido{
  0%{ box-shadow:0 0 0 0 rgba(204,255,0,.5) }
  70%{ box-shadow:0 0 0 9px rgba(204,255,0,0) }
  100%{ box-shadow:0 0 0 0 rgba(204,255,0,0) }
}
@media (prefers-reduced-motion:reduce){ .micro-prueba .viva::before{ animation:none } }

/* ── Lienzo de flujo ────────────────────────────────────────────────
   Es la demo del producto, no una decoración: "automatización" no
   significa nada hasta que se ve el trabajo pasando solo.

   🔴 Antes eran cajas HTML que se arrastraban con 172 líneas de JS. Se
   cambió por SVG animado por dos motivos medidos: el arrastre casi nadie
   lo descubría (había que leer el aviso para saber que existía), y el
   lienzo estaba QUIETO hasta que alguien lo tocaba. Ahora corre solo
   desde el primer segundo, que es lo que hay que demostrar. Los puntos
   viajan con <animateMotion>, que es SVG nativo: cero JS y cero
   librerías. */
.flujo-marco{
  border:1px solid var(--linea); border-radius:var(--r-2);
  background:var(--negro-elev); overflow:hidden;
}
.flujo-barra{
  display:flex; align-items:center; gap:var(--s-3);
  padding:13px var(--s-5); border-bottom:1px solid var(--linea);
}
.flujo-punto{
  width:7px; height:7px; border-radius:50%; background:var(--lima);
  box-shadow:0 0 8px rgba(204,255,0,.7);
  animation:latir 2s var(--e-ui) infinite;
}
@keyframes latir{ 0%,100%{ opacity:1 } 50%{ opacity:.18 } }
.flujo-barra .label{ color:var(--texto-2) }
.flujo-pista{
  margin-left:auto; color:var(--texto-3); font-size:11px;
  font-variant-numeric:tabular-nums;
}
/* Un diagrama que se desliza y no avisa que se desliza es un diagrama que
   nadie desliza: se ve el borde cortado y se lee como que está roto. */
.flujo-desliza{ display:none }

/* El lienzo scrollea en su propio contenedor: mide 980px y en un celular
   de 375 no cabe. Nunca hace scrollear la página a lo ancho.

   🔴 Y ESO NO ESTABA PASANDO. `base.css` trae `svg{ max-width:100% }` como
   reset general, y un `max-width` SIEMPRE le gana al `width`. Así que en vez
   de scrollear, el diagrama se encogía de 980px a 375: el texto de 12,5px
   quedaba dibujado a menos de 5px reales. No era un problema de diseño, era
   una regla de reset de tres palabras ganándole a la intención.
   `min-width` es la que sí manda sobre `max-width`, y por eso va acá. */
.flujo-visor{
  overflow-x:auto; overflow-y:hidden; -webkit-overflow-scrolling:touch;
  /* Que el dedo pueda arrastrar el diagrama sin que la página se vaya con él. */
  overscroll-behavior-x:contain;
}
.flujo-svg{ display:block; width:980px; min-width:980px; height:auto }
/* La versión apilada solo existe en el celular. */
.flujo-svg-v{ display:none }

/* Las líneas de conexión y los puntos que viajan por ellas. */
.fl-linea{ fill:none; stroke:var(--lima-dim); stroke-width:1.5; stroke-dasharray:3 5; opacity:.75 }
.fl-punto{ fill:var(--lima-tinta) }

/* Cajas. El relleno no usa var(): dentro de un SVG el degradado de fondo
   del marco no llega, así que cada caja pinta el suyo. */
.fl-caja{ fill:var(--fl-caja); stroke:var(--linea-2); stroke-width:1 }
.fl-caja-agente{ fill:var(--fl-agente); stroke:var(--lima-tinta); stroke-width:1.2 }
.fl-caja-sale{ fill:var(--fl-caja); stroke:var(--linea); stroke-width:1 }

.fl-et{ font-family:'Archivo',sans-serif; font-weight:600; font-size:9.5px;
        letter-spacing:.12em; fill:var(--lima-dim) }
.fl-tit{ font-family:'Archivo',sans-serif; font-weight:700; font-size:12.5px; fill:var(--texto) }
.fl-sub{ font-family:'Archivo',sans-serif; font-weight:400; font-size:10.5px; fill:var(--texto-3) }
.fl-agente-et{ fill:var(--lima-tinta) }

/* Los tres puntitos del nodo que "está pensando". */
.fl-pensando circle{ fill:var(--lima-tinta); animation:pensar 1.2s var(--e-ui) infinite }
.fl-pensando circle:nth-child(2){ animation-delay:.4s }
.fl-pensando circle:nth-child(3){ animation-delay:.8s }
@keyframes pensar{ 0%,100%{ opacity:.15 } 50%{ opacity:1 } }

/* Semáforo de cada salida: verde = ya pasó, ámbar = en curso. */
.fl-ok{ fill:#5FD068 }
.fl-curso{ fill:#E0A62B; animation:pensar 1.9s var(--e-ui) infinite }
.fl-curso.b{ animation-duration:2.3s; animation-delay:.35s }

/* ── El renglón que va contando lo que pasa ─────────────────────────
   Nueve frases apiladas en el mismo hueco; solo se ve una a la vez. Es
   CSS puro: con JS habría que despertar un temporizador en cada visita
   y esto tiene que poder correr en un celular viejo sin costar nada. */
.flujo-log{
  border-top:1px solid var(--linea); padding:11px var(--s-5);
  display:flex; gap:9px; align-items:flex-start;
  height:46px; overflow:hidden;
}
.flujo-log .fl-cursor{ color:var(--lima-tinta); font-weight:700; flex:none; line-height:1.5 }
.flujo-log ul{ list-style:none; position:relative; flex:1; height:100% }
.flujo-log li{
  position:absolute; inset:0; font-size:12px; line-height:1.5; color:var(--texto-2);
  /* `backwards` no es opcional: sin él, una línea con delay de 18 s se
     pinta con su estilo normal hasta que le toca, y las nueve aparecen
     encimadas durante los primeros segundos. */
  opacity:0; animation:renglon 23.4s linear infinite backwards;
}
@keyframes renglon{
  0%     { opacity:0; transform:translateY(6px) }
  1.5%   { opacity:1; transform:none }
  9.6%   { opacity:1; transform:none }
  11.1%  { opacity:0; transform:translateY(-6px) }
  100%   { opacity:0; transform:translateY(-6px) }
}
.flujo-log li:nth-child(1){ animation-delay:0s }
.flujo-log li:nth-child(2){ animation-delay:2.6s }
.flujo-log li:nth-child(3){ animation-delay:5.2s }
.flujo-log li:nth-child(4){ animation-delay:7.8s }
.flujo-log li:nth-child(5){ animation-delay:10.4s }
.flujo-log li:nth-child(6){ animation-delay:13s }
.flujo-log li:nth-child(7){ animation-delay:15.6s }
.flujo-log li:nth-child(8){ animation-delay:18.2s }
.flujo-log li:nth-child(9){ animation-delay:20.8s }

/* ── Los números de abajo ───────────────────────────────────────────*/
.flujo-pie{
  border-top:1px solid var(--linea); padding:12px var(--s-5);
  display:flex; flex-wrap:wrap; gap:var(--s-6) var(--s-7);
}
.flujo-pie div{ min-width:0 }
.flujo-pie dt{
  font-size:9px; letter-spacing:.1em; text-transform:uppercase; color:var(--texto-3);
  margin-bottom:3px;
}
.flujo-pie dd{
  font-size:15px; color:var(--texto-2); font-weight:700;
  font-variant-numeric:tabular-nums;
}
.flujo-pie .der{ margin-left:auto; text-align:right }
.flujo-pie .der dd{ font-size:11px; font-weight:400; color:var(--lima-dim) }

/* ── En el celular ──────────────────────────────────────────────────
   El diagrama se desliza a tamaño completo en vez de encogerse. Se cambia
   "6 pasos · conectado a WhatsApp" por la instrucción de deslizar: ese dato
   ya está en el pie del propio marco, y en 375px lo que hace falta no es más
   información, es saber que ahí se puede arrastrar. */
@media (max-width:700px){
  /* Se cambia el diagrama entero, no se encoge. A 980px de ancho el texto más
     chico cae a 8,5px —que a un brazo de distancia no se lee, se adivina— y a
     tamaño real hay que deslizar tres pantallas para ver seis pasos, con lo
     que se pierde lo único que un diagrama aporta: verlo todo de una vez. */
  .flujo-svg{ display:none }
  .flujo-svg-v{ display:block; width:100%; height:auto }
  /* Ya no hay nada que deslizar: entra completo. */
  .flujo-visor{ overflow:visible; padding:var(--s-4) var(--s-4) var(--s-3) }
  .flujo-desliza{ display:none }
  .flujo-log{ padding-inline:var(--s-4) }
}

/* ── Modo claro ─────────────────────────────────────────────────────
   🔴 El lima puro sobre blanco da 1,18:1 — literalmente invisible, y es la
   regla que el proyecto ya tenía escrita: "lima nunca sobre fondo claro".
   `base.css` redefine `--lima-dim` para claro, pero NO `--lima`, así que
   todo lo que pintaba con lima puro (los puntos que viajan, el que late en
   la barra, los tres del asistente) desaparecía en el tema claro. */
:root[data-tema="claro"] .flujo-punto{
  background:var(--lima-dim); box-shadow:0 0 8px rgba(92,122,0,.45);
}
:root[data-tema="claro"] .fl-punto,
:root[data-tema="claro"] .fl-pensando circle,
:root[data-tema="claro"] .fl-agente-et{ fill:var(--lima-dim) }
:root[data-tema="claro"] .fl-caja-agente{ stroke:var(--lima-dim) }
:root[data-tema="claro"] .flujo-log .fl-cursor{ color:var(--lima-dim) }
/* El semáforo también: #5FD068 sobre blanco da 2,1:1 y el ámbar 2,3:1. */
:root[data-tema="claro"] .fl-ok{ fill:#2E7D34 }
:root[data-tema="claro"] .fl-curso{ fill:#9A6B00 }
:root[data-tema="claro"] .fl-linea{ opacity:1 }

/* 🔴 Quien pidió menos movimiento ve el mismo diagrama, quieto y legible.
   No se esconde: el diagrama ES la explicación. */
@media (prefers-reduced-motion:reduce){
  .flujo-punto, .fl-pensando circle, .fl-curso{ animation:none }
  .fl-pensando circle, .fl-curso{ opacity:1 }
  .flujo-desliza::after{ animation:none }
  .flujo-log{ height:auto }
  .flujo-log li{ position:static; animation:none; opacity:1; margin-bottom:4px }
  .flujo-log li:not(:first-child){ display:none }
}

/* ── Fotos de Matías ────────────────────────────────────────────────
   El sitio no tenía ni una cara en sus cinco páginas, y prometía
   "escribes tú, contesto yo". Un dueño de negocio le compra a una
   persona que puede ver. */

/* Hero de /sobre-mi/: retrato al lado del texto. */
.yo-retrato{
  border-radius:var(--r-2); overflow:hidden; position:relative;
  border:1px solid var(--linea-2); background:var(--negro-elev);
}
.yo-retrato img{ width:100%; height:auto; display:block; aspect-ratio:1122/1402; object-fit:cover }
/* Un degradado desde abajo asienta la foto en la página en vez de dejarla
   flotando como un recorte pegado encima. */
.yo-retrato::after{
  content:''; position:absolute; inset:auto 0 0 0; height:38%;
  background:linear-gradient(transparent, rgba(10,10,10,.5));
  pointer-events:none;
}
:root[data-tema="claro"] .yo-retrato::after{ background:linear-gradient(transparent, rgba(0,0,0,.18)) }

/* Hero del inicio: la foto de fondo, con el texto encima. */
.hero-foto{
  position:absolute; inset:0; z-index:0; overflow:hidden; pointer-events:none;
}
.hero-foto img{
  width:100%; height:100%; object-fit:cover; object-position:70% center; display:block;
  /* La foto está en penumbra y detrás de un velo: sin ayuda queda lavada y
     no se lee ni qué está pasando en la escena. */
  /* 🔴 ACLARAR, no dar contraste. La escena es una persona en penumbra y
     encima lleva un velo oscuro: subirle el contraste hunde los negros y la
     borra del todo — probado, y el hero quedó liso. Lo que la hace visible a
     través del velo es levantar el brillo; el contraste se toca apenas, solo
     para que no quede lechosa. En tema claro es al revés (más abajo). */
  filter:brightness(1.5) contrast(1.06) saturate(1.12);
}
/* 🔴 El velo NO es decoración: sin él el texto cae sobre zonas claras de la
   foto y baja de 4.5:1. Va denso a la izquierda, donde vive el titular, y se
   abre a la derecha para que se vea la escena.
   📌 El titular termina cerca del 55% del ancho, así que del 70% en adelante
   no hay nada que proteger: ahí el velo estaba tapando por costumbre, no por
   necesidad. Se abre de .62→.35 y de .30→.06. */
.hero-foto::after{
  content:''; position:absolute; inset:0;
  background:linear-gradient(90deg, rgba(10,10,10,.95) 0%, rgba(10,10,10,.85) 45%, rgba(10,10,10,.35) 72%, rgba(10,10,10,.06) 100%);
}
/* 🔴 EN TEMA CLARO LA FOTO SE PASA A CLAVE ALTA. No se toca el velo: se
   cambia el RANGO TONAL de la imagen.

   El problema no era la densidad del velo. El texto del hero es NEGRO y la
   foto es una escena en penumbra, así que subir el velo la borraba y bajarlo
   mataba la lectura del titular. Tres intentos moviendo el velo y los tres
   peores que el punto de partida.

   `brightness(1.7) contrast(.62)` comprime la foto hacia arriba: su rango
   pasa a vivir entre 0.26 y 0.78 de luminancia en vez de entre 0.02 y 0.35.
   Contra texto negro eso da 6.26:1 medido —muy sobre el 4.5 de AA— y la foto
   RECUPERA forma, que es lo que faltaba. Antes, con el velo al 88%, vivía
   entre 0.70 y 0.88: no era una foto tenue, era una mancha plana.

   📌 Los números salieron de medir la imagen real en un canvas con el filtro
   y el degradado aplicados, no de ajustar a ojo. Con tres intentos fallidos
   encima, medir salía más barato que seguir probando. */
:root[data-tema="claro"] .hero-foto img{ filter:brightness(1.7) contrast(.62) saturate(1.05) }
:root[data-tema="claro"] .hero-foto::after{
  background:linear-gradient(90deg, rgba(247,248,246,.82) 0%, rgba(247,248,246,.62) 45%, rgba(247,248,246,.3) 74%, rgba(247,248,246,.06) 100%);
}
@media (max-width:860px){
  /* En celular la columna es todo el ancho: el degradado horizontal deja el
     texto sobre la parte clara. Se cambia a vertical.

     🔴 Y el reparto importa más que la densidad. Antes empezaba en .75 y
     terminaba en .98: la foto no se veía en NINGUNA parte, ni siquiera donde
     no estorbaba. Ahora arranca en .30 —el tercio de arriba, donde solo está
     el badge— y cierra denso abajo, que es donde caen el párrafo y los
     botones. Se ve la escena y el texto no pierde ni un punto de contraste. */
  /* 🔴 EL VELO NACE OPACO. La barra de arriba es una franja lisa del color
     del tema, y si la foto empieza a verse pegada a ella el corte se nota
     como una raya: en claro, barra blanca contra un gris sucio. Los primeros
     10% son del color del fondo puro, así que la foto "sale" de la barra en
     vez de chocar con ella. Recién después se abre, en la zona donde está la
     cara, y vuelve a cerrarse abajo para el párrafo y los botones. */
  .hero-foto img{ object-position:60% top; filter:brightness(1.6) contrast(1.04) saturate(1.14) }
  .hero-foto::after{
    background:linear-gradient(180deg,
      rgba(10,10,10,1) 0%, rgba(10,10,10,.42) 16%, rgba(10,10,10,.6) 34%,
      rgba(10,10,10,.9) 62%, rgba(10,10,10,.98) 100%);
  }
  /* Mismo truco de clave alta, y acá importa más: en una columna el texto
     ocupa el hero entero, así que la foto tiene que ser legible POR DEBAJO
     de cada línea. Medido con el degradado real: titular 6.26:1, párrafo
     8.71:1, botones 12.51:1. La primera parada sigue en 1 para que la foto
     salga de la barra de arriba en vez de chocar con ella. */
  :root[data-tema="claro"] .hero-foto img{ filter:brightness(1.7) contrast(.62) saturate(1.05) }
  :root[data-tema="claro"] .hero-foto::after{
    background:linear-gradient(180deg,
      rgba(247,248,246,1) 0%, rgba(247,248,246,.42) 14%, rgba(247,248,246,.5) 38%,
      rgba(247,248,246,.8) 66%, rgba(247,248,246,.92) 100%);
  }
}

/* Botón flotante con su cara en vez del icono genérico.
   Es lo que hace webunica.cl y es la razón por la que se le cree: quien
   duda antes de escribir ve a quién le va a escribir. */
.wa-flota.con-cara{ background:none; overflow:visible }
.wa-flota.con-cara img{
  width:100%; height:100%; border-radius:50%; object-fit:cover;
  border:2px solid var(--lima);
}
/* El icono de WhatsApp baja a una insignia en la esquina: sin él, la foto
   sola no dice que ese botón abre un chat. */
.wa-flota.con-cara .burbuja{
  position:absolute; right:-3px; bottom:-3px;
  width:24px; height:24px; border-radius:50%; background:#25D366;
  display:grid; place-items:center; border:2px solid var(--negro);
}
.wa-flota.con-cara .burbuja svg{ width:13px; height:13px }

/* ── Vitrina con volumen y parallax ─────────────────────────────────
   La lección de Boldium: una captura plana dice "hice una web"; la misma
   captura con perspectiva, sombra y desfase dice "hice un producto". El
   material es idéntico, cambia cómo pesa.

   Todo con transform y opacity, que son las dos únicas propiedades que el
   navegador compone en GPU sin recalcular el layout. */
.vitrina3{
  display:grid; gap:var(--s-5); grid-template-columns:1fr;
}
/* 🔴 Antes cada pieza iba girada en perspectiva y a distinta altura. Con
   tres capturas de web distintas eso no se lee como composición: se lee
   como una fila mal alineada, y encima obliga al ojo a enderezar cada
   imagen antes de mirar el trabajo. Ahora van rectas y a la misma altura,
   dentro de un marco de navegador. El marco hace dos cosas: enmarca la
   captura como lo que es, y deja ver la dirección real del sitio. */
/* 🔴 Eran tres columnas. Al entrar la cuarta pieza, la última quedaba sola
   en una segunda fila y se leía como un error de maquetación. Con 2×2 las
   cuatro pesan igual y, de paso, cada captura pasa de ~380px a ~560px de
   ancho: en una captura de web esa diferencia decide si se entiende de qué
   sitio se trata o si es una mancha de colores. */
@media (min-width:760px){
  .vitrina3{ grid-template-columns:repeat(2,1fr); gap:var(--s-6); align-items:start }
}

.pieza{ display:block; text-decoration:none; color:inherit; position:relative }
.pieza-marco{
  border-radius:12px; overflow:hidden;
  border:1px solid var(--linea-2); background:var(--fl-caja);
  box-shadow:0 18px 44px rgba(0,0,0,.42);
  transition:transform var(--t-media) var(--e-salida), box-shadow var(--t-media) var(--e-salida),
             border-color var(--t-corta) var(--e-ui);
}
/* La barra del navegador con los tres puntos y la dirección. El texto de
   la barra sale del atributo data-url de cada pieza, no de un <span>: así
   no se puede quedar desincronizado con el href. */
.pieza-marco::before{
  content:attr(data-url);
  display:block; padding:9px 12px 9px 58px; position:relative;
  font-size:11px; color:var(--texto-3); background:var(--negro-elev);
  border-bottom:1px solid var(--linea);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
/* Los tres puntos, en un solo pseudo-elemento con tres sombras. */
.pieza-marco::after{
  content:''; position:absolute; top:15px; left:14px;
  width:7px; height:7px; border-radius:50%; background:var(--linea-2);
  box-shadow:13px 0 0 var(--linea-2), 26px 0 0 var(--linea-2);
}
@media (hover:hover){
  .pieza:hover .pieza-marco{
    transform:translateY(-7px);
    box-shadow:0 28px 62px rgba(0,0,0,.55);
    border-color:rgba(204,255,0,.42);
  }
}
@media (prefers-reduced-motion:reduce){ .pieza-marco{ transition:none } }

.pieza-marco img{ width:100%; height:auto; display:block; aspect-ratio:1424/600; object-fit:cover; object-position:top center }

/* Una pieza que en vez de captura lleva la escena corriendo. Misma
   proporción que las capturas para que la fila no se desnivele. */
.pieza-vivo{ position:relative; aspect-ratio:1424/600; background:#050805; overflow:hidden }
.pieza-vivo iframe{
  position:absolute; inset:0; width:100%; height:100%; border:0; display:block;
  /* El dedo y el clic lo atraviesan: la tarjeta entera es un enlace y el
     iframe no debe robárselo. Para interactuar con la escena se abre
     entera, que es lo que dice el texto de la tarjeta. */
  pointer-events:none;
}
.pieza-txt{ margin-top:var(--s-4) }
.pieza-et{ font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--lima-tinta); font-weight:700 }
:root[data-tema="claro"] .pieza-et{ color:#3F5500 }
.pieza-txt h3{ margin-top:6px; font-size:var(--fs-body); font-weight:700 }
.pieza-txt p{ margin-top:6px; color:var(--texto-3); font-size:var(--fs-small); line-height:1.5 }

/* ── Aparición al scroll ────────────────────────────────────────────
   El observer ya existía en sitio.js y no lo usaba nadie. Ahora los
   bloques entran con un desplazamiento corto en vez de estar ahí de golpe.
   16px, no 60: un recorrido largo se siente lento y estorba al que ya
   estaba leyendo. */
/* 🔴 SE ESCONDE SOLO SI EL JS LO AUTORIZA, con la clase .anim en <html>.
   Antes estaba al revés: el CSS ponía opacity:0 siempre y el JS revelaba. Si
   el observer no corría —reduced-motion, script caído, navegador viejo— 15
   bloques quedaban invisibles para siempre y no se notaba, porque el hero se
   veía bien y el resto estaba en blanco. Sin JS ahora todo se ve. */
.anim [data-entra]{ opacity:0; transform:translateY(16px);
                    transition:opacity 620ms var(--e-salida), transform 620ms var(--e-salida) }
.anim [data-entra].visible{ opacity:1; transform:none }
/* Escalonado dentro de una misma fila: 60ms por pieza. */
[data-entra="1"]{ transition-delay:60ms }
[data-entra="2"]{ transition-delay:120ms }
[data-entra="3"]{ transition-delay:180ms }
@media (prefers-reduced-motion:reduce){
  .anim [data-entra]{ opacity:1; transform:none; transition:none }
}

/* ── Cursor ─────────────────────────────────────────────────────────
   El punto va pegado a la mano y el anillo lo persigue con retraso. Lo
   dibuja el JS solo con puntero fino y sin prefers-reduced-motion; acá
   solo está el aspecto. */

.cur-anillo, .cur-punto{
  position:fixed; top:0; left:0; z-index:9999; pointer-events:none;
  border-radius:50%; translate:-100px -100px;
  /* El centrado va en `transform` y la POSICIÓN en `translate`, que son
     propiedades distintas y se componen. Si el JS escribiera transform,
     borraría el -50% y los dos círculos irían corridos media pantalla. */
  transform:translate(-50%,-50%);
  opacity:1; transition:opacity 200ms var(--e-ui);
}
/* 🔴 Los dos llevan un aro oscuro por fuera además del color. Sin él, el
   cursor lima desaparece sobre las capturas claras y sobre el panal
   cuando la luz de fondo pasa por amarillo. Un puntero que se pierde
   media pantalla es peor que no tener puntero propio: el visitante deja
   de saber dónde está haciendo clic. */
.cur-punto{
  width:9px; height:9px; background:var(--lima);
  box-shadow:0 0 0 1.5px rgba(0,0,0,.55), 0 0 10px rgba(204,255,0,.55);
}
.cur-anillo{
  width:34px; height:34px; border:2px solid rgba(204,255,0,.9);
  box-shadow:0 0 0 1px rgba(0,0,0,.45), inset 0 0 0 1px rgba(0,0,0,.35),
             0 0 14px rgba(204,255,0,.22);
  transition:width 260ms var(--e-salida), height 260ms var(--e-salida),
             background-color 260ms var(--e-ui), border-color 200ms var(--e-ui),
             opacity 200ms var(--e-ui);
}
:root[data-tema="claro"] .cur-anillo{ border-color:rgba(92,122,0,.6) }
:root[data-tema="claro"] .cur-punto{ background:#5C7A00 }

/* Sobre algo clicable el anillo crece y se llena apenas. */
.cur-anillo.activo{ width:54px; height:54px; background:rgba(204,255,0,.10); border-color:rgba(204,255,0,.8) }
.cur-anillo.abrir{ width:66px; height:66px }
.cur-anillo.apretado{ width:26px; height:26px }

.cur-fuera .cur-anillo, .cur-fuera .cur-punto{ opacity:0 }

/* El cursor del sistema se esconde solo donde el nuestro lo reemplaza
   bien. En un campo de texto la barrita en I dice dónde va a caer lo que
   escribes, y eso no se toca. */
.cursor-propio, .cursor-propio a, .cursor-propio button,
.cursor-propio [role="button"], .cursor-propio summary{ cursor:none }
.cursor-propio input, .cursor-propio textarea, .cursor-propio select,
.cursor-propio input[type="range"]{ cursor:auto }
.cursor-propio input[type="range"]{ cursor:grab }

/* En pantallas táctiles no se dibuja nada, pero por si acaso: nunca
   esconder el cursor donde no hay reemplazo. */
@media (hover:none), (pointer:coarse), (prefers-reduced-motion:reduce){
  .cur-anillo, .cur-punto{ display:none }
  .cursor-propio, .cursor-propio *{ cursor:auto }
}

/* ── Fondo: panal de hexágonos con luz neón ─────────────────────────
   Dos canvas fijos detrás de todo, montados por fondo.js. El de abajo
   es la luz; el de arriba es el panal opaco que la deja asomar solo por
   las rendijas. El orden de los canvas ES el efecto: invertirlos deja
   una mancha de color encima de una malla y no se parece en nada. */
.fondo-hex{ position:fixed; inset:0; z-index:0; pointer-events:none }
.fondo-hex canvas{ position:absolute; inset:0; width:100%; height:100% }

/* 🔴 ACÁ HABÍA UNA REGLA QUE ROMPIÓ TRES COSAS, Y ERA UN "SEGURO":
       body:has(.fondo-hex) > *:not(.fondo-hex){ position:relative; z-index:1 }
   La idea era subir el contenido por encima del canvas por si aparecía un
   hijo nuevo del body. Lo que hizo fue pisarle el `position` a TODO hijo
   directo: el botón flotante de WhatsApp dejó de flotar y se fue al final
   de la página, y los dos círculos del cursor pasaron de `fixed` a
   `relative` — o sea que desaparecieron de la pantalla mientras el CSS
   seguía escondiendo el cursor del sistema. Quedó sin puntero visible.

   base.css ya sube el contenido con una lista explícita (.nav, main,
   .pie, .rutas, .wa-flota) y eso alcanza. Un selector con `*` no es un
   seguro: es una regla que no sabes a qué le va a pegar. */

/* 🔴 En tema claro NO va. El panal es negro sólido: sobre un sitio claro
   no es una textura, es una pared. Se apaga entero y vuelve el fondo
   normal, que en claro ya funciona. */
:root[data-tema="claro"] .fondo-hex{ display:none }
