/* ═══════════════════════════════════════════════════════════════
   CENTRY — Sistema de diseño
   Tema único (oscuro, deliberado). Sin dependencias.
   Orden: tokens · base · layout · tipografía · componentes · utilidades
   ═══════════════════════════════════════════════════════════════ */

/* ── Fuentes autoalojadas ─────────────────────────────────────── */
/* Plus Jakarta Sans es una fuente VARIABLE (eje wght 200-800). Los tres
   archivos que servía Google eran idénticos byte a byte: uno solo cubre
   todos los pesos y además hace que font-weight:700 sea un 700 real y no
   un 800 redondeado hacia arriba.
   Sin unicode-range: con un único archivo no ahorra nada y desactivaría
   la fuente en silencio ante cualquier carácter futuro fuera del rango. */
@font-face{font-family:'Jakarta';src:url('/fonts/pjs-var.woff2') format('woff2');font-weight:200 800;font-style:normal;font-display:swap}

/* Fallbacks ajustados métricamente: evitan salto de layout (CLS) al cargar */
@font-face{font-family:'Jakarta-fb';src:local('Segoe UI'),local('Helvetica Neue'),local('Arial');size-adjust:109.5%;ascent-override:94.8%;descent-override:20.3%;line-gap-override:0%}

/* ── Tokens ───────────────────────────────────────────────────── */
:root{
  /* Superficies — negro puro, sesgo cálido mínimo en los elevados */
  --bg:#000000;
  --bg-1:#0a0a09;
  --bg-2:#111110;
  --line:#191817;
  --line-2:#302e2b;
  --line-3:#605d57;   /* límites interactivos: 3,2:1 */

  /* Texto — rampa de 5 pasos, ligeramente cálida */
  --fg:#ffffff;
  --fg-2:#c7c4be;
  --fg-3:#918d86;
  --fg-4:#88847d;   /* 5,4:1; era #7d7973 (4,7:1), justo para texto pequeño */

  /* Señal única: blanco puro. Sobre negro, el acento no es un color:
     es el brillo máximo. Todo lo demás vive en la rampa de grises, así
     que un blanco del 100% destaca tanto como destacaría un color y no
     rompe el binomio negro/blanco. */
  --signal:#ffffff;
  --signal-2:#ffffff;

  /* Acento. El sitio era blanco y negro puros a proposito, y sigue
     siendolo casi entero: este coral aparece SOLO en palabras sueltas
     de los titulares, en el filete de las etiquetas y, desde el
     29/09/2026, en los puntos y destellos del diagrama de integraciones
     y el degradado de sus tarjetas (lo que en Visionarius es verde). Es el unico
     color del sitio, y por eso funciona — si estuviera en los botones,
     en los enlaces y en los iconos dejaria de destacar nada.
     Sobre negro da 9,2:1 de contraste, muy por encima de AAA, asi que
     una palabra en coral se lee igual de bien que una en blanco. */
  --acc:#ff8080;
  --signal-bg:rgba(255,255,255,.07);
  --signal-line:rgba(255,255,255,.28);
  /* El error tampoco usa color: se distingue por peso, por un filete a
     la izquierda y por el texto. Nunca dependió del color de todos
     modos — WCAG 1.4.1 prohíbe justo eso. */
  --danger:#ffffff;

  /* Tipografía */
  --f-sans:'Jakarta','Jakarta-fb',system-ui,-apple-system,'Segoe UI',sans-serif;

  --t-display:clamp(2.4rem,5.5vw,4.4rem);
  --t-h1:clamp(2.1rem,4.6vw,3.6rem);
  --t-h2:clamp(1.85rem,3.9vw,3rem);
  --t-h3:clamp(1.18rem,1.9vw,1.5rem);
  --t-h4:1.18rem;
  --t-lead:clamp(1.12rem,.9rem + .9vw,1.3rem);
  --t-body:1.0625rem;
  /* Subidos el 30/09/2026: el texto pequeño costaba de leer. */
  --t-sm:.96rem;
  --t-xs:.875rem;
  --t-label:.78rem;

  /* Espaciado */
  --s1:.25rem; --s2:.5rem;  --s3:.75rem; --s4:1rem;  --s5:1.5rem;
  --s6:2rem;   --s7:2.75rem;--s8:4rem;   --s9:6rem;
  --section-y:clamp(4.6rem,9.5vw,8.5rem);
  --gutter:clamp(1.25rem,4.6vw,3rem);
  --maxw:1140px;
  --measure:64ch;

  /* Movimiento */
  --e-out:cubic-bezier(.16,1,.3,1);
  --e-io:cubic-bezier(.4,0,.2,1);
}

/* ── Base ─────────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{
  -webkit-text-size-adjust:100%;
  scroll-behavior:smooth;
  scroll-padding-top:6.2rem;
  scrollbar-gutter:stable;
  color-scheme:dark;
}
body{
  background:var(--bg);
  color:var(--fg);
  font-family:var(--f-sans);
  font-size:var(--t-body);
  line-height:1.62;
  /* El espacio de Jakarta mide .17em (lo normal es ~.25em): a tamaño de texto pequeño, y con el
     redondeo de Windows, se queda en 2 px y las palabras parecen pegadas
     («Sinalguien»). Los titulares lo recuperan abajo. */
  word-spacing:.08em;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
[hidden]{display:none!important}
img,svg,video{display:block;max-width:100%;height:auto}
button,input,select,textarea{font:inherit;color:inherit}
a{color:inherit}
::selection{background:var(--signal);color:#000}
:focus-visible{outline:2px solid var(--signal);outline-offset:3px;border-radius:1px}
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-track{background:var(--bg)}
::-webkit-scrollbar-thumb{background:var(--line-2)}
::-webkit-scrollbar-thumb:hover{background:var(--fg-4)}

.skip{
  position:absolute;top:-999px;left:var(--s4);z-index:2000;
  background:var(--fg);color:#000;padding:.7rem 1.2rem;
  font-size:var(--t-sm);font-weight:600;text-decoration:none;
}
.skip:focus{top:var(--s4)}

/* ── Layout ───────────────────────────────────────────────────── */
.wrap{max-width:var(--maxw);margin-inline:auto;padding-inline:var(--gutter);width:100%}
.sect{position:relative;padding-block:var(--section-y);border-top:1px solid var(--line)}
.sect--flush{border-top:none}
/* Con GSAP al mando, el filete superior de la sección no está: se
   dibuja de izquierda a derecha cuando la sección llega. El valor por
   defecto de --filete es 1, así que si GSAP no cargara la línea está
   entera desde el primer momento y no se pierde nada. */
.gs .sect{border-top-color:transparent}
.gs .sect::before{
  content:"";position:absolute;left:0;right:0;top:-1px;height:1px;
  background:var(--line);transform:scaleX(var(--filete,1));transform-origin:left;
}
.gs .sect--flush::before{display:none}
.sect--tight{padding-block:clamp(3rem,6vw,5rem)}

/* Retícula estructural del hero.
   Eran cinco líneas, y dos de ellas caían justo sobre los bordes del
   contenido: hacían de paredes. Con el filete de la sección siguiente
   cerrando por abajo, el hero se leía como una caja con el texto
   encajado dentro. Ahora son tres, todas por dentro del texto, y se
   disuelven arriba y abajo con una máscara: nacen y mueren sin cortar
   en seco, así que sugieren una retícula en lugar de cerrar un marco. */
.rule-grid{
  position:absolute;inset:0;pointer-events:none;z-index:0;
  max-width:var(--maxw);margin-inline:auto;padding-inline:var(--gutter);
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 20%,#000 55%,transparent 92%);
  mask-image:linear-gradient(to bottom,transparent 0,#000 20%,#000 55%,transparent 92%);
}
.rule-grid span{position:absolute;top:0;bottom:0;width:1px;background:#1a1918}
.rule-grid span:nth-child(1){left:25%}
.rule-grid span:nth-child(2){left:50%}
.rule-grid span:nth-child(3){left:75%}
@media(max-width:820px){.rule-grid span:nth-child(1),.rule-grid span:nth-child(3){display:none}}
@media(max-width:600px){.rule-grid{display:none}}

/* ── Tipografía ───────────────────────────────────────────────── */
.display,.h1{font-weight:800;letter-spacing:-.032em;line-height:1.07}
.display,.h1,.h2,.h3{text-wrap:balance;word-spacing:normal}
/* El punto de Jakarta tiene ~.137em de margen lateral: a tamaño de titular
   se lee como un espacio. El generador lo envuelve en .tp y aquí se recupera. */
.display .tp,.h1 .tp,.h2 .tp{margin-left:-.12em;margin-right:-.04em}
.display{font-size:var(--t-display)}
.h1{font-size:var(--t-h1)}
.h2{font-size:var(--t-h2);font-weight:800;letter-spacing:-.028em;line-height:1.1}
.h3{font-size:var(--t-h3);font-weight:700;letter-spacing:-.016em;line-height:1.18}
/* Los saltos duros están puestos para escritorio; en móvil vuelven a
   partirse y producen hasta 6 líneas desiguales. */
@media(max-width:700px){.display br,.h1 br,.h2 br{display:none}}
/* Escalón intermedio: .h3 servía a la vez para tarjeta y para paso. */
.step h3{font-size:clamp(1.3rem,1.05rem + .8vw,1.6rem);line-height:1.22}
.lead{font-size:var(--t-lead);line-height:1.62;color:var(--fg-2);max-width:var(--measure)}
.body{font-size:var(--t-body);color:var(--fg-2);max-width:var(--measure)}
.sm{font-size:var(--t-sm);color:var(--fg-3);line-height:1.7}
strong,b{font-weight:700;color:var(--fg)}
/* Palabra destacada de un titular. <em> y no <span>: asi el enfasis
   existe tambien sin hoja de estilos. La cursiva se quita porque
   aqui el enfasis lo da el color. */
em.hi,.hi{color:var(--acc);font-style:normal}
/* El punto final va DENTRO del <em> para que no se quede solo al
   final de una linea (una palabra no se parte; dos elementos
   inline-block si). Pero el punto no se destaca: es puntuacion,
   no palabra, asi que recupera el color del texto. */
.hi .tp{color:var(--fg)}

/* Etiqueta de sección: la señal de latón vive aquí */
.label{
  display:flex;align-items:center;gap:.7rem;
  font-size:var(--t-label);
  letter-spacing:0.15em;font-weight:600;text-transform:uppercase;
  color:var(--fg-3);margin-bottom:var(--s5);
}
.label::before{content:"";width:1.6rem;height:1px;background:var(--acc);flex:none}


/* ── Botones ──────────────────────────────────────────────────── */
.btn{
  display:inline-flex;align-items:center;gap:.6rem;
  padding:.95rem 1.6rem;font-size:var(--t-sm);font-weight:700;
  text-decoration:none;border:1px solid transparent;cursor:pointer;
  transition:background .22s var(--e-io),color .22s var(--e-io),border-color .22s var(--e-io),transform .22s var(--e-out);
  white-space:nowrap;
  /* Sin esto, un .btn que sea <button> de verdad —y no <a>— hereda el
     fondo gris `buttonface` del navegador. Pasaba en "Cambiar mis
     cookies", el unico boton fantasma que es un <button>: texto claro
     sobre gris medio, 3.06:1, por debajo de AA. */
  background:none;font-family:inherit;color:inherit;
}
.btn svg{flex:none;transition:transform .28s var(--e-out)}
/* Iman: el boton se inclina hacia el puntero. Va por `translate` y no
   por `transform` porque el hover ya usa transform, y dos reglas que
   escriben la misma propiedad se anulan la una a la otra. */
.btn,#chat-open{translate:var(--iman-x,0) var(--iman-y,0)}
.btn{transition:background .22s var(--e-io),color .22s var(--e-io),border-color .22s var(--e-io),transform .22s var(--e-out),translate .3s var(--e-out)}
.btn--solid{background:var(--fg);color:#000;box-shadow:inset 0 -3px 0 var(--signal)}
.btn--solid:hover{background:var(--signal-2);transform:translateY(-2px)}
.btn--solid:hover svg{transform:translateX(4px)}
.btn--ghost{border-color:var(--line-3);color:var(--fg-2);font-weight:600;font-size:var(--t-xs);letter-spacing:0.08em;text-transform:uppercase;padding:1rem 1.5rem}
.btn--ghost:hover{border-color:var(--fg-4);color:var(--fg)}
.btn--sm{padding:.6rem 1.15rem;font-size:var(--t-xs)}
.btn--block{width:100%;justify-content:center}
/* Una etiqueta larga no debe desbordar en pantallas estrechas. */
@media(max-width:520px){.btn{white-space:normal;text-align:center}}

/* Enlace de texto con flecha */
.link{
  display:inline-flex;align-items:center;gap:.45rem;
  font-size:var(--t-xs);letter-spacing:0.07em;
  font-weight:600;text-transform:uppercase;color:var(--fg-3);text-decoration:none;
  border-bottom:1px solid var(--line-3);padding-bottom:.35rem;
  transition:color .2s,border-color .2s;
}
.link:hover{color:var(--signal);border-color:var(--signal-line)}
.link svg{transition:transform .25s var(--e-out)}
.link:hover svg{transform:translateX(3px)}

/* Enlace dentro de un parrafo: se subraya solo al pasar por encima,
   creciendo desde la izquierda. */
.en-texto{
  color:var(--fg);text-decoration:none;position:relative;font-weight:700;
}
.en-texto::after{
  content:"";position:absolute;left:0;right:0;bottom:-2px;height:1px;
  background:var(--fg);transform:scaleX(1);transform-origin:left;
  transition:transform .3s var(--e-out);
}
@media(hover:hover){
  .en-texto:hover::after{transform:scaleX(0);transform-origin:right}
}

/* ── Cabecera ─────────────────────────────────────────────────── */
.hdr{
  position:fixed;inset:0 0 auto;z-index:900;
  background:#000;
  border-bottom:1px solid transparent;
  transition:border-color .3s;
}
.hdr.is-stuck{border-bottom-color:var(--line)}
/* Progreso de lectura. Un scaleX sobre un filete de 2px: el JS solo
   escribe --leido, el navegador hace el resto en la GPU. */
.leido{
  position:absolute;left:0;right:0;bottom:-1px;height:2px;
  background:var(--fg);transform-origin:left;
  transform:scaleX(var(--leido,0));
  opacity:0;transition:opacity .3s;pointer-events:none;
}
.hdr.is-stuck .leido{opacity:.55}
.hdr-in{
  max-width:var(--maxw);margin-inline:auto;padding:0 var(--gutter);
  height:5.1rem;display:flex;align-items:center;justify-content:space-between;gap:var(--s5);
}
.brand{
  font-weight:800;font-size:1.55rem;letter-spacing:.26em;text-transform:uppercase;
  text-decoration:none;color:var(--fg);margin-right:-.26em;flex:none;
}
/* En pantalla estrecha compite con el boton del menu. */
@media(max-width:400px){.brand{font-size:1.3rem;letter-spacing:.2em;margin-right:-.2em}}
.nav{display:flex;align-items:center;gap:var(--s5)}
.nav-links{display:flex;align-items:center;gap:.35rem;list-style:none}
.nav-a{
  display:inline-flex;align-items:center;gap:.3rem;
  padding:.5rem .75rem;font-size:var(--t-xs);font-weight:600;
  color:var(--fg-3);text-decoration:none;cursor:pointer;
  transition:color .2s;position:relative;
}
.nav-a:hover,.nav-a[aria-expanded="true"]{color:var(--fg)}
.nav-a[aria-current="page"]{color:var(--fg)}
.nav-a svg{transition:transform .22s}
.nav-a[aria-expanded="true"] svg{transform:rotate(180deg)}

.dd-wrap{position:relative}
.dd{
  position:absolute;top:calc(100% + .7rem);left:50%;
  transform:translateX(-50%) translateY(-8px) scale(.985);transform-origin:top center;
  min-width:320px;background:var(--bg-1);border:1px solid var(--line-2);
  padding:.4rem;opacity:0;visibility:hidden;
  box-shadow:0 18px 44px -12px rgba(0,0,0,.8);
  transition:opacity .22s var(--e-out),transform .28s var(--e-out),visibility 0s linear .28s;
}
/* Puente invisible sobre el hueco de .7rem que separa el boton del panel.
   Sin el, al bajar el raton se perdia el :hover a mitad de camino y el
   panel desaparecia antes de poder pinchar nada. Es exactamente el bug
   de "los desplegables no se pueden pinchar". */
.dd::before{content:"";position:absolute;left:0;right:0;top:-.8rem;height:.8rem}
.dd.is-open{
  opacity:1;visibility:visible;transform:translateX(-50%) translateY(0) scale(1);
  transition:opacity .22s var(--e-out),transform .28s var(--e-out),visibility 0s;
}
/* Las entradas del panel entran escalonadas una vez abierto. */
.dd-a{
  display:block;padding:.75rem .9rem;text-decoration:none;
  transition:background .18s,transform .3s var(--e-out),opacity .3s var(--e-out);
  opacity:0;transform:translateY(-5px);
}
.dd.is-open .dd-a{opacity:1;transform:none;transition-delay:calc(var(--i,0) * 40ms + 40ms)}
.dd.is-open .dd-foot{opacity:1;transform:none;transition-delay:.22s}
.dd-foot{opacity:0;transform:translateY(-5px);transition:opacity .3s var(--e-out),transform .3s var(--e-out)}
.dd-a:hover,.dd-a:focus-visible{background:var(--bg-2)}
.dd-a.is-cur{background:var(--bg-2);box-shadow:inset 2px 0 0 var(--signal)}
.dd-a b{display:block;font-size:var(--t-xs);font-weight:700;color:var(--fg);margin-bottom:.1rem}
.dd-a span{display:block;font-size:var(--t-label);letter-spacing:0.04em;color:var(--fg-4);line-height:1.5}
.dd-foot{border-top:1px solid var(--line);margin-top:.4rem;padding:.7rem .9rem .4rem}

.ham{
  display:none;width:2.75rem;height:2.75rem;background:none;border:1px solid var(--line-3);
  cursor:pointer;align-items:center;justify-content:center;flex-direction:column;gap:5px;flex:none;
}
.ham i{display:block;width:16px;height:1.5px;background:var(--fg);transition:transform .3s var(--e-out),opacity .2s}
.ham[aria-expanded="true"] i:nth-child(1){transform:translateY(6.5px) rotate(45deg)}
.ham[aria-expanded="true"] i:nth-child(2){opacity:0}
.ham[aria-expanded="true"] i:nth-child(3){transform:translateY(-6.5px) rotate(-45deg)}

@media(max-width:1024px){
  .nav-links,.hdr .btn{display:none}
  .ham{display:flex}
}

/* Panel móvil */
.drawer{
  position:fixed;inset:4.6rem 0 0;z-index:890;background:var(--bg);
  transform:translateY(-100%);transition:transform .38s var(--e-out);
  overflow-y:auto;padding:var(--s6) var(--gutter) var(--s8);
  visibility:hidden;
}
.drawer.is-open{transform:translateY(0);visibility:visible}
.drawer-lbl{font-size:var(--t-label);letter-spacing:0.14em;font-weight:600;text-transform:uppercase;color:var(--fg-4);margin:var(--s5) 0 var(--s3)}
.drawer-lbl:first-child{margin-top:0}
.drawer-a{display:block;padding:.85rem 0;border-bottom:1px solid var(--line);text-decoration:none;font-size:1.05rem;font-weight:600}
.drawer-a span{display:block;font-size:var(--t-label);letter-spacing:0.04em;color:var(--fg-4);font-weight:400;margin-top:.15rem}
.drawer .btn{margin-top:var(--s6)}

/* ── Hero ─────────────────────────────────────────────────────── */
.hero{position:relative;padding-top:calc(4.6rem + clamp(3.5rem,8vw,6.5rem));padding-bottom:0;overflow:hidden}
.hero-in{position:relative;z-index:1}
.hero .display{max-width:13.9em;margin-bottom:var(--s5)}
.hero .lead{max-width:52ch}
.hero-cta{display:flex;flex-wrap:wrap;gap:var(--s3) var(--s4);margin-top:var(--s7);align-items:center}

/* Franja de compromisos — reemplaza las métricas inventadas */
.commit{
  position:relative;z-index:1;
  display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line);
  border-block:1px solid var(--line);margin-top:clamp(3rem,6vw,4.5rem);
}
.commit div{background:var(--bg);padding:1.15rem 1.25rem}
.commit dt{
  font-size:var(--t-label);letter-spacing:0.1em;
  font-weight:600;text-transform:uppercase;color:var(--signal);margin-bottom:.4rem;
}
.commit dd{font-size:var(--t-sm);color:var(--fg-2);line-height:1.5;font-weight:600}
@media(max-width:760px){
  .commit{grid-template-columns:1fr}
  .commit div{padding:.95rem 1.1rem}
}

/* Hero de página interior */
.phero{padding-top:calc(4.6rem + clamp(2.25rem,5.2vw,3.75rem));padding-bottom:clamp(2rem,4.5vw,3rem)}
.phero .h1{max-width:13.2em;margin-bottom:var(--s5)}
.crumb{
  display:flex;gap:.5rem;align-items:center;flex-wrap:wrap;
  font-size:var(--t-label);letter-spacing:0.1em;
  font-weight:600;text-transform:uppercase;color:var(--fg-4);margin-bottom:var(--s5);
}
.crumb a{color:var(--fg-3);text-decoration:none;display:inline-block;padding-block:.3rem}
.crumb a:hover{color:var(--signal)}
.crumb svg{opacity:.5}

/* ── Rejilla genérica de celdas con hairline ──────────────────── */
.cells{display:grid;border-top:1px solid var(--line);border-left:1px solid var(--line)}
.cells>*{
  position:relative;background:var(--bg);
  border-right:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:clamp(1.9rem,3.4vw,2.9rem);
  transition:background-color .45s var(--e-io);
}
/* El filete superior recorre la celda ENTERA y sólo al pasar por
   encima. Sustituye al trocito de línea suelto que había fijo en la
   esquina de cada celda: aquello era un adorno que no decía nada y
   dejaba la rejilla sucia. Ahora la línea significa "estás aquí". */
.cells>*::before{
  content:"";position:absolute;left:-1px;right:-1px;top:-1px;height:1px;
  background:var(--signal);transform:scaleX(0);transform-origin:left;
  transition:transform .55s var(--e-out);
}
@media(hover:hover){
  .cells>*:hover{background:var(--bg-1)}
  .cells>*:hover::before{transform:scaleX(1)}
}
.cells--2{grid-template-columns:repeat(2,1fr)}
.cells--3{grid-template-columns:repeat(3,1fr)}
@media(max-width:900px){.cells--3{grid-template-columns:repeat(2,1fr)}}
@media(max-width:620px){.cells--2,.cells--3{grid-template-columns:1fr}}

/* ── Síntomas ("¿Te suena?") ──────────────────────────────────── */
/* Sin ::before propio: el filete lo pone .cells>*, y aparece al pasar
   el puntero. Aquí sólo queda la tipografía. */
.symp{display:flex;flex-direction:column;gap:.5rem}
.symp p{font-size:var(--t-sm);color:var(--fg);line-height:1.55;font-weight:600;max-width:30ch}
.symp small{display:block;font-size:var(--t-xs);color:var(--fg-4);line-height:1.65;font-weight:400;max-width:34ch}

/* ── Proceso ──────────────────────────────────────────────────── */
.proc{display:grid;grid-template-columns:minmax(0,22rem) minmax(0,1fr);gap:clamp(2rem,5vw,4.5rem);align-items:start}
@media(max-width:900px){.proc{grid-template-columns:1fr;gap:var(--s6)}}
/* max-height + scroll: en pantallas bajas, o con el banner de cookies
   ocupando el borde inferior, las ultimas fases quedaban tapadas de
   forma permanente porque el aside es sticky y no se desplaza. */
.proc-aside{
  position:sticky;top:6.5rem;
  max-height:calc(100vh - 8rem - var(--ck-alto,0px));
  overflow-y:auto;overscroll-behavior:contain;
}
@media(max-width:900px){.proc-aside{position:static}}
.phase-nav{list-style:none;margin-top:var(--s6);border-left:1px solid var(--line)}
.phase-nav li{margin-left:-1px;border-left:1px solid transparent;transition:border-color .3s,color .3s}
/* Cada fase es un enlace a su seccion. Antes eran <li> sueltos: parecian
   una navegacion lateral y no respondian al click. El padding vive en el
   <a> para que toda la fila sea zona pulsable. */
.phase-nav a{display:block;padding:.55rem 0 .55rem 1.1rem;text-decoration:none}
.phase-nav a:hover b{color:var(--fg)}
.phase-nav a:hover span{color:var(--fg-3)}
.phase-nav li.is-on{border-left-color:var(--signal)}
.phase-nav b{
  display:block;font-size:var(--t-label);letter-spacing:0.11em;
  font-weight:600;text-transform:uppercase;color:var(--fg-4);transition:color .3s;
}
.phase-nav li.is-on b{color:var(--signal)}
.phase-nav span{font-size:var(--t-xs);color:var(--fg-4);transition:color .3s}
.phase-nav li.is-on span{color:var(--fg-2)}
@media(max-width:900px){.phase-nav{display:none}}

.step{display:grid;grid-template-columns:3.2rem minmax(0,1fr);gap:var(--s4);padding-block:var(--s5);border-top:1px solid var(--line)}
.step:first-child{border-top:none;padding-top:0}
.step-n{
  font-size:var(--t-label);letter-spacing:0.08em;color:var(--signal);
  padding-top:.42rem;font-variant-numeric:tabular-nums;
}
.step h3{margin-bottom:.45rem}
.step p{font-size:var(--t-sm);color:var(--fg-3);line-height:1.7;max-width:56ch}
.step p.step-out,.step-out{
  margin-top:var(--s3);padding-top:var(--s3);border-top:1px dashed var(--line-2);
  font-size:var(--t-label);letter-spacing:0.07em;
  font-weight:600;text-transform:uppercase;color:var(--fg-4);
}
.step-out b{color:var(--fg-2);font-weight:400}
@media(max-width:560px){
  .step{grid-template-columns:1fr;gap:var(--s2)}
  .step-n{padding-top:0}
}

/* ── Territorios ──────────────────────────────────────────────── */
.terr{display:flex;flex-direction:column;gap:var(--s4);text-decoration:none;position:relative;transition:background .25s}
a.terr:hover{background:var(--bg-2)}
.terr-top{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s4)}
.terr-n{font-size:var(--t-label);letter-spacing:0.1em;color:var(--fg-4)}
.terr h3{max-width:16ch}
.terr ul{list-style:none;display:flex;flex-direction:column;gap:.42rem}
.terr li{
  font-size:var(--t-xs);color:var(--fg-3);line-height:1.5;
  padding-left:.95rem;position:relative;
}
.terr li::before{content:"";position:absolute;left:0;top:.62em;width:.4rem;height:1px;background:var(--fg-4)}
a.terr:hover li::before{background:var(--signal)}
.terr .link{margin-top:auto;align-self:flex-start}

/* ── Pilares / diferenciación ─────────────────────────────────── */
.split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(2rem,5vw,4.5rem);align-items:start}
@media(max-width:860px){.split{grid-template-columns:1fr;gap:var(--s6)}}
.pillars{display:flex;flex-direction:column;gap:var(--s5);margin-top:var(--s6)}
.pillar{display:grid;grid-template-columns:1.75rem minmax(0,1fr);gap:var(--s4)}
.pillar-i{color:var(--signal);padding-top:.15rem}
.pillar b{display:block;font-size:var(--t-h4);font-weight:700;margin-bottom:.2rem}
.pillar p{font-size:var(--t-sm);color:var(--fg-3);line-height:1.65}

/* Panel de compromisos verificables */
.panel{border:1px solid var(--line);background:var(--bg-1)}
.panel-row{display:flex;align-items:flex-start;gap:var(--s4);padding:1.15rem 1.35rem;border-bottom:1px solid var(--line)}
.panel-row:last-child{border-bottom:none}
.panel-row svg{color:var(--signal);flex:none;margin-top:.22rem}
/* En el panel de rechazos el acento invertía la lectura: marcaba en
   color de marca justo lo que NO hacemos. */
.panel--neg .panel-row svg{color:var(--fg-3)}
.panel-row b{display:block;font-size:var(--t-sm);font-weight:700;margin-bottom:.15rem}
.panel-row span{display:block;font-size:var(--t-xs);color:var(--fg-4);line-height:1.6}

/* Declaración destacada */
.stmt{
  border-left:2px solid var(--signal);background:var(--signal-bg);
  padding:1.35rem 1.6rem;margin-top:var(--s6);
}
.stmt p{font-size:var(--t-h4);font-weight:700;line-height:1.45;max-width:46ch;color:var(--fg)}
.stmt small{display:block;font-size:var(--t-xs);color:var(--fg-2);margin-top:.5rem;line-height:1.65;font-weight:400;max-width:62ch}

/* ── Agenda de la reunión ─────────────────────────────────────── */
.agenda{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);border:1px solid var(--line)}
.agenda>div{background:var(--bg);padding:1.5rem 1.35rem}
.agenda dt{font-size:var(--t-label);letter-spacing:0.11em;font-weight:600;text-transform:uppercase;color:var(--fg-2);margin-bottom:.65rem}
.agenda dd{font-size:var(--t-sm);color:var(--fg-2);line-height:1.6}
@media(max-width:880px){.agenda{grid-template-columns:repeat(2,1fr)}}
@media(max-width:520px){.agenda{grid-template-columns:1fr}}

/* ── FAQ ──────────────────────────────────────────────────────────
   Sigue siendo <details> nativo: sin JavaScript abre y cierra igual.
   El JS solo anade el deslizamiento de altura, que el elemento nativo
   no sabe hacer, y cierra la pregunta anterior. */
.faq{max-width:46rem}
.faq details{border-bottom:1px solid var(--line);position:relative}
.faq details::before{
  content:"";position:absolute;left:calc(var(--s4) * -1);top:0;bottom:1px;width:1px;
  background:var(--fg);transform:scaleY(0);transform-origin:top;
  transition:transform .42s var(--e-out);
}
.faq details[open]::before{transform:scaleY(1)}
.faq--js details:not(.is-open)::before{transform:scaleY(0)}
@media(max-width:900px){.faq details::before{display:none}}

.faq summary{
  display:flex;align-items:center;justify-content:space-between;gap:var(--s4);
  padding:1.3rem 0;cursor:pointer;list-style:none;
  font-size:var(--t-h4);font-weight:700;
  transition:color .25s var(--e-out),padding-left .35s var(--e-out),transform .14s var(--e-out);
}
.faq summary:active{transform:scale(.995)}
.faq summary::-webkit-details-marker{display:none}
@media(hover:hover){.faq summary:hover{color:var(--fg);padding-left:.4rem}}
.faq summary:focus-visible{outline:2px solid var(--signal);outline-offset:3px}

/* Signo mas que gira hasta convertirse en un menos. Dos filetes, cero
   imagenes, y la rotacion no toca la maquetacion. */
.faq-ic{flex:none;position:relative;width:1rem;height:1rem;transition:transform .45s var(--e-out)}
.faq-ic::before,.faq-ic::after{
  content:"";position:absolute;left:50%;top:50%;width:1rem;height:1.5px;
  background:var(--fg-3);transform:translate(-50%,-50%);
  transition:transform .45s var(--e-out),background-color .25s;
}
.faq-ic::after{transform:translate(-50%,-50%) rotate(90deg)}
.faq details[open] .faq-ic{transform:rotate(180deg)}
.faq details[open] .faq-ic::before,.faq details[open] .faq-ic::after{background:var(--fg)}
.faq details[open] .faq-ic::after{transform:translate(-50%,-50%) rotate(0deg)}
/* Con el acordeon JS instalado manda .is-open y no [open]. El motivo
   es el CIERRE: [open] se quita AL FINAL de la animacion, porque en el
   instante en que se quita el navegador oculta el contenido de golpe.
   Si el CSS se apoyara en [open], como hacia hasta aqui, la salida no
   llegaba a verse nunca. */
.faq--js details:not(.is-open) .faq-ic{transform:none}
.faq--js details:not(.is-open) .faq-ic::before,
.faq--js details:not(.is-open) .faq-ic::after{background:var(--fg-3)}
.faq--js details:not(.is-open) .faq-ic::after{transform:translate(-50%,-50%) rotate(90deg)}

/* El deslizamiento: una rejilla de una fila que pasa de 0fr a 1fr.
   Es la unica forma de animar "hasta la altura del contenido" sin
   medirla con JavaScript en cada fotograma. */
.faq-wrap{display:grid;grid-template-rows:0fr;transition:grid-template-rows .44s var(--e-out)}
.faq details[open] .faq-wrap{grid-template-rows:1fr}
/* Al cerrar, curva simetrica. Con la de apertura —que arranca muy
   rapido— el panel se desplomaba en los primeros 80ms y luego se
   quedaba pegado al cero: medido, a 180ms ya estaba en 0,28px. */
.faq--js details:not(.is-open) .faq-wrap{
  grid-template-rows:0fr;transition-timing-function:var(--e-io);transition-duration:.38s;
}
.faq-wrap > div{overflow:hidden}
.faq-a{
  padding-bottom:1.35rem;font-size:var(--t-sm);color:var(--fg-3);
  line-height:1.75;max-width:60ch;
  opacity:0;transform:translateY(6px);
  transition:opacity .34s var(--e-out) .1s,transform .44s var(--e-out) .1s;
}
.faq details[open] .faq-a{opacity:1;transform:none}
.faq--js details:not(.is-open) .faq-a{
  opacity:0;transform:translateY(6px);
  transition:opacity .2s var(--e-io),transform .3s var(--e-io);
}
.faq-a p+p{margin-top:.7rem}
/* Sin JS la rejilla no se anima pero tampoco estorba: el navegador
   muestra el contenido al abrir y .faq-a debe verse igualmente. */
html:not(.js) .faq-wrap{grid-template-rows:1fr}
html:not(.js) .faq-a{opacity:1;transform:none}

/* ── Banda CTA ────────────────────────────────────────────────── */
.cta{text-align:center}
.cta .h2{max-width:20ch;margin-inline:auto;margin-bottom:var(--s5)}
.cta .lead{margin-inline:auto;text-align:center;max-width:50ch}
.cta-btns{display:flex;flex-wrap:wrap;gap:var(--s4);justify-content:center;margin-top:var(--s7)}
.cta-note{
  font-size:var(--t-label);letter-spacing:0.08em;
  color:var(--fg-4);margin-top:var(--s5);line-height:1.9;
}


/* ── Integraciones ────────────────────────────────────────────── */
.integ{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line);border:1px solid var(--line)}
@media(max-width:860px){.integ{grid-template-columns:repeat(2,1fr)}}
@media(max-width:520px){.integ{grid-template-columns:1fr}}
.integ div{background:var(--bg);padding:1.1rem 1.2rem}
.integ b{display:block;font-size:var(--t-xs);font-weight:700;margin-bottom:.15rem}
.integ span{font-size:var(--t-label);letter-spacing:0.04em;color:var(--fg-4);line-height:1.5}

/* ── La cuenta: calculadora y comparativa ─────────────────────────
   Los números de esta sección NO son de Centry. Los pone quien lee,
   moviendo dos barras. Por eso puede haber cifras grandes en la web
   sin afirmar nada: son su propia aritmética, en directo.

   Es la única pieza interactiva de la web aparte de los formularios,
   así que se lleva el peso visual de la página. */
.calc{display:grid;grid-template-columns:minmax(0,22rem) minmax(0,1fr);gap:var(--s7)}
@media(max-width:940px){.calc{grid-template-columns:1fr;gap:var(--s6)}}

/* Mandos */
.calc-mandos{display:flex;flex-direction:column;gap:var(--s5);align-self:start}
/* Los dos titulos cuentan la cuenta en orden: la pregunta a la
   izquierda, la respuesta a la derecha. Van en blanco y sin
   mayusculas para que no se confundan con las etiquetas. */
.calc-tit{font-size:var(--t-body);font-weight:700;color:var(--fg);line-height:1.35;letter-spacing:-.01em;text-wrap:balance}
.calc-res{display:flex;flex-direction:column;gap:var(--s5);min-width:0}
.calc-m{display:flex;flex-direction:column;gap:.7rem}
.calc-m label{
  font-size:var(--t-xs);letter-spacing:0.07em;
  font-weight:600;text-transform:uppercase;color:var(--fg-3);
}
.calc-m b{color:var(--fg);font-weight:700;font-variant-numeric:tabular-nums}

/* Barra: se dibuja entera a mano porque el control nativo cambia de
   aspecto en cada navegador y aquí tiene que ser el mismo objeto. */
.calc-m input[type="range"]{
  appearance:none;-webkit-appearance:none;
  width:100%;height:2rem;background:none;cursor:pointer;
}
.calc-m input[type="range"]::-webkit-slider-runnable-track{
  height:2px;background:var(--line-2);border-radius:2px;
}
.calc-m input[type="range"]::-moz-range-track{
  height:2px;background:var(--line-2);border-radius:2px;
}
.calc-m input[type="range"]::-webkit-slider-thumb{
  appearance:none;-webkit-appearance:none;
  width:1.1rem;height:1.1rem;margin-top:-.52rem;border-radius:50%;
  background:var(--fg);border:none;
  box-shadow:0 0 0 0 rgba(255,255,255,.14);
  transition:box-shadow .25s var(--e-out),transform .25s var(--e-out);
}
.calc-m input[type="range"]::-moz-range-thumb{
  width:1.1rem;height:1.1rem;border-radius:50%;
  background:var(--fg);border:none;
  box-shadow:0 0 0 0 rgba(255,255,255,.14);
  transition:box-shadow .25s var(--e-out),transform .25s var(--e-out);
}
@media(hover:hover){
  .calc-m input[type="range"]:hover::-webkit-slider-thumb{box-shadow:0 0 0 .5rem rgba(255,255,255,.1)}
  .calc-m input[type="range"]:hover::-moz-range-thumb{box-shadow:0 0 0 .5rem rgba(255,255,255,.1)}
}
.calc-m input[type="range"]:active::-webkit-slider-thumb{transform:scale(.88)}
.calc-m input[type="range"]:active::-moz-range-thumb{transform:scale(.88)}
/* El foco va en el control, no solo en el pulgar: un anillo dibujado
   con box-shadow sobre el pseudo-elemento se ve, pero no lo detecta
   ninguna herramienta ni lo hereda el modo de alto contraste. */
.calc-m input[type="range"]:focus-visible{outline:2px solid var(--signal);outline-offset:4px}
.calc-m input[type="range"]:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 .4rem rgba(255,255,255,.16)}
.calc-m input[type="range"]:focus-visible::-moz-range-thumb{box-shadow:0 0 0 .4rem rgba(255,255,255,.16)}
.calc-m small{font-size:var(--t-xs);color:var(--fg-4);line-height:1.6}

/* Resultados */
.calc-out{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--line)}
@media(max-width:560px){.calc-out{grid-template-columns:1fr}}
.calc-cel{background:var(--bg);padding:var(--s5) var(--s5) 1.4rem}
.calc-cel .n{
  display:block;font-size:clamp(2.6rem,6vw,4.2rem);font-weight:800;
  line-height:1;letter-spacing:-.03em;font-variant-numeric:tabular-nums;
  /* El número no debe reflotar mientras cuenta: el ancho de tabular
     mantiene cada dígito en su sitio y la celda no baila. */
}
.calc-cel .u{
  display:block;margin-top:.55rem;
  font-size:var(--t-xs);letter-spacing:0.07em;
  font-weight:600;text-transform:uppercase;color:var(--fg-3);
}
.calc-nota{
  margin-top:var(--s5);padding-left:1rem;
  box-shadow:inset 2px 0 0 var(--line-3);
  font-size:var(--t-xs);color:var(--fg-4);line-height:1.7;max-width:52ch;
}

/* Comparativa: dos columnas, sin color. La diferencia se lee por el
   signo, por el brillo del texto y por el filete de la izquierda. */
.vs{display:grid;grid-template-columns:repeat(2,1fr);margin-top:var(--s7);
  border:1px solid var(--line)}
.vs-col{background:var(--bg);padding:var(--s5)}
.vs-col+.vs-col{border-left:1px solid var(--line)}
@media(max-width:700px){
  .vs{grid-template-columns:1fr}
  .vs-col+.vs-col{border-left:0;border-top:1px solid var(--line)}
}
.vs-cab{
  font-size:var(--t-xs);letter-spacing:0.08em;
  font-weight:600;text-transform:uppercase;padding-bottom:1rem;margin-bottom:1.1rem;
  border-bottom:1px solid var(--line-2);
}
.vs-col--no .vs-cab{color:var(--fg-4)}
.vs-col--si .vs-cab{color:var(--fg)}
.vs-i{
  display:flex;gap:.85rem;align-items:baseline;
  padding:.72rem 0;font-size:var(--t-sm);line-height:1.6;
}
.vs-i::before{
  flex:none;width:1em;
  /* El símbolo no es adorno: es lo que distingue las dos columnas
     para quien no percibe el contraste de brillo. */
}
.vs-col--no .vs-i{color:var(--fg-4)}
.vs-col--no .vs-i::before{content:"×"}
.vs-col--si .vs-i{color:var(--fg-2)}
.vs-col--si .vs-i::before{content:"✓";color:var(--fg)}

/* Entrada escalonada de las filas, en sentidos opuestos: la columna de
   la izquierda entra desde la izquierda y la de la derecha desde la
   derecha. Se lee como dos cosas que se enfrentan. */
@media(prefers-reduced-motion:no-preference){
  .js [data-rv] .vs-col--no .vs-i{opacity:0;transform:translateX(-10px)}
  .js [data-rv] .vs-col--si .vs-i{opacity:0;transform:translateX(10px)}
  .js [data-rv].rv-in .vs-i{
    opacity:1;transform:none;
    transition:opacity .5s var(--e-out),transform .55s var(--e-out);
    transition-delay:calc(var(--i,0) * 65ms + .1s);
  }
}

/* ── Criterios (¿esto se puede automatizar?) ──────────────────── */
.crit{display:grid;grid-template-columns:repeat(3,1fr);
  border-top:1px solid var(--line);border-left:1px solid var(--line)}
@media(max-width:860px){.crit{grid-template-columns:1fr}}
.crit-c{
  position:relative;background:var(--bg);padding:var(--s5);
  border-right:1px solid var(--line);border-bottom:1px solid var(--line);
  transition:background-color .45s var(--e-io);
}
.crit-c::before{
  content:"";position:absolute;left:-1px;right:-1px;top:-1px;height:1px;
  background:var(--signal);transform:scaleX(0);transform-origin:left;
  transition:transform .55s var(--e-out);
}
@media(hover:hover){
  .crit-c:hover{background:var(--bg-1)}
  .crit-c:hover::before{transform:scaleX(1)}
}

/* El filete de cada etiqueta se dibuja al entrar la seccion. Son 1,6rem
   de linea: cuesta un scaleX y se nota en todas las secciones. */
@media(prefers-reduced-motion:no-preference){
  .js [data-rv].label::before,.js [data-rv].label::after{
    transform:scaleX(0);transform-origin:left;
    transition:transform .6s var(--e-out) .1s;
  }
  .js [data-rv].label.rv-in::before,.js [data-rv].label.rv-in::after{transform:scaleX(1)}
}

/* La celda responde al puntero: el numero se aclara y sube un pelo. */
.calc-cel{transition:background-color .3s var(--e-io)}
.calc-cel .n{transition:transform .35s var(--e-out)}
@media(hover:hover){
  .calc-cel:hover{background:var(--bg-1)}
  .calc-cel:hover .n{transform:translateY(-2px)}
}
.crit-c .q{
  font-size:var(--t-xs);letter-spacing:0.06em;
  color:var(--fg-4);display:block;margin-bottom:.9rem;
}
.crit-c h3{font-size:var(--t-h4);font-weight:700;line-height:1.35;margin-bottom:.6rem}
.crit-c p{font-size:var(--t-sm);color:var(--fg-3);line-height:1.7}

/* ── Agenda ───────────────────────────────────────────
   La pantalla de reserva. No hay ni un color ni un tamaño nuevos:
   todo sale de los tokens de arriba.

   Los dias NO se pintan en una rejilla de mes. La API solo ofrece los
   proximos catorce dias, asi que un mes entero serian tres cuartos de
   casillas muertas y dos flechas que no llevan a ninguna parte. Se
   enseña lo que hay. */
.ag-cols{
  display:grid;grid-template-columns:minmax(0,21rem) minmax(0,1fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:start;
}
@media(min-width:941px){.ag-info{position:sticky;top:7rem}}
@media(max-width:940px){.ag-cols{grid-template-columns:1fr;gap:var(--s7)}}

.ag-info h1,.ag-info h2{margin:.6rem 0 var(--s5)}
.ag-datos{
  display:flex;flex-direction:column;gap:.9rem;
  padding-top:var(--s5);margin-top:var(--s5);border-top:1px solid var(--line);
}
.ag-dato{display:flex;gap:.7rem;align-items:flex-start;font-size:var(--t-sm);color:var(--fg-2)}
.ag-dato svg{flex:none;margin-top:.2rem;color:var(--fg-4)}
.ag-nota{
  margin-top:var(--s5);padding-left:1rem;box-shadow:inset 2px 0 0 var(--line-3);
  font-size:var(--t-xs);color:var(--fg-4);line-height:1.7;
}

/* Tres pasos. El numero no es adorno: es una secuencia de verdad y
   dice por donde vas. */
.ag-pasos{display:flex;gap:var(--s5);flex-wrap:wrap;margin-bottom:var(--s6)}
.ag-paso{
  display:flex;align-items:center;gap:.5rem;
  font-size:var(--t-label);letter-spacing:.07em;text-transform:uppercase;
  font-weight:600;color:var(--fg-4);
}
.ag-paso b{
  display:grid;place-items:center;width:1.5rem;height:1.5rem;flex:none;
  border:1px solid var(--line-2);font-size:var(--t-label);font-weight:700;
}
.ag-paso[aria-current="step"]{color:var(--fg)}
.ag-paso[aria-current="step"] b{border-color:var(--fg);background:var(--fg);color:#000}
.ag-paso[data-hecho="si"]{color:var(--fg-3)}
.ag-paso[data-hecho="si"] b{border-color:var(--line-3);color:var(--fg-3)}

.ag-demo{
  margin-bottom:var(--s4);padding:.7rem .9rem;
  border-left:2px solid var(--signal-line);background:var(--signal-bg);
  font-size:var(--t-xs);color:var(--fg-2);
}
.ag-caja{border:1px solid var(--line);background:var(--bg-1)}
.ag-bloque{padding:var(--s5)}
.ag-bloque + .ag-bloque{border-top:1px solid var(--line)}
.ag-cab-mini{
  font-size:var(--t-label);letter-spacing:.07em;text-transform:uppercase;
  font-weight:600;color:var(--fg-3);margin-bottom:var(--s4);
}
.ag-cab-mini b{color:var(--fg);font-weight:600}

/* Dias: una tarjeta por dia con hueco. */
.ag-dias{display:grid;grid-template-columns:repeat(auto-fill,minmax(5rem,1fr));gap:.5rem}
.ag-dia{
  display:flex;flex-direction:column;align-items:center;gap:.15rem;
  padding:.7rem .4rem;background:none;border:1px solid var(--line-2);
  color:var(--fg-2);font:inherit;cursor:pointer;
  transition:border-color .2s,background .2s,color .2s;
}
.ag-dia:hover{border-color:var(--fg);color:var(--fg)}
.ag-dia:focus-visible{outline:2px solid var(--signal);outline-offset:2px}
.ag-dia-sem,.ag-dia-mes{
  font-size:var(--t-label);letter-spacing:.06em;text-transform:uppercase;font-weight:600;
  color:var(--fg-4);
}
.ag-dia-num{font-size:1.35rem;font-weight:800;line-height:1;color:var(--fg);font-variant-numeric:tabular-nums}
.ag-dia[aria-pressed="true"]{background:var(--fg);border-color:var(--fg)}
.ag-dia[aria-pressed="true"] .ag-dia-num{color:#000}
.ag-dia[aria-pressed="true"] .ag-dia-sem,.ag-dia[aria-pressed="true"] .ag-dia-mes{color:#000;opacity:.6}

/* Horas */
.ag-horas{display:grid;grid-template-columns:repeat(auto-fill,minmax(6.5rem,1fr));gap:.5rem}
.ag-hora{
  padding:.75rem .5rem;background:none;border:1px solid var(--line-2);color:var(--fg);
  font:inherit;font-size:var(--t-sm);font-variant-numeric:tabular-nums;cursor:pointer;
  transition:border-color .2s,background .2s,color .2s;
}
.ag-hora:hover{border-color:var(--fg)}
.ag-hora:focus-visible{outline:2px solid var(--signal);outline-offset:2px}
.ag-hora[aria-pressed="true"]{background:var(--fg);color:#000;border-color:var(--fg);font-weight:700}
.ag-vacio{font-size:var(--t-sm);color:var(--fg-4);line-height:1.75}
.ag-aviso{margin-top:var(--s4)}

/* Datos y confirmacion */
.ag-form{border-top:1px solid var(--line);padding:var(--s5);display:none}
.ag-form.on{display:block}
.ag-resumen{
  display:flex;align-items:center;justify-content:space-between;gap:var(--s4);
  flex-wrap:wrap;padding:var(--s4);margin-bottom:var(--s5);
  background:var(--signal-bg);border-left:2px solid var(--signal-line);
}
.ag-resumen b{font-size:var(--t-body);font-weight:700}
.ag-resumen b::first-letter{text-transform:uppercase}
.ag-resumen span{display:block;font-size:var(--t-xs);color:var(--fg-3);margin-top:.15rem}
.ag-cambiar{
  background:none;border:none;color:var(--fg-3);font:inherit;font-size:var(--t-xs);
  text-decoration:underline;text-underline-offset:3px;cursor:pointer;padding:.4rem;
}
.ag-cambiar:hover{color:var(--fg)}
.ag-campos{display:flex;flex-direction:column;gap:var(--s5)}
.ag-listo{padding:clamp(2rem,5vw,3.5rem) var(--s5);text-align:center;display:none}
/* Se le da el foco al confirmar para que un lector de pantalla lea el
   mensaje. Ese foco es programatico, no lo ha pedido nadie con el
   teclado, asi que no lleva anillo: sale un recuadro blanco enorme
   alrededor de la caja y parece un fallo. */
.ag-listo:focus{outline:none}
.ag-listo.on{display:block}
.ag-listo p{font-size:var(--t-sm);color:var(--fg-2);line-height:1.75;max-width:46ch;margin-inline:auto}
.ag-tick{
  width:3rem;height:3rem;margin:0 auto var(--s5);display:grid;place-items:center;
  border:1px solid var(--signal-line);background:var(--signal-bg);
}

/* ── Formularios ──────────────────────────────────────────────── */
.form{display:flex;flex-direction:column;gap:var(--s4)}
.form-row{display:grid;grid-template-columns:1fr 1fr;gap:var(--s4)}
@media(max-width:620px){.form-row{grid-template-columns:1fr}}
.field{display:flex;flex-direction:column;gap:.45rem}
.field label{font-size:var(--t-xs);letter-spacing:0.07em;font-weight:600;text-transform:uppercase;color:var(--fg-2)}
.field label .opt{color:var(--fg-4);letter-spacing:.08em}
/* Ayuda bajo un campo: explica por que se pide, no como rellenarlo. */
.field .hint{font-size:var(--t-xs);color:var(--fg-4);line-height:1.55;margin-top:-.1rem}
.field input,.field select,.field textarea{
  background:var(--bg-1);border:1px solid var(--line-3);color:var(--fg);
  padding:.8rem .95rem;font-size:var(--t-sm);width:100%;
  transition:border-color .2s,background .2s;
}
.field textarea{resize:vertical;min-height:7.5rem;line-height:1.6}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--signal);background:var(--bg-2)}
/* El cambio de borde de 1px no basta como indicador de foco: con teclado
   hace falta algo que se vea. Antes habia aqui un outline:none que ganaba
   por especificidad al :focus-visible global. */
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{
  outline:2px solid var(--signal);outline-offset:2px;
}
.field input::placeholder,.field textarea::placeholder{color:var(--fg-4)}
.field select{appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--fg-4) 50%),linear-gradient(135deg,var(--fg-4) 50%,transparent 50%);background-position:calc(100% - 18px) 55%,calc(100% - 12px) 55%;background-size:6px 6px;background-repeat:no-repeat}
/* Prefijo + número de WhatsApp. El prefijo es un <select> nativo: en el
   móvil abre la rueda del sistema, que es lo que la gente conoce. Mide
   lo que su opción más larga ("US/CA +1"), por eso las opciones van con
   código de país y no con el nombre. */
.tel{display:flex;gap:.5rem}
.field .tel-pref{flex:none;width:auto;padding-right:2.2rem}
.tel input{flex:1 1 auto;min-width:0}
/* Sin color: el error se reconoce por el simbolo, el peso y el filete.
   Nunca debio depender del color (WCAG 1.4.1), asi que no se pierde nada. */
.err{
  font-family:var(--f-sans);font-size:var(--t-xs);font-weight:700;
  color:var(--fg);display:none;padding-left:.6rem;
  box-shadow:inset 2px 0 0 var(--fg);
}
.err.on{display:flex;gap:.4rem;align-items:baseline}
.err.on::before{content:"!";flex:none}
.field input[aria-invalid="true"],.field textarea[aria-invalid="true"]{
  border-color:var(--fg);box-shadow:inset 0 -2px 0 var(--fg);
}
/* Caja de Turnstile. Casi siempre está vacía a la vista (solo pinta
   una casilla si Cloudflare duda): sin caja propia, no deja un hueco
   de más en la columna del formulario. */
.ts{display:contents}
.check{display:flex;gap:.7rem;align-items:flex-start}
.check input{width:1.05rem;height:1.05rem;margin-top:.22rem;flex:none;accent-color:var(--signal)}
.check label{font-family:var(--f-sans);font-size:var(--t-xs);letter-spacing:0;text-transform:none;color:var(--fg-3);line-height:1.6}
.check a{color:var(--fg-2)}
.ok{
  display:none;border:1px solid var(--signal-line);background:var(--signal-bg);
  padding:1.1rem 1.3rem;font-size:var(--t-sm);color:var(--fg-2);
}
.ok.on{display:block}
.ok--err{border-color:var(--line-3);background:rgba(255,255,255,.05);
  box-shadow:inset 3px 0 0 var(--fg)}

/* ── Pie ──────────────────────────────────────────────────────── */
.ftr{border-top:1px solid var(--line)}
body.ck-open{padding-bottom:var(--ck-alto,0px)}
/* El nombre a todo el ancho, como cierre. Va FUERA de .wrap para que
   pueda llegar a los bordes, y el tamano es en vw para que llene la
   pantalla sea cual sea: 6 letras de Jakarta 800 con este espaciado
   miden unos 4,6em, asi que 21vw las lleva de lado a lado.
   overflow:hidden es la red: si una fuente de reserva mide distinto,
   lo que sobre se recorta en lugar de abrir scroll horizontal.
   El degradado hace que la palabra se apague hacia abajo: se lee como
   un cierre y no como un titular mas. */
.ftr-mark{
  overflow:hidden;line-height:.84;
  padding-top:clamp(.5rem,1.5vw,1.5rem);
  padding-bottom:clamp(1.2rem,3vw,2.6rem);
  font-size:23.2vw;font-weight:800;letter-spacing:.015em;
  text-transform:uppercase;text-align:center;user-select:none;
  color:rgba(255,255,255,.16);
  background:linear-gradient(180deg,
              rgba(255,255,255,.30) 0%,
              rgba(255,255,255,.13) 38%,
              rgba(255,255,255,.04) 66%,
              rgba(255,255,255,0)   88%);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;
}
/* Un halo tenue por encima, para que la palabra no salga de la nada.
   Es el unico adorno del pie. */
.ftr-mark-halo{
  height:clamp(3rem,6vw,5.5rem);margin-bottom:-1.5rem;pointer-events:none;
  background:radial-gradient(58% 100% at 50% 100%,rgba(255,255,255,.05),transparent 72%);
}
@media(max-width:520px){.ftr-mark{font-size:22.6vw}}

.ftr-bar{
  padding-block:1.25rem;
  display:flex;flex-wrap:wrap;gap:var(--s3) var(--s5);align-items:center;justify-content:space-between;
}
.ftr-bar p,.ftr-bar a{font-size:var(--t-label);letter-spacing:0.07em;color:var(--fg-4);text-decoration:none}
.ftr-bar a{display:inline-block;padding-block:.4rem}
.ftr-bar a:hover{color:var(--fg-3)}
.ftr-bar nav{display:flex;flex-wrap:wrap;gap:var(--s4)}
.ftr-nav a{color:var(--fg-3)}
.ftr-nav a:hover{color:var(--fg)}
@media(max-width:760px){.ftr-bar{flex-direction:column;align-items:flex-start;gap:var(--s3)}}

/* ── Botón del asistente ──────────────────────────────────────── */
#chat-open{
  position:fixed;right:1.25rem;bottom:1.25rem;z-index:930;
  display:inline-flex;align-items:center;gap:.55rem;
  background:var(--bg-1);color:var(--fg-2);border:1px solid var(--line-3);
  padding:.7rem 1.05rem;cursor:pointer;
  font-size:var(--t-label);letter-spacing:0.08em;
  font-weight:600;text-transform:uppercase;
  transition:border-color .22s,color .22s,transform .22s var(--e-out),translate .35s var(--e-out);
}
#chat-open:hover{border-color:var(--signal);color:var(--fg);transform:translateY(-2px)}
#chat-open svg{color:var(--signal);flex:none}
#chat-open[aria-busy="true"]{opacity:.6;cursor:progress}
/* Mientras el banner de cookies está abierto ocupa todo el borde
   inferior y dejaba el botón del asistente inalcanzable. */
body.ck-open #chat-open{opacity:0;pointer-events:none;transform:translateY(8px)}
/* Con el pie a la vista, el boton flotante se aparta: entre ~600 y
   ~1200px caia justo encima de los enlaces de Privacidad y Cookies. */
body.ftr-a-la-vista #chat-open{opacity:0;pointer-events:none;transform:translateY(8px)}
@media(max-width:520px){
  #chat-open{right:.75rem;bottom:.75rem;padding:.65rem .8rem}
  #chat-open span{display:none}
}

/* ── Banner de cookies y panel del asistente ──────────────────────
   Antes los inyectaban boot.js y chat.js como <style> al arrancar.
   Viven aquí para que la CSP pueda prohibir cualquier hoja <style>
   insertada en la página (style-src-elem 'self'): si algún día se
   colara HTML, no podría traer su propio CSS. Mismas reglas que antes. */
#ck{position:fixed;left:0;right:0;bottom:0;z-index:950;background:#0a0a09;
  border-top:1px solid #302e2b;padding:1.1rem var(--gutter,1.5rem);
  transform:translateY(110%);transition:transform .38s cubic-bezier(.16,1,.3,1)}
#ck.on{transform:translateY(0)}
#ck .in{max-width:1140px;margin-inline:auto;display:flex;gap:1.25rem;
  align-items:center;justify-content:space-between;flex-wrap:wrap}
#ck p{margin:0;font-size:.9rem;line-height:1.6;color:#c7c4be;max-width:60ch}
#ck a{color:#fff}
#ck .btns{display:flex;gap:.6rem;flex-wrap:wrap}
#ck button{font:inherit;font-size:.84rem;font-weight:700;padding:.6rem 1.2rem;
  cursor:pointer;border:1px solid #302e2b;background:none;color:#c7c4be;white-space:nowrap}
#ck button:hover{border-color:#63605b;color:#fff}
#ck button.ck-yes{background:#fff;color:#000;border-color:#fff}
#ck button.ck-yes:hover{background:#e6e6e6;border-color:#e6e6e6}
@media(max-width:620px){#ck .in{flex-direction:column;align-items:stretch}#ck .btns button{flex:1}}

#chat{position:fixed;right:1.25rem;bottom:5.2rem;z-index:940;
  width:min(370px,calc(100vw - 2.5rem));height:min(520px,calc(100vh - 8rem));
  background:#000;border:1px solid #302e2b;display:flex;flex-direction:column;
  opacity:0;transform:translateY(10px);pointer-events:none;
  transition:opacity .25s,transform .25s cubic-bezier(.16,1,.3,1);
  box-shadow:0 18px 50px rgba(0,0,0,.6)}
#chat.on{opacity:1;transform:none;pointer-events:auto}
#chat header{padding:.9rem 1rem;border-bottom:1px solid #1d1c1a;display:flex;
  align-items:center;justify-content:space-between;gap:1rem;flex:none}
#chat header b{font-size:.8rem;font-weight:800;letter-spacing:.15em;text-transform:uppercase}
#chat header span{display:block;font-size:.66rem;font-weight:600;
  letter-spacing:.07em;text-transform:uppercase;color:#fff;margin-top:.15rem}
#chat header button{background:none;border:none;color:#918d86;cursor:pointer;
  font-size:1.3rem;line-height:1;padding:.2rem .4rem}
#chat header button:hover{color:#fff}
#chat .log{flex:1;overflow-y:auto;padding:1rem;display:flex;flex-direction:column;gap:.7rem}
#chat .m{max-width:86%;padding:.6rem .85rem;font-size:.92rem;line-height:1.6;white-space:pre-wrap}
#chat .m.u{align-self:flex-end;background:#fff;color:#000}
#chat .m.a{align-self:flex-start;background:#111110;border:1px solid #1d1c1a;color:#c7c4be}
#chat .m a{color:inherit;text-decoration:underline;text-underline-offset:2px;overflow-wrap:anywhere}
#chat .m.u a{color:#000}
#chat .m.s{align-self:center;font-size:.78rem;color:#88847d;text-align:center;max-width:100%}
#chat form{display:flex;gap:.5rem;padding:.8rem;border-top:1px solid #1d1c1a;flex:none}
#chat textarea{flex:1;background:#0a0a09;border:1px solid #302e2b;color:#fff;
  padding:.55rem .7rem;font:inherit;font-size:.92rem;resize:none;max-height:5rem;min-height:2.4rem}
#chat textarea:focus{outline:none;border-color:#fff}
#chat form button{background:#fff;color:#000;border:none;padding:0 .95rem;
  font-weight:700;font-size:.86rem;cursor:pointer}
#chat form button:hover{background:#e6e6e6}
#chat form button:disabled{opacity:.45;cursor:default}
@media(pointer:coarse){#chat textarea{font-size:16px}}
@media(max-width:520px){#chat{right:.75rem;left:.75rem;width:auto;bottom:4.8rem;height:min(70vh,480px)}}

/* ── Barra de reserva (móvil) ─────────────────────────────────────
   Solo en las páginas que la traen ([data-barra], hoy /inmobiliarias/)
   y solo por debajo de 1025px, que es donde la cabecera esconde su
   botón: sin ella, en el móvil no quedaba ninguna llamada a la vista
   entre el hero y el final. La enciende centry.js con .on; sin
   JavaScript no aparece nunca.
   Va por debajo del menú lateral (z 890), así que el menú la tapa, y
   el botón del asistente (z 930) se sube lo que ella mide. */
.barra-cta{
  position:fixed;left:0;right:0;bottom:0;z-index:880;
  display:flex;align-items:center;gap:var(--s4);
  padding:.7rem var(--gutter) calc(.7rem + env(safe-area-inset-bottom));
  background:var(--bg);border-top:1px solid var(--line-3);
  transform:translateY(105%);visibility:hidden;
  transition:transform .35s var(--e-out),visibility 0s linear .35s;
}
.barra-cta.on{transform:none;visibility:visible;transition:transform .35s var(--e-out),visibility 0s}
/* nowrap: por debajo de 520px .btn parte el texto, y una barra de dos
   líneas crecía hasta ~6,3rem y tapaba medio párrafo. */
.barra-cta .btn{flex:1 1 auto;justify-content:center;white-space:nowrap}
.barra-cta small{flex:none;font-size:var(--t-xs);color:var(--fg-3)}
/* El banner de cookies ocupa el mismo borde, y el panel del asistente
   abierto se superpone: en los dos casos la barra se aparta. */
body.ck-open .barra-cta.on,body:has(#chat.on) .barra-cta.on{
  transform:translateY(105%);visibility:hidden;
  transition:transform .35s var(--e-out),visibility 0s linear .35s;
}
@media(max-width:520px){.barra-cta small{display:none}}
@media(min-width:1025px){.barra-cta{display:none}}
@media(max-width:1024px){
  /* El asistente sube lo que mide la barra (--barra-alto lo publica
     centry.js) y conserva su imán, que también va por translate. */
  body.barra-on:not(.ck-open):not(:has(#chat.on)) #chat-open{
    translate:var(--iman-x,0px) calc(var(--iman-y,0px) - var(--barra-alto,4.9rem));
  }
  /* Que el foco del teclado no quede debajo de la barra (WCAG 2.4.11). */
  html:has(.barra-cta.on){scroll-padding-bottom:calc(var(--barra-alto,4.9rem) + 1rem)}
}

/* ── Canal que cambia ([data-rota]) ───────────────────────────────
   Una palabra de un titular que se borra y se reescribe con la
   siguiente: WhatsApp, Instagram, teléfono… Todas las variantes
   ocupan la MISMA celda de una rejilla, así que la caja mide siempre
   lo que la más larga y el titular no se mueve ni un píxel al
   cambiar (CLS cero). Sin JavaScript se ve la primera y nada más.
   El borrado y el tecleo son el mismo clip-path en escalones que el
   de los titulares, con dos velocidades propias: una palabra suelta a
   22 ms por letra no llega a verse escribir. */
:root{--rota-teclea:65ms;--rota-borra:32ms}
.rota{display:inline-grid;white-space:nowrap}
.rota-i{grid-area:1/1}
/* Reserva el ancho de la variante más larga (data-ancho) desde el
   primer pintado, antes de que centry.js cree las demás: sin esto,
   crearlas ensancharía la caja y movería el titular. Es contenido
   generado e invisible: no lo leen ni el buscador ni el lector de
   pantalla, así que el titular sigue diciendo solo "…por WhatsApp." */
.rota[data-ancho]::after{content:attr(data-ancho);grid-area:1/1;visibility:hidden;pointer-events:none}
/* Las variantes que crea centry.js llevan la palabra en data-t y la
   pinta este ::before: nunca son texto del documento. */
.rota-i[data-t]::before{content:attr(data-t)}
.rota-i+.rota-i{visibility:hidden}
.rota.rota-vivo .rota-i{
  visibility:visible;clip-path:inset(-40% 100% -40% -20%);
  transition:clip-path calc(var(--n,8) * var(--rota-borra)) steps(var(--n,8),jump-start);
}
.rota.rota-vivo .rota-i.on{
  clip-path:inset(-40% -20% -40% -20%);
  transition:clip-path calc(var(--n,8) * var(--rota-teclea)) steps(var(--n,8),jump-start);
}
/* Mientras gira, manda el clip de la variante: el tecleo de entrada
   del titular ya terminó y su estado final no debe pisarlo. */
.rota.rota-vivo .w{animation:none!important;clip-path:none!important}
.rota.rota-vivo .w::after{display:none}

/* ── Diagrama: tus programas → Centry ─────────────────────────────
   Una fila de seis logos y, de cada uno, una línea curva que baja y
   converge en la insignia de Centry; debajo, tres tarjetas. Piezas en
   _build/parciales/ (logos-*.html y diagrama.html).
   Todo el bloque se escala con su font-size (los logos miden en em) y
   el SVG conserva su proporción, así que en móvil es el mismo dibujo
   más pequeño: las x de las líneas (50…550 sobre 600) caen siempre en
   el centro de las seis columnas de logos.
   El coral es el acento del sitio: aquí solo en los puntos de arranque
   y en los destellos. Lo demás, blanco y grises. */
.diag{
  position:relative;isolation:isolate;max-width:40rem;margin:var(--s7) auto 0;
  font-size:clamp(.74rem,2.6vw,1rem);
}
.diag-logos{list-style:none;display:grid;grid-template-columns:repeat(6,minmax(0,1fr));align-items:center}
.diag-logo{display:flex;align-items:center;justify-content:center;gap:.32em;height:2.4em;color:var(--fg)}
.diag-logo svg{display:block;width:var(--w,4em);max-width:86%;height:auto;max-height:2.2em}
.diag-logo--txt svg{width:1.15em;flex:none}
.diag-logo--txt span,.diag-logo--nombre span{font-weight:700;font-size:.92em;letter-spacing:-.02em;line-height:1;white-space:nowrap}
.diag-logo--nombre span{font-size:1em;letter-spacing:-.035em}
/* En móvil el nombre junto al símbolo (Gmail, WhatsApp) no cabe en su
   columna: queda solo el símbolo, más grande, y el nombre pasa a ser
   texto para lectores de pantalla (se oculta sin display:none). */
@media(max-width:560px){
  .diag-logo--txt svg{width:1.45em}
  .diag-logo--txt span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}
}
.diag-lin{display:block;width:100%;height:auto;margin-top:.9em;overflow:visible}
.diag-lin path{fill:none}
.diag-lin .l{stroke:var(--line-2);stroke-width:1.5}
.diag-flujo{stroke:var(--acc);stroke-width:1.8;stroke-linecap:round;stroke-dasharray:30 100;stroke-dashoffset:30;opacity:0}
.diag-puntos circle{fill:var(--acc)}
/* La insignia: el símbolo metálico en un círculo oscuro con filete. El
   anillo coral de ::after solo existe para el destello de llegada (ver
   MOVIMIENTO); en reposo está apagado. */
.diag-centro{
  position:relative;width:4.25em;height:4.25em;margin:.35em auto 0;border-radius:50%;
  display:grid;place-items:center;
  background:radial-gradient(circle at 50% 35%,#1b1a18,var(--bg-1) 70%);
  border:1px solid var(--line-2);box-shadow:0 0 0 .35em var(--bg),0 0 0 calc(.35em + 1px) var(--line);
}
.diag-centro img{width:64%;height:auto}
.diag-centro::after{
  content:"";position:absolute;inset:-1px;border-radius:50%;pointer-events:none;opacity:0;
  box-shadow:0 0 0 1px var(--acc),0 0 1.6em rgba(255,128,128,.35);
}
.diag-nota{text-align:center;max-width:52ch;margin:var(--s6) auto 0}

/* Las tres tarjetas. Un degradado radial coral asoma por el borde de
   abajo; es fijo, no se mueve. Esquinas rectas, como el resto. */
.diag-tarjs{
  list-style:none;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:var(--s4);margin-top:var(--s8);
}
.diag-tarj{
  position:relative;isolation:isolate;overflow:hidden;
  border:1px solid var(--line-2);background:var(--bg-1);
  padding:clamp(1.5rem,2.6vw,2.1rem) clamp(1.3rem,2.4vw,1.9rem) clamp(2.2rem,3.6vw,2.9rem);
}
.diag-tarj::after{
  content:"";position:absolute;z-index:-1;left:-10%;right:-10%;bottom:-58%;height:100%;pointer-events:none;
  background:radial-gradient(closest-side,rgba(255,128,128,.3),rgba(255,128,128,.1) 50%,transparent);
}
.diag-tarj svg{
  display:block;width:1.45rem;height:1.45rem;margin-bottom:var(--s5);
  fill:none;stroke:var(--fg);stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;
}
.diag-tarj h3{font-size:var(--t-h4);font-weight:700;letter-spacing:-.012em;line-height:1.3;margin-bottom:var(--s2);text-wrap:balance}
.diag-tarj p{font-size:var(--t-sm);color:var(--fg-3);line-height:1.7}
@media(max-width:860px){.diag-tarjs{grid-template-columns:1fr;margin-top:var(--s7)}}

/* ── Stack: la barra de logos ─────────────────────────────────────
   Las herramientas sobre las que construimos, en una fila que se
   desliza hacia la izquierda sin fin (_build/parciales/stack.html).
   Van rotuladas como herramientas, no como socios: ni lo somos ni las
   marcas lo permiten.
   Blanco puro: las guías de OpenAI y WhatsApp admiten el logo en
   blanco o negro, no en gris.

   EXCEPCIÓN A «NADA SE REPITE». Es uno de los dos bucles infinitos de
   la web (el otro, los destellos del diagrama) y está porque se pidió
   expresamente. Por eso:
   · se mueve SIEMPRE, también con «reducir movimiento»: el usuario lo
     pidió así (en su propio Windows, con "Mostrar animaciones"
     apagado, la barra quieta parecía rota). Con esa preferencia va más
     despacio (bloque de movimiento reducido). Solo al imprimir queda
     quieta y centrada;
   · sólo se anima transform, en lineal y a velocidad de lectura;
   · no se para al pasar el ratón: no hay nada que pulsar.
   La costura no se ve porque la pista lleva cuatro tiras iguales y
   se desplaza la mitad exacta (-50 %): al volver al principio, lo que
   hay en pantalla es idéntico. Cada tira termina con el mismo hueco
   que separa los logos, para que el paso sea regular. */
.logos-rotulo{
  font-size:var(--t-label);letter-spacing:.15em;font-weight:600;text-transform:uppercase;
  color:var(--fg-3);text-align:center;margin-bottom:var(--s6);
}
.logos{
  --logos-hueco:clamp(2.5rem,6vw,4.5rem);
  position:relative;overflow:hidden;padding-block:.35rem;color:#fff;
  font-size:clamp(.82rem,.7rem + .5vw,1rem);
}
.logos-defs{position:absolute;width:0;height:0;overflow:hidden}
.logos-pista{display:flex;justify-content:center}
.logos-tira{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:1.4rem var(--logos-hueco);list-style:none;
}
.logos-tira[aria-hidden]{display:none}
.logos-tira>li{display:flex;align-items:center;flex:none}
.logos svg{display:block;width:auto;height:1.6em;fill:currentColor}
.logos .lg-openai{height:1.42em}
.lg-wa{gap:.45em;font-size:1.12em;font-weight:700;letter-spacing:-.015em;line-height:1;white-space:nowrap}
.logos .lg-wa svg{height:1.4em}
/* Los bordes se funden con el fondo. */
.logos{
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 14%,#000 86%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 14%,#000 86%,transparent);
}
.logos-pista{
  justify-content:flex-start;width:max-content;
  animation:logos-gira var(--logos-dur,56s) linear infinite;
}
.logos-tira{flex-wrap:nowrap;flex:none;padding-right:var(--logos-hueco)}
.logos-tira[aria-hidden]{display:flex}
@media(max-width:640px){.logos{--logos-dur:40s}}
@keyframes logos-gira{to{transform:translateX(-50%)}}
@media print{
  .logos{-webkit-mask-image:none;mask-image:none}
  .logos-pista{animation:none!important;width:auto;justify-content:center}
  .logos-tira{flex-wrap:wrap;padding-right:0}
  .logos-tira[aria-hidden]{display:none}
}

/* ── Equipo ───────────────────────────────────────────────────────
   Tarjetas grandes: foto vertical arriba, nombre y cargo debajo. Tres
   por fila en escritorio (arriba la parte técnica, abajo la comercial)
   y dos por debajo de 720px. Seis personas llenan las dos rejillas sin
   fila coja; si cambia el número, hay que revisar esto.
   Mientras no hay foto, la caja enseña las iniciales con la misma
   proporción que tendrá la foto (4:5), así que cambiarla no mueve
   nada. Las fotos van en escala de grises, como todo lo demás. */
.equipo{list-style:none;grid-template-columns:repeat(3,minmax(0,1fr))}
.cells.equipo>li{padding:0;display:flex;flex-direction:column}
.persona-foto{
  aspect-ratio:4/5;background:var(--bg-1);display:grid;place-items:center;
  border-bottom:1px solid var(--line);overflow:hidden;
}
.persona-foto span{font-size:clamp(2rem,5vw,3.75rem);font-weight:800;letter-spacing:.08em;color:var(--line-3)}
.persona-foto img{width:100%;height:100%;object-fit:cover;filter:grayscale(1);transition:transform .7s var(--e-out)}
@media(hover:hover){.equipo>li:hover .persona-foto img{transform:scale(1.03)}}
.persona-txt{padding:1.2rem 1.4rem 1.5rem}
.persona-txt b{display:block;font-size:var(--t-body);font-weight:700;letter-spacing:-.01em}
.persona-txt small{display:block;font-size:var(--t-sm);color:var(--fg-3);line-height:1.5;margin-top:.3rem}
@media(max-width:720px){
  .cells.equipo{grid-template-columns:repeat(2,minmax(0,1fr))}
  .persona-txt{padding:.9rem 1rem 1.1rem}
  .persona-txt b{font-size:var(--t-sm)}
  .persona-txt small{font-size:var(--t-xs)}
}

/* ── Al reservar, te llevas ───────────────────────────────────────
   La tarjeta que dice qué sale de la primera conversación. Un filete
   de luz por arriba la separa del resto sin usar color. */
.llevas{position:relative;border:1px solid var(--line-2);background:var(--bg-1);padding:clamp(1.6rem,4vw,2.8rem)}
.llevas::before{
  content:"";position:absolute;left:-1px;right:-1px;top:-1px;height:1px;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.75),transparent);
}
.llevas .label{margin-bottom:var(--s6)}
.llevas-lista{list-style:none;display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s6) clamp(1.5rem,4vw,3rem)}
.llevas-lista li{display:flex;flex-direction:column;gap:.5rem}
.llevas-n{font-size:var(--t-label);letter-spacing:.1em;color:var(--fg-4);font-variant-numeric:tabular-nums}
.llevas-lista b{font-size:var(--t-h4);font-weight:700;line-height:1.3}
.llevas-lista p{font-size:var(--t-sm);color:var(--fg-3);line-height:1.7}
.llevas-pie{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--s4) var(--s6);
  margin-top:var(--s7);padding-top:var(--s5);border-top:1px solid var(--line);
}
.llevas-pie p{font-size:var(--t-xs);color:var(--fg-3);line-height:1.6;max-width:52ch}
@media(max-width:820px){.llevas-lista{grid-template-columns:1fr}}

/* ── Prosa legal ──────────────────────────────────────────────── */
.prose{max-width:44rem}
.prose h2{font-size:var(--t-h3);font-weight:700;letter-spacing:-.014em;margin:var(--s7) 0 var(--s3);color:var(--fg)}
.prose h2:first-child{margin-top:0}
.prose h3{font-size:var(--t-h4);font-weight:700;margin:var(--s5) 0 var(--s2)}
.prose p,.prose li{font-size:var(--t-sm);color:var(--fg-3);line-height:1.8;max-width:68ch}
.prose p{margin-bottom:var(--s3)}
.prose ul,.prose ol{padding-left:1.2rem;margin-bottom:var(--s4);display:flex;flex-direction:column;gap:.4rem}
.prose li::marker{color:var(--fg-4)}
.prose a{color:var(--fg-2);text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--line-2)}
.prose a:hover{color:var(--signal);text-decoration-color:var(--signal-line)}
.prose strong{color:var(--fg-2)}
.prose dl{border:1px solid var(--line);margin-bottom:var(--s4)}
.prose dl>div{display:grid;grid-template-columns:11rem 1fr;gap:var(--s4);padding:.8rem 1.1rem;border-bottom:1px solid var(--line)}
.prose dl>div:last-child{border-bottom:none}
.prose dt{font-size:var(--t-label);letter-spacing:0.08em;font-weight:600;text-transform:uppercase;color:var(--fg-4);padding-top:.15rem}
.prose dd{font-size:var(--t-sm);color:var(--fg-2)}
@media(max-width:560px){.prose dl>div{grid-template-columns:1fr;gap:.2rem}}

/* ── Utilidades ───────────────────────────────────────────────── */
.stack{display:flex;flex-direction:column}
.stack-3{gap:var(--s3)} .mt-4{margin-top:var(--s4)} .mt-5{margin-top:var(--s5)}
.mt-6{margin-top:var(--s6)} .mt-7{margin-top:var(--s7)}
.mb-6{margin-bottom:var(--s6)}
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.hdr-lead{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,24rem);gap:clamp(2rem,5vw,4rem);align-items:end;margin-bottom:var(--s8)}
@media(max-width:860px){.hdr-lead{grid-template-columns:1fr;align-items:start;gap:var(--s4)}}

/* ══════════════════════════════════════════════════════════════════
   MOVIMIENTO
   Tres reglas gobiernan todo lo de abajo:
   1. Sólo se animan `transform`, `opacity` y `clip-path` (más
      `stroke-dashoffset` en los trazos SVG: iconos de los pilares y
      líneas del diagrama). Nada que obligue al navegador a recalcular
      la maquetación.
   2. El punto de partida es VISIBLE. La clase .js la pone el script
      inline del <head>, así que sin JavaScript no se oculta nada.
   3. El H1 del hero nunca parte de opacity:0 — un elemento transparente
      no puntúa como LCP en Chrome, y retrasaríamos la métrica.
   ══════════════════════════════════════════════════════════════════ */

/* ── Tecleo de titulares ──────────────────────────────────────────
   El generador envuelve cada palabra en <span class="w"> con tres
   numeros: --i (orden), --c (caracteres que van por delante) y --n
   (largo de la palabra).

   La palabra no se desvanece: se DESTAPA de izquierda a derecha con
   clip-path, en tantos escalones como letras tiene. Eso da el tecleo
   de verdad, letra a letra, y no el escalonado por palabras de antes.

   Por que clip-path y no partir el texto por caracteres:
   · un <span> por letra rompe el kerning y las ligaduras, y cambia el
     ancho del titular — medido: la caja no varia ni un pixel asi;
   · un <span> por letra multiplica por seis los nodos del documento;
   · clip-path se compone en la GPU, igual que transform y opacity.

   Velocidad: --vel es el tiempo por caracter, y ha ido y vuelto.
   A 12ms el titular terminaba en 0,8s y no daba tiempo a verlo. A 32ms
   se veia perfectamente, pero el titular de la portada tiene 77
   caracteres y tardaba 2,5s — demasiado para la frase que trae a la
   gente aqui. 22ms es el equilibrio: 1,7s la portada y unos 0,6s los
   titulares de seccion. Se ve teclear de principio a fin sin que nadie
   espere para leer.
   Una maquina de escribir real va a 60-100ms por tecla; a esa
   velocidad este titular tardaria mas de cinco segundos. */
.w{display:inline-block;will-change:clip-path}
:root{--vel:22ms}

/* Un titular ya partido no se desvanece como bloque: lo hacen sus
   palabras. Sin esto se encadenarian dos fundidos sobre lo mismo. */
.js [data-rv][data-split]{opacity:1;transform:none;transition:none}

/* El tecleo NO esta detras de @media(no-preference). Lo estaba, y por
   eso en un equipo con "reducir movimiento" activado el titular
   aparecia de golpe y la web entera parecia muerta. Un barrido corto
   de texto no es de los movimientos que marean: no desplaza nada, no
   gira, no se repite y no retrasa la lectura. Lo que cambia con esa
   preferencia es la VELOCIDAD — --vel baja a 14ms, el titular de la
   portada termina en 1,1s — y que el cursor se acorta con ella. */

/* 1. Titular de la pagina. Teclea solo, con una animacion CSS en
   forwards: no espera a ningun script ni a ningun observador, asi
   que no puede quedarse tapado si el JS falla.
   El -20%/-40% es holgura hacia fuera, para no recortar tildes,
   colas ni el filete del punto. */
.js [data-typed] .w{
  /* El estado de partida va AQUI, no en el fill-mode de la animacion.
     Con `both`, el relleno hacia atras aplica el valor en progreso 0 —
     y `jump-start` salta en ese mismo instante, asi que el valor
     rellenado durante la espera ya era 1/n: cada palabra ensenaba su
     primera letra desde el segundo cero, todas a la vez. Se veia el
     titular entero salpicado de letras sueltas antes de escribirse.
     Con `forwards`, durante la espera manda esta regla —tapada— y la
     animacion solo se queda con el estado final. */
  clip-path:inset(-40% 100% -40% -20%);
  animation:teclear calc(var(--n) * var(--vel)) steps(var(--n),jump-start) forwards;
  animation-delay:calc(var(--c) * var(--vel));
}

/* 2. Titulares de seccion. Esperan a entrar en pantalla, y solo se
   tapan los que tienen data-rv — que son justo los que reciben
   .rv-in y vuelven a destaparse. Cualquier otro titular partido se
   queda visible, como debe. */
.js [data-rv][data-split] .w{clip-path:inset(-40% 100% -40% -20%)}
.js [data-rv][data-split].rv-in .w{
  clip-path:inset(-40% -20% -40% -20%);
  transition:clip-path calc(var(--n) * var(--vel)) steps(var(--n),jump-start);
  transition-delay:calc(var(--c) * var(--vel));
}

/* Cursor de la maquina de escribir.
   Estaba en el ::after del TITULAR, es decir al final de toda la frase.
   Como el titular ocupa su sitio definitivo desde el principio aunque
   el texto este tapado, el cursor aparecia flotando en medio del hueco
   vacio, a cuatro lineas de distancia de la letra que se estaba
   escribiendo. Parecia un fallo, no un efecto.

   Ahora hay un cursor por PALABRA, dentro de ella, y recorre la palabra
   con exactamente los mismos escalones que la destapan: va justo en la
   letra que se esta escribiendo. Dos animaciones sobre el mismo
   pseudo-elemento, con el mismo reloj:
   · caretPos mueve el cursor de izquierda a derecha, a saltos de letra;
   · caretOn lo enciende durante el turno de esa palabra y lo apaga al
     acabar — esta encendido hasta el 99,9% y se apaga en el 100%.
   Sin `backwards` en el relleno: antes de que le toque, manda la regla
   de abajo y el cursor esta apagado. */
.js [data-typed] .w{position:relative}
.js [data-typed] .w::after{
  content:"";position:absolute;left:0;top:.08em;bottom:.1em;
  width:.055em;min-width:1px;background:currentColor;
  opacity:0;pointer-events:none;
  animation:caretPos calc(var(--n) * var(--vel)) steps(var(--n),jump-start) forwards,
            caretOn calc(var(--n) * var(--vel)) linear forwards;
  animation-delay:calc(var(--c) * var(--vel));
}

/* Los titulares del hero no llevan data-rv (estan sobre el pliegue):
   el BLOQUE no debe animarse por su cuenta, lo hacen sus palabras. Sin
   esto, .hero [data-in] le aplicaria el fundido de entrada al h1 entero
   y ademas lo dejaria en opacity:0 un momento — y un elemento
   transparente no puntua como LCP en Chrome. */
.hero h1[data-in],.phero h1[data-in]{animation:none}

@keyframes teclear{
  from{clip-path:inset(-40% 100% -40% -20%)}
  to{clip-path:inset(-40% -20% -40% -20%)}
}

/* El cursor camina con las letras y se apaga al pasar a la siguiente
   palabra. No parpadea: parpadear obliga a repetir una animacion
   indefinidamente, y eso si es de las cosas que hay que quitar cuando
   alguien pide menos movimiento. */
@keyframes caretPos{from{left:0}to{left:100%}}
/* El apagado NO usa steps(1). Lo usaba, y en un titular concreto
   —la palabra 7 de 8 de /como-trabajamos/— el cursor se quedaba
   encendido para siempre: la animacion daba playState 'finished' y
   aun asi el valor retenido era el de partida. Con keyframes
   explicitos y linear no hay ambiguedad: en el 100% vale 0, y eso
   es lo que retiene forwards. */
@keyframes caretOn{0%,99.9%{opacity:1}100%{opacity:0}}

/* ── Revelado al hacer scroll ─────────────────────────────────── */
.js [data-rv]{opacity:0;transform:translateY(16px)}
.js [data-rv].rv-in{
  opacity:1;transform:none;
  transition:opacity .66s var(--e-out),transform .66s var(--e-out);
}
.js [data-rv-d="1"].rv-in{transition-delay:.08s}
.js [data-rv-d="2"].rv-in{transition-delay:.16s}
.js [data-rv-d="3"].rv-in{transition-delay:.24s}

/* Escalonado de rejillas. El índice lo escribe el JS una sola vez al
   observar el contenedor, no en cada fotograma. */
.js [data-stagger] > *{opacity:0;transform:translateY(18px)}
.js [data-stagger].rv-in > *{
  opacity:1;transform:none;
  transition:opacity .58s var(--e-out),transform .58s var(--e-out);
  transition-delay:calc(var(--i,0) * 70ms);
}

/* ── Cuando GSAP está al mando ──────────────────────────────────
   La clase .gs la pone movimiento.js, y sólo si GSAP llegó y arrancó
   sin fallar. Entonces el revelado por clase se aparta: quien mueve
   opacidad y posición es GSAP, con líneas de tiempo por sección.

   La clase .rv-in SE SIGUE PONIENDO, porque de ella cuelgan cosas que
   siguen siendo del CSS: el tecleo de los titulares, el filete de las
   etiquetas y el trazo de los iconos. Lo único que se apaga aquí es la
   TRANSICIÓN, para que el fundido del CSS no se sume al de GSAP.

   Si .gs no aparece —librería bloqueada, navegador antiguo, un error—
   todo lo de arriba sigue en pie tal cual. La web nunca depende de la
   librería para mostrarse; sólo para verse mejor. */
.gs [data-rv],.gs [data-rv].rv-in,
.gs [data-stagger].rv-in > *,.gs [data-rv].rv-in .vs-i{transition:none!important}

/* ── Entrada del hero (elementos que no son el titular) ─────────── */
@media(prefers-reduced-motion:no-preference){
  .hero [data-in],.phero [data-in]{animation:rise .62s var(--e-out) both}
  [data-in="2"]{animation-delay:.05s}
  [data-in="3"]{animation-delay:.12s}
  [data-in="4"]{animation-delay:.19s}
  [data-in="5"]{animation-delay:.26s}

  /* Las reglas verticales del fondo del hero se dibujan solas. */
  .rule-grid span{transform-origin:top;animation:ruleIn 1.3s var(--e-out) both}
  .rule-grid span:nth-child(2){animation-delay:.1s}
  .rule-grid span:nth-child(3){animation-delay:.2s}
}
@keyframes rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes ruleIn{from{transform:scaleY(0)}to{transform:scaleY(1)}}

/* ── Iconos de trazo: se dibujan al entrar ───────────────────────
   Sólo sobre los iconos de los pilares, que son cuatro. Aplicarlo a
   todos los SVG del sitio sería gratuito y costoso a la vez. */
@media(prefers-reduced-motion:no-preference){
  .js .pillar-i svg path,.js .pillar-i svg circle{
    stroke-dasharray:var(--len,48);stroke-dashoffset:var(--len,48);
  }
  .js [data-rv].rv-in .pillar-i svg path,
  .js [data-rv].rv-in .pillar-i svg circle{
    stroke-dashoffset:0;
    transition:stroke-dashoffset .9s var(--e-out);
    transition-delay:calc(.2s + var(--i,0) * 90ms);
  }
}

/* ── Micro-interacciones ─────────────────────────────────────────
   Todas por transform o color. Ninguna toca la maquetación. */
/* Las celdas ya NO se levantan al pasar por encima. Dentro de una
   rejilla de hairlines, mover una celda tres píxeles abre un hueco en
   la línea que la separa de su vecina: se ve el fallo, no el gesto. */
.terr{transition:background-color .3s var(--e-io)}
@media(hover:hover){
  .terr:hover .terr-n{color:var(--signal)}
  .terr:hover h3{color:var(--signal)}
}
.terr h3{transition:color .3s var(--e-io)}
.terr-n{transition:color .3s var(--e-io)}



/* El botón se hunde al pulsarlo. Dos cuidados:
   · va por `transform`; el imán del puntero escribe en `translate`, que
     es otra propiedad — si compartieran una se pisarían;
   · NO se declara aquí un `transition` nuevo. La primera versión de
     esto puso un atajo `transition:` sobre .btn y sobre summary, y al
     ser una propiedad abreviada BORRÓ las que ya tenían declaradas: el
     botón perdió el suavizado del imán y el summary el deslizamiento
     del hover. Cada elemento ya lleva `transform` en su transición.
   · .btn--solid se eleva 2px al pasar por encima, así que su pulsación
     tiene que partir de ahí; si no, al pulsar caería de golpe. */
.btn:active{transform:scale(.97)}
.btn--solid:active{transform:translateY(-1px) scale(.97)}

/* Enlaces de navegación: subrayado que crece desde la izquierda. */
.nav-a{position:relative}
.nav-a::after{
  content:"";position:absolute;left:0;right:0;bottom:-.34rem;height:1px;
  background:var(--signal);transform:scaleX(0);transform-origin:right;
  transition:transform .32s var(--e-out);
}
@media(hover:hover){.nav-a:hover::after{transform:scaleX(1);transform-origin:left}}
.nav-a[aria-current="page"]::after{transform:scaleX(1);background:var(--signal)}

/* Filas del panel: entran escalonadas. */
.js [data-rv].rv-in .panel-row{animation:rowIn .5s var(--e-out) both}
.js [data-rv].rv-in .panel-row:nth-child(2){animation-delay:.09s}
.js [data-rv].rv-in .panel-row:nth-child(3){animation-delay:.18s}
.js [data-rv].rv-in .panel-row:nth-child(4){animation-delay:.27s}
@keyframes rowIn{from{opacity:0;transform:translateX(-8px)}to{opacity:1;transform:none}}

/* ── Diagrama: las líneas se trazan y los datos van llegando ─────
   No cuelga de la línea de tiempo de su sección: la sección mide más
   de una pantalla y el diagrama se habría animado sin que nadie lo
   viera. Tiene su propio observador (centry.js) que le pone .en-vista
   al verse y .en-pausa cuando sale de la pantalla.

   Primero las seis líneas se trazan hacia Centry y aparecen los puntos
   de arranque. Luego, por las seis a la vez, baja un destello coral
   que se funde al llegar, y la insignia se enciende un instante.

   EXCEPCIÓN CONSCIENTE a "nada infinito": los destellos se repiten sin
   fin, porque el efecto ES que los datos siguen llegando (lo pidió así
   el cliente, como la referencia de la que sale). Tres límites:
   · solo corren mientras el diagrama está en pantalla: fuera, .en-pausa
     congela la animación (animation-play-state), no la reinicia;
   · con movimiento reducido no hay trazado (las líneas están dibujadas
     desde el principio) y los destellos siguen, pero más despacio
     (bloque de movimiento reducido);
   · solo se anima stroke-dashoffset y opacity (la excepción de los
     trazos SVG ya aceptada arriba), nada que recalcule maquetación.
   El estado tapado solo existe bajo .js: sin centry.js las líneas se
   ven enteras y los destellos, que parten de opacity:0, no salen. */
@media(prefers-reduced-motion:no-preference){
  .js [data-diag] .diag-lin .l{
    stroke-dasharray:100;stroke-dashoffset:100;
    transition:stroke-dashoffset 1.2s var(--e-out);transition-delay:calc(var(--i,0) * 80ms);
  }
  .js [data-diag].en-vista .diag-lin .l{stroke-dashoffset:0}
  .js [data-diag] .diag-puntos circle{
    opacity:0;transition:opacity .4s linear;transition-delay:calc(var(--i,0) * 80ms);
  }
  .js [data-diag].en-vista .diag-puntos circle{opacity:1}
}
/* Los destellos van fuera del @media a propósito: corren también con
   «reducir movimiento», más despacio (bloque de movimiento reducido),
   porque el usuario los quiere siempre. */
.js [data-diag].en-vista .diag-flujo{animation:flujo 4.2s linear 1.5s infinite}
.js [data-diag].en-vista .diag-centro::after{animation:llega 4.2s linear 1.5s infinite}
.js [data-diag].en-pausa .diag-flujo,
.js [data-diag].en-pausa .diag-centro::after{animation-play-state:paused}
/* El destello (30 de 100 de la línea) entra por arriba, baja con
   aceleración suave y se funde al llegar; el resto del ciclo, quietud:
   llegan de uno en uno, no en chorro. */
@keyframes flujo{
  0%{stroke-dashoffset:30;opacity:0;animation-timing-function:cubic-bezier(.45,0,.55,1)}
  8%{opacity:1}
  58%{opacity:1}
  70%{stroke-dashoffset:-100;opacity:0}
  100%{stroke-dashoffset:-100;opacity:0}
}
/* La insignia se enciende cuando la cabeza del destello la alcanza. */
@keyframes llega{
  0%,40%{opacity:0}
  50%{opacity:1}
  74%,100%{opacity:0}
}

/* ── Preferencia de movimiento reducido ─────────────────────────
   Aquí había un `*{transition-duration:.01ms}` que apagaba la web
   entera. Era demasiado, y se notaba: en un equipo con esa preferencia
   puesta —que en Windows se activa sin querer, es el mismo interruptor
   de "Mostrar animaciones"— no se veía el tecleo, no aparecía nada al
   bajar y el cursor iba clavado al ratón. La web parecía rota.

   `reduce` quiere decir REDUCIDO, no apagado. Lo que molesta de verdad
   a quien tiene sensibilidad vestibular es el movimiento grande: lo que
   se desplaza, lo que hace paralaje, lo que gira y lo que se repite.
   Un fundido corto y un barrido de texto no.

   Así que aquí se quita, una por una:
   · toda traslación de entrada — las cosas aparecen, no suben;
   · todo lo que se dibuja solo o se repite: reglas del fondo, trazos
     de los iconos;
   · el imán de los botones;
   y se acorta lo que queda. El tecleo sigue, a 14 ms por carácter. */
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto!important}
  /* 14ms en vez de 22: el titular de la portada pasa de 1,7s a 1,1s.
     Se sigue viendo teclear. Aquí llegó a estar en 4ms —dos décimas en
     total— y eso es no verlo. */
  :root{--vel:14ms}

  /* 1. Nada se desplaza: sólo aparece. */
  .js [data-rv],.js [data-stagger] > *,
  .hero [data-in],.phero [data-in],
  .js [data-rv].rv-in .panel-row{transform:none!important}
  .btn{translate:none!important}

  /* 2. Nada se dibuja solo ni se repite. */
  .rule-grid span{animation:none!important;transform:none!important}
  .js .pillar-i svg path,.js .pillar-i svg circle{
    stroke-dasharray:none!important;stroke-dashoffset:0!important;transition:none!important;
  }
  .js [data-rv].label::before,.js [data-rv].label::after{transform:scaleX(1)!important;transition:none!important}

  /* 3. Lo que queda son fundidos cortos, y todos a la vez: sin cascada,
     que la cascada es lo que hace que la página "se mueva sola". */
  .js [data-rv].rv-in,.js [data-stagger].rv-in > *{
    transition:opacity .3s linear!important;transition-delay:0s!important;
  }
  /* El H1 queda fuera: un titular que parte de opacity:0 no puntúa como
     LCP. Antes entraba aquí, y el !important pisaba la excepción de
     .hero h1[data-in]: con la preferencia puesta, el H1 de todas las
     páginas se fundía desde transparente. */
  .hero [data-in]:not(h1),.phero [data-in]:not(h1),
  .js [data-rv].rv-in .panel-row{animation:fundido .3s linear both!important}

  /* 4. La barra de reserva no sube desde abajo: aparece. Y el asistente
     cambia de sitio sin desplazarse. */
  .barra-cta{transform:none!important;opacity:0;transition:opacity .3s linear,visibility 0s linear .3s!important}
  .barra-cta.on{opacity:1;transition:opacity .3s linear,visibility 0s!important}
  body.ck-open .barra-cta.on,body:has(#chat.on) .barra-cta.on{opacity:0}
  #chat-open{transition:border-color .22s,color .22s!important}

  /* 5. Los dos únicos bucles de la web —los destellos del diagrama y
     la barra de logos— SIGUEN, más despacio: el usuario los quiere
     siempre en marcha (29/09/2026). Las líneas del diagrama están
     trazadas desde el principio, con sus puntos. El canal que cambia
     sigue, más rápido y una sola vuelta (centry.js). */
  .logos{--logos-dur:90s}
  .js [data-diag] .diag-lin .l{stroke-dasharray:none!important;stroke-dashoffset:0!important;transition:none!important}
  .js [data-diag] .diag-puntos circle{opacity:1!important;transition:none!important}
  .js [data-diag].en-vista .diag-flujo,
  .js [data-diag].en-vista .diag-centro::after{animation-duration:6.3s}
  :root{--rota-teclea:40ms;--rota-borra:20ms}
  .equipo .persona-foto img{transition:none!important;transform:none!important}
}
@keyframes fundido{from{opacity:0}to{opacity:1}}

/* ── Impresión ────────────────────────────────────────────────── */
@media print{
  .hdr,.drawer,.ftr-bar,#chat-open{display:none!important}
  body{background:#fff;color:#000}
  .sect{padding-block:1.5rem;border-color:#ccc}
}

/* ══════════════════════════════════════════════════════════════════
   CURSOR BURBUJA
   Recuperado de la web anterior (punto + anillo con retardo elástico).
   Se conservan los valores originales: anillo de 40 px que crece a 64,
   punto de 5 px, interpolación del 12 %, paleta acromática.

   Cambios respecto al original, todos por un motivo concreto:
   · el movimiento va por `transform`, no por `left`/`top`, que forzaba
     recálculo de maquetación en cada fotograma;
   · el crecimiento en hover va por `scale()`, no por `width`/`height`;
   · los campos de texto conservan su cursor nativo de inserción;
   · el punto lleva un contorno sutil, porque blanco sobre el botón
     blanco desaparecía por completo.
   ══════════════════════════════════════════════════════════════════ */
:root{
  --cur-size:40px;
  --cur-hot:1.6;
  /* Subido desde .42: a ese valor el anillo se perdia sobre las
     secciones claras y sobre las fotos. Con .58 sigue siendo discreto
     y se ve en toda la web. */
  --cur-bd:rgba(255,255,255,.58);
  --cur-bd-hot:rgba(255,255,255,.9);
  --cur-fill-hot:rgba(255,255,255,.06);
  --cur-dot:#fff;
}

/* El cursor nativo sólo se apaga cuando el sustituto EXISTE ya en el
   DOM. Si el script fallara, la clase no se añade y el usuario conserva
   su puntero de siempre. */
html.cur-on,html.cur-on *,html.cur-on *::before,html.cur-on *::after{cursor:none!important}

/* Excepción deliberada: escribir sin barra de inserción visible es un
   problema real de usabilidad, no un detalle estético. */
html.cur-on :is(input,textarea,select,[contenteditable="true"]){cursor:auto!important}

.cur,.cur-dot{
  position:fixed;top:0;left:0;pointer-events:none;z-index:9999;
  opacity:0;transition:opacity .25s ease;will-change:transform;
}
.cur.is-on,.cur-dot.is-on{opacity:1}

.cur-dot{
  width:5px;height:5px;border-radius:50%;background:var(--cur-dot);
  /* Contorno tenue: sin él el punto se pierde sobre los botones claros. */
  box-shadow:0 0 0 1px rgba(0,0,0,.35);
}

/* `.cur` es un ancla de 0×0 que mueve el bucle; el anillo vive dentro.
   Separarlos evita que el translate3d del rAF y el scale() del hover
   se peleen por la misma propiedad `transform`. */
.cur{width:0;height:0}
.cur__ring{
  position:absolute;top:0;left:0;
  width:var(--cur-size);height:var(--cur-size);box-sizing:border-box;
  border:1.5px solid var(--cur-bd);border-radius:50%;
  /* Halo negro por fuera: garantiza el contraste del anillo tambien
     sobre un boton blanco, sin pintar nada visible sobre el negro. */
  box-shadow:0 0 0 1px rgba(0,0,0,.22);
  transform:translate(-50%,-50%) scale(1);
  transition:transform .3s cubic-bezier(.22,.61,.36,1),
             border-color .3s ease,border-width .3s ease,background-color .3s ease;
}
.cur.is-hot .cur__ring{
  transform:translate(-50%,-50%) scale(var(--cur-hot));
  border-color:var(--cur-bd-hot);
  /* .94 × 1.6 = 1.5 px reales: el borde no engorda al escalar. */
  border-width:.94px;
  background-color:var(--cur-fill-hot);
}
.cur.is-down .cur__ring{transform:translate(-50%,-50%) scale(.85)}
.cur.is-hot.is-down .cur__ring{transform:translate(-50%,-50%) scale(calc(var(--cur-hot) * .88))}

/* Redes de seguridad. El JS ya evita estos casos, pero si una hoja
   cacheada se colara, el puntero del sistema vuelve igualmente. */
@media(pointer:coarse),(hover:none){
  html.cur-on,html.cur-on *,html.cur-on *::before,html.cur-on *::after{cursor:auto!important}
  .cur,.cur-dot{display:none!important}
}
/* Movimiento reducido: el cursor se queda, Y EL RETARDO TAMBIEN.
   Aqui hubo dos errores seguidos. Primero un display:none, que le
   quitaba el cursor a quien tuviera la preferencia puesta. Luego, al
   arreglarlo, deje el anillo pegado al puntero sin retardo — y el
   retardo ES el cursor: el punto va delante y la burbuja lo alcanza.
   Sin eso son dos circulos superpuestos.

   Un elemento que sigue a la mano del propio usuario no es movimiento
   autonomo: no aparece solo, no se repite y no se lo encuentra nadie
   sin haberlo provocado. Se queda. Lo unico que se acorta es la cola,
   que el JS hace subiendo la interpolacion de .11 a .30. */
/* Alto contraste de Windows: jamás escondemos el puntero del sistema,
   porque ahí el usuario lo ha configurado a propósito. */
@media(forced-colors:active){
  html.cur-on,html.cur-on *{cursor:auto!important}
  .cur,.cur-dot{display:none!important}
}

/* ── Con el dedo ────────────────────────────────────────────
   (pointer:coarse) pregunta "se maneja con un dedo?", que es lo que
   de verdad importa aqui. Por ancho no vale: hay tablets anchas que
   son tactiles y portatiles estrechos que no lo son. En raton no
   cambia absolutamente nada.

   Y va al FINAL del archivo a proposito: .crumb a y .ftr-bar a ya
   existen mas arriba con la misma especificidad, y entre dos reglas
   igual de especificas gana la que viene despues. */
@media (pointer:coarse){
  /* 16px en los campos NO es una decision de estilo. Safari en iOS
     hace zoom automatico al enfocar cualquier campo de menos de 16px
     y deja la pagina descuadrada y desplazada a la derecha, y de ahi
     ya no vuelve solo. Es el fallo clasico del formulario en movil.
     16px exactos, no 1rem: si alguien ha cambiado el tamaño de letra
     del navegador, 1rem deja de ser 16px y vuelve el zoom. */
  .field input,.field select,.field textarea{font-size:16px}
  .check input[type="checkbox"]{width:1.35rem;height:1.35rem}

  /* Objetivos tactiles. Se crecen con relleno, no con altura fija:
     el relleno agranda la zona sensible sin mover nada de sitio ni
     cambiar como se ve el texto. */
  .crumb a{padding-block:.62rem}
  .ftr-bar a{padding-block:.72rem}
  .brand{padding-block:.35rem}
}
