/* ============================================================
   VirtualNet Cloud — hoja de estilo del sitio
   T031 Fase 2 · Leo · sobre la dirección B "Operación" de Diego

   Los tokens, la escala tipográfica y los componentes de portada
   son los de direccion-b-operacion.html sin alterar. Lo añadido
   aquí es lo que la maqueta no cubría: páginas interiores, migas,
   formulario, prosa larga y marcadores internos.

   Cero JavaScript. El menú móvil es <details>.
   ============================================================ */

@font-face{font-family:'Host Grotesk';font-style:normal;font-weight:400 700;font-display:swap;
  src:url(/assets/fonts/host-grotesk-latin.woff2?v=5662dcd15d) format('woff2')}

:root{
  /* --- color: paleta de la pieza del 15-oct (tokens medidos por Diego el
     16-oct sobre el .html de la pieza, NO los del logo de AI Maestro).
     PROVISIONAL hasta que Diego cierre bandas y tratamiento. Contraste
     medido y defendido por tests/unit/test_contraste.py. --- */
  --paper:     oklch(0.19 0.065 266);   /* fondo                      #061130 */
  --paper-2:   oklch(0.23 0.07 266);    /* superficie, hover          #0d1a3d */
  --paper-3:   oklch(0.27 0.075 266);   /* hover sobre superficie */
  --rule:      oklch(0.42 0.13 263);    /* lineas: decoracion, 2,2:1 */
  --rule-soft: oklch(0.32 0.10 265);
  --rule-strong: var(--ink);            /* filetes fuertes de seccion */
  --ink:       oklch(0.97 0.01 260);    /* texto, 17:1 */
  --ink-2:     oklch(0.80 0.05 260);    /* texto 2, 9,9:1 */
  --ink-3:     oklch(0.62 0.07 262);    /* solo numerales grandes decorativos */
  --accent:    #2d71ff;                 /* 4,4:1: H1, titulares grandes, decoracion. NUNCA texto pequeno */
  --accent-ch: 0.60 0.235 263;          /* el mismo acento, para tintes con alfa */
  --accent-text: oklch(0.72 0.17 255);  /* #53a6ff, 7,3:1: enlaces, kickers, texto pequeno */
  --accent-bg: #2563eb;                 /* boton y banda CTA (Lola y Diego) */
  --accent-on: var(--ink);              /* texto sobre --accent-bg, 4,7:1. Texto 2 aqui NO: 2,8 */
  --live:      oklch(0.84 0.14 205);    /* cian: solo puntos y estados */
  --alert:     oklch(0.50 0.17 30);
  --alert-on:  var(--ink);
  --alert-text: oklch(0.74 0.14 35);    /* el asterisco de obligatorio, sobre el fondo */
  --band:      var(--paper-2);          /* barras y cabeceras que antes iban en tinta */
  --band-ink:  var(--ink);
  --band-ink-2: var(--ink-2);
  --night:     oklch(0.19 0.065 266);   /* hero y clientes */
  --night-ch:  0.19 0.065 266;
  --hl:        0.97 0.01 260;           /* filetes finos con alfa sobre oscuro */

  /* --- tipografía --- */
  /* Autohospedada (privacidad: ningun tercero recibe peticion). Una sola
     familia: Diego eligio la variante A el 2026-10-16 y Big Shoulders salio.
     --disp se queda como nombre de rol, para no tocar cada selector. */
  --disp: var(--sans);
  --sans: 'Host Grotesk', -apple-system, 'Helvetica Neue', Arial, sans-serif;

  --fs-h1:   clamp(3.4rem, 10.5vw, 9.5rem);
  --fs-h1s:  clamp(2.6rem, 7vw, 5.4rem);   /* h1 de página interior */
  --fs-h2:   clamp(2.5rem, 6vw, 4.75rem);
  --fs-h2s:  clamp(1.9rem, 3.6vw, 2.9rem); /* h2 dentro de prosa */
  --fs-h3:   clamp(1.15rem, 1.6vw, 1.35rem);
  --fs-lead: clamp(1.06rem, 1.35vw, 1.24rem);
  --fs-body: 1.02rem;
  --fs-meta: 0.69rem;

  --pad: clamp(1.1rem, 4vw, 4rem);
  --sec: clamp(4rem, 8vw, 8rem);
  --max: 1420px;
  --prose: 68ch;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{
  margin:0;background:var(--paper);color:var(--ink);
  font-family:var(--sans);font-size:var(--fs-body);line-height:1.55;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block}
a{color:inherit}
h1,h2,h3,h4,p,figure{margin:0}
::selection{background:var(--accent-bg);color:var(--accent-on)}
:where(a,button,input,select,textarea,summary):focus-visible{outline:2px solid var(--accent-text);outline-offset:2px}

.wrap{max-width:var(--max);margin-inline:auto;padding-inline:var(--pad)}
.meta{
  font-family:var(--sans);font-size:var(--fs-meta);font-weight:600;
  letter-spacing:.18em;text-transform:uppercase;line-height:1.4;
}
.disp{font-family:var(--disp);text-transform:uppercase;font-weight:700;letter-spacing:.004em;line-height:.86}
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
.skip{
  position:absolute;left:.5rem;top:-4rem;z-index:80;background:var(--accent-bg);color:var(--accent-on);
  padding:.7rem 1rem;text-decoration:none;font-size:.8rem;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;transition:top .15s;
}
.skip:focus{top:.5rem}

/* ---------- marcador interno (se elimina con build.py --public) ---------- */
.internal{
  background:var(--alert);color:var(--alert-on);
  border-bottom:2px solid var(--rule-strong);
}
.internal .wrap{padding-block:.6rem}
.internal p{font-size:.8rem;line-height:1.45;max-width:none}
.internal p + p{margin-top:.3rem}
.internal strong{font-size:var(--fs-meta);font-weight:700;letter-spacing:.16em;text-transform:uppercase}
.internal a{color:var(--alert-on)}

/* ---------- selector de idioma ---------- */
.status-right{display:inline-flex;align-items:center;gap:.9rem;flex-wrap:wrap}
.langsw{display:inline-flex;align-items:center;gap:.1rem}
.langsw a,.langsw span{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:1.75rem;min-height:1.55rem;padding:.18rem .42rem;line-height:1;
  text-decoration:none;border:1px solid oklch(var(--hl)/.28);
}
@media (pointer:coarse){.langsw a,.langsw span{min-width:2.6rem;min-height:1.7rem}}
.langsw a + a,.langsw a + span,.langsw span + a{margin-left:-1px}
.langsw a:hover,.langsw a:focus-visible{background:var(--accent-bg);color:var(--accent-on);border-color:var(--accent-bg)}
.langsw [aria-current="true"]{background:var(--accent-bg);color:var(--accent-on);border-color:var(--accent-bg)}

/* Cadena aun sin traducir. Solo se ve en el build interno; con --public
   la version espanola cae a ingles en silencio. */
.untranslated{
  text-decoration:underline;text-decoration-style:dotted;text-decoration-thickness:1px;
  text-decoration-color:var(--alert-text);text-underline-offset:.22em;
}

/* ---------- barra de estado ---------- */
.status{background:var(--band);color:var(--band-ink)}
.status .wrap{display:flex;justify-content:space-between;align-items:center;gap:1rem;min-height:2.3rem;flex-wrap:wrap}
.status .meta{color:var(--band-ink-2)}
.st-short{display:none}
.status a{text-decoration:none}
.status a:hover{color:var(--accent-text)}
.dot{
  display:inline-block;width:.5rem;height:.5rem;background:var(--live);
  border-radius:50%;margin-right:.5rem;vertical-align:.02rem;
}
@media (prefers-reduced-motion:no-preference){
  .dot{animation:blink 2.6s cubic-bezier(.16,1,.3,1) 3 both}   /* Fase 0: tres veces y se queda encendido */
  @keyframes blink{0%,72%,100%{opacity:1}82%{opacity:.25}}
}

/* ---------- nav ---------- */
header.nav{position:sticky;top:0;z-index:40;background:var(--paper);border-bottom:1px solid var(--rule-strong)}
header.nav .wrap{display:flex;align-items:stretch;gap:0;min-height:4.3rem}
.mark{display:flex;align-items:center;gap:.55rem;text-decoration:none;padding-right:2rem}
.mark .m1{font-family:var(--disp);text-transform:uppercase;font-weight:800;font-size:1.85rem;line-height:1;letter-spacing:.005em}
.mark .m2{
  font-size:.6rem;font-weight:700;letter-spacing:.2em;text-transform:uppercase;
  border:1px solid var(--rule-strong);padding:.22rem .42rem;line-height:1;
}
nav.links{display:flex;align-items:stretch;margin-left:auto}
nav.links a{
  display:flex;align-items:center;padding-inline:1.35rem;text-decoration:none;
  font-size:.82rem;font-weight:600;letter-spacing:.02em;
  border-left:1px solid var(--rule);
  transition:background-color .2s cubic-bezier(.22,1,.36,1);
}
nav.links a:hover,nav.links a:focus-visible{background:var(--accent-bg);color:var(--accent-on)}
nav.links a[aria-current="page"]{box-shadow:inset 0 -3px 0 var(--ink);font-weight:700}
@media (max-width:1000px){nav.links{display:none}}
/* T172 (Diego, 27-oct): con «Contact» en el menú, entre 1001 y 1179 px se partían
   enlaces (ES hasta 1100, EN a 1001-1024). Ahí hay portátiles pequeños y tablets en
   horizontal: el menú se queda entero, con menos aire. El nowrap va fuera de la media
   query a propósito: si un texto crece, se verá como desborde y no como enlace partido. */
nav.links a,.nav-cta{white-space:nowrap}
@media (min-width:1001px) and (max-width:1179px){
  nav.links a{padding-inline:.8rem}
  .nav-cta{padding-inline:1rem;letter-spacing:.08em}
  .mark{padding-right:1rem}
}

/* menú móvil sin JS. Panel opaco: F-07 de la auditoría. */
.menu{display:none}
@media (max-width:1000px){
  .menu{display:block;border-top:1px solid var(--rule);background:var(--paper)}
  .menu summary{
    list-style:none;cursor:pointer;padding:.8rem var(--pad);
    font-size:var(--fs-meta);font-weight:700;letter-spacing:.16em;text-transform:uppercase;
    display:flex;justify-content:space-between;align-items:center;
  }
  .menu summary::-webkit-details-marker{display:none}
  .menu summary::after{content:"+";font-size:1.05rem;line-height:1}
  .menu[open] summary::after{content:"\2013"}
  .menu ul{list-style:none;margin:0;padding:0 var(--pad) .9rem;display:grid}
  .menu > ul > li > a{
    display:block;padding:.7rem 0;text-decoration:none;
    border-top:1px solid var(--rule);font-family:var(--disp);
    text-transform:uppercase;font-weight:700;font-size:1.3rem;line-height:1;
  }
  .menu ul ul{padding:0 0 .5rem 0;display:grid;gap:.1rem}
  .menu ul ul a{
    display:block;padding:.42rem 0 .42rem .9rem;text-decoration:none;
    font-size:.9rem;color:var(--ink-2);border-left:1px solid var(--rule);
  }
}
.nav-cta{margin-left:auto}
nav.links + .nav-cta{margin-left:0}
/* T146: por debajo de 1000 px nav.links esta oculto pero sigue siendo el hermano
   de delante, y la regla de arriba pegaba el boton al logo. Con «VirtualNet
   Cloud» no se notaba porque el logo llenaba la fila; con «VNet Cloud» quedaba un
   hueco a la derecha. Jaime: el boton, al borde derecho. */
@media (max-width:1000px){nav.links + .nav-cta{margin-left:auto}}
.nav-cta{
  display:flex;align-items:center;padding-inline:1.5rem;background:var(--accent-bg);color:var(--accent-on);
  text-decoration:none;font-size:.74rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  transition:background-color .2s cubic-bezier(.22,1,.36,1),color .2s cubic-bezier(.22,1,.36,1);
}
.nav-cta:hover,.nav-cta:focus-visible{background:var(--ink);color:var(--paper)}

/* Este bloque vivia ANTES de las reglas base de .nav-cta y .mark, asi que
   no aplicaba nada: las media queries no suman especificidad y ganaba el
   orden. El diseno estrecho estaba escrito y era codigo muerto — de ahi
   que a 320 px el boton midiese 192 px y desbordase la pagina entera
   (fallo de WCAG 1.4.10 Reflow, en las 38 paginas). No hace falta
   redisenar la barra: basta con que se aplique lo que ya estaba.
   Ampliado a 400px el caso extremo, que es donde el castellano aprieta
   mas: «Pedir cotizacion» corre 8 px mas que «Request a quote». */
@media (max-width:620px){
  /* El logotipo caia en dos lineas y dejaba la cabecera a doble altura,
     descuadrada respecto al boton. El distintivo es decorativo: fuera. */
  .mark .m2{display:none}
  .mark .m1{font-size:1.35rem;white-space:nowrap}
  .mark{padding-right:.75rem}
  .nav-cta{padding-inline:.85rem;font-size:.62rem;letter-spacing:.07em;white-space:nowrap}
  header.nav .wrap{min-height:3.9rem}
  .status .wrap{min-height:auto;padding-block:.4rem}
}
/* «Pedir cotizacion» corre 8 px mas que «Request a quote» y a 320 px se salia
   por 3. Un escalon mas abajo, no un rediseno. */
@media (max-width:400px){
  .nav-cta{padding-inline:.6rem;letter-spacing:.04em}
  .mark{padding-right:.5rem}
}

/* ---------- hero de portada ---------- */
.hero{position:relative;background:var(--night);color:var(--ink);overflow:hidden}
/* Con todo del mismo color, los 48 px de abajo del hero y los 115 de arriba de
   #start se leian como 163 px de nada. El filete hace de eje base de la traza
   y cierra el hero; el segundo recorta el aire a ~80 px (Diego, 16-oct). */
.hero{border-bottom:1px solid var(--rule-soft)}
.hero + section{padding-top:clamp(3rem,6vw,5rem)}
.hero-media{position:absolute;inset:0}
.hero-media img{width:100%;height:100%;object-fit:cover}
/* T180 (QA de Ricardo): por debajo de 900 la escena pisa el párrafo; sin dibujo y sin alt (el picture fuera del árbol). */
@media (max-width:899px){.hero-media picture{display:none}}
/* T180 (QA de Ricardo): con el ancho, la escena crecía hacia el titular. Desde 1441 la caja se queda en
   1440 y pegada a la derecha: el texto corre la mitad de lo que corre la escena. El SVG es transparente. */
@media (min-width:1441px){.hero-media{left:auto;width:1440px}}
.hero-media::after{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(90deg,oklch(var(--night-ch)/.88) 0%,oklch(var(--night-ch)/.78) 45%,oklch(var(--night-ch)/.2) 72%,oklch(var(--night-ch)/.3) 100%),
    linear-gradient(180deg,oklch(var(--night-ch)/.5) 0%,transparent 30%,transparent 80%,oklch(var(--night-ch)/.6) 100%);
}
.hero-guides{position:absolute;inset:0;display:grid;grid-template-columns:repeat(4,1fr);pointer-events:none}
@media (min-width:900px){.hero-guides{grid-template-columns:repeat(12,1fr)}}
.hero-guides span{border-right:1px solid oklch(var(--hl)/.09)}
.hero-guides span:last-child{border-right:none}
.hero .wrap{position:relative;padding-block:clamp(4rem,10vw,9rem) clamp(2rem,4vw,3rem)}
.hero-kicker{color:var(--accent-text);margin-bottom:clamp(1.4rem,3vw,2.2rem)}
h1.hero-h1{font-family:var(--disp);text-transform:uppercase;font-weight:800;font-size:var(--fs-h1);line-height:.83;letter-spacing:.002em;max-width:16ch}
h1.hero-h1 span{color:var(--accent)}
.hero-lower{display:grid;grid-template-columns:1fr;gap:2rem;margin-top:clamp(2rem,4vw,3.2rem);align-items:end}
@media (min-width:900px){.hero-lower{grid-template-columns:minmax(0,1fr) minmax(0,20rem)}}
.hero-lower p.lead{font-size:var(--fs-lead);max-width:52ch;color:var(--band-ink)}
.hero-acts{display:flex;gap:.8rem;flex-wrap:wrap;margin-top:1.7rem}
/* T5 · Hero en móvil (Diego): la tira va en el flujo, entre los botones y la tarjeta; por encima de 900 px manda el
   dibujo de fondo y la tira no se pinta. Decorativa (aria-hidden): el titular y la tarjeta ya lo dicen. */
.hero-tira{margin-top:1.8rem}
.hero-tira img{display:block;width:100%;max-width:34rem;height:auto}
@media (min-width:900px){.hero-tira{display:none}}
.hero-card{border:1px solid oklch(var(--hl)/.24);padding:1.15rem 1.25rem 1.3rem;
  background:oklch(var(--night-ch)/.85)}   /* T177 QA (Ricardo): la pila y la traza del hero pasan por detrás */
.hero-card .meta{color:var(--accent-text)}
.hero-card dl{margin:.85rem 0 0;display:grid;gap:.55rem}
.hero-card div{display:flex;justify-content:space-between;gap:1rem;border-bottom:1px dotted oklch(var(--hl)/.2);padding-bottom:.45rem}
.hero-card dt{color:var(--band-ink-2);font-size:.84rem}
.hero-card dd{margin:0;font-weight:600;font-size:.9rem}
.btn{
  display:inline-flex;align-items:center;gap:.6rem;text-decoration:none;cursor:pointer;
  font-size:.75rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  padding:1rem 1.6rem;border:1px solid currentColor;background:none;
  transition:background-color .2s cubic-bezier(.22,1,.36,1),color .2s cubic-bezier(.22,1,.36,1);
}
.btn-signal{background:var(--accent-bg);border-color:var(--accent-bg);color:var(--accent-on)}
.btn-signal:hover,.btn-signal:focus-visible{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.btn-ink{background:var(--accent-bg);border-color:var(--accent-bg);color:var(--accent-on)}
.btn-ink:hover,.btn-ink:focus-visible{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.btn-line{color:inherit}
.btn-line:hover,.btn-line:focus-visible{background:currentColor}
.btn-line:hover span,.btn-line:focus-visible span{color:var(--night)}
.btn-line-ink:hover,.btn-line-ink:focus-visible{background:var(--ink);color:var(--paper)}
.btn-line-ink:hover span,.btn-line-ink:focus-visible span{color:var(--paper)}

/* ---------- cabecera de página interior ---------- */
/* T164 · A1 (Diego): .phead es un <section> y le caía también section{padding-block},
   115 px de más arriba y abajo; el texto de la ficha quedaba bajo el pliegue. */
.phead{background:var(--band);color:var(--band-ink);position:relative;overflow:hidden;padding-block:0}
.phead .wrap{position:relative;padding-block:clamp(2.6rem,6vw,5rem) clamp(2.2rem,5vw,4rem)}
.phead .hero-guides span{border-right-color:oklch(var(--hl)/.07)}
.phead .kicker{color:var(--accent-text);margin-bottom:1rem}
.phead h1{
  font-family:var(--disp);text-transform:uppercase;font-weight:800;
  font-size:var(--fs-h1s);line-height:.85;letter-spacing:.002em;max-width:18ch;
}
.phead p.lead{margin-top:1.4rem;font-size:var(--fs-lead);max-width:58ch;color:var(--band-ink)}
.phead .phead-facts{
  display:flex;flex-wrap:wrap;gap:0 2.5rem;margin-top:1.8rem;padding-top:1.1rem;
  border-top:1px solid oklch(var(--hl)/.22);
}
.phead .phead-facts div{padding-block:.5rem}
.phead .phead-facts dt{font-size:var(--fs-meta);font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--band-ink-2)}
.phead .phead-facts dd{margin:.3rem 0 0;font-family:var(--disp);text-transform:uppercase;font-weight:700;font-size:1.5rem;line-height:1}

/* ---------- migas ---------- */
.crumbs{border-bottom:1px solid var(--rule);background:var(--paper)}
.crumbs ol{
  /* T164 · B1: sin padding-inline, la lista conservaba su sangría y las migas
     empezaban 40 px a la derecha del título. */
  list-style:none;margin:0;padding-block:.75rem;padding-inline:0;display:flex;flex-wrap:wrap;gap:.45rem;
  font-size:var(--fs-meta);font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-2);
}
.crumbs a{text-decoration:none;display:inline-block;padding-block:.42rem;margin-block:-.42rem}
.crumbs a:hover{color:var(--ink);text-decoration:underline}
.crumbs li + li::before{content:"/";margin-right:.45rem;color:var(--rule)}
.crumbs [aria-current="page"]{color:var(--ink)}

/* ---------- estructura de sección ---------- */
section{padding-block:var(--sec)}
section.tight{padding-top:0}
.sec-head{
  display:grid;grid-template-columns:1fr;gap:1rem;align-items:end;
  border-bottom:1px solid var(--rule-strong);padding-bottom:1.4rem;margin-bottom:clamp(2rem,4vw,3.2rem);
}
@media (min-width:900px){.sec-head{grid-template-columns:5.5rem minmax(0,1fr) minmax(0,26rem);gap:2.5rem}}
.sec-head .idx{font-size:var(--fs-meta);font-weight:700;letter-spacing:.16em;color:var(--ink-2)}
.sec-head h2{font-family:var(--disp);text-transform:uppercase;font-weight:700;font-size:var(--fs-h2);line-height:.85;letter-spacing:.004em}
.sec-head .aside{color:var(--ink-2);font-size:.98rem;line-height:1.5}

/* ---------- los tres caminos (portada) ---------- */
.paths{display:grid;grid-template-columns:1fr;border-top:1px solid var(--rule-strong);border-left:1px solid var(--rule)}
@media (min-width:980px){.paths{grid-template-columns:repeat(3,1fr)}}
.path{
  display:flex;flex-direction:column;gap:.9rem;text-decoration:none;
  padding:1.7rem 1.6rem 1.9rem;border-bottom:1px solid var(--rule);border-right:1px solid var(--rule);
  transition:background-color .2s cubic-bezier(.22,1,.36,1);
}
.path:hover,.path:focus-visible{background:var(--paper-2)}
.path .pq{font-size:.95rem;color:var(--ink-2);font-style:italic;max-width:34ch}
.path h3{font-family:var(--disp);text-transform:uppercase;font-weight:800;font-size:clamp(1.9rem,3vw,2.5rem);line-height:.88;letter-spacing:.004em}
.path ul{list-style:none;margin:0;padding:0;display:grid;gap:.42rem;font-size:.93rem;color:var(--ink-2)}
.path li{padding-left:1rem;position:relative}
.path li::before{content:"";position:absolute;left:0;top:.62em;width:.42rem;height:1px;background:var(--accent-text)}
.path .pfoot{
  margin-top:auto;padding-top:1.1rem;border-top:1px dotted var(--rule);
  display:flex;justify-content:space-between;align-items:baseline;gap:1rem;flex-wrap:wrap;
}
.path .pprice{font-size:.85rem;font-weight:700}
.path .pprice.q{font-weight:500;color:var(--ink-2)}
.path .pgo{font-size:var(--fs-meta);font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--accent-text)}
.path:hover .pgo{text-decoration:underline}

/* Enlace a la seccion de agentes bajo los tres caminos (16-oct). Provisional:
   la posicion la decide Diego. */
.paths-more{display:flex;align-items:center;gap:.7rem;flex-wrap:wrap;margin-top:1.3rem;font-size:.95rem;font-weight:600}
.paths-more a{color:var(--accent-text);text-underline-offset:.18em}
.paths-more a:hover{color:var(--ink)}
/* Botones en fila que se apilan en movil. gap, no margin-left en el segundo:
   el margen se quedaba al apilar y sangraba «Call» 9,6 px a 390 (Diego). */
.acts{display:flex;flex-wrap:wrap;gap:.6rem;align-items:flex-start}
.prose .acts .btn{margin-top:0}

/* ---------- grupos de cobertura (los tres caminos) ---------- */
.covgroup + .covgroup{margin-top:clamp(2.4rem,4vw,3.4rem)}
.covgroup-h{
  font-family:var(--disp);text-transform:uppercase;font-weight:800;
  font-size:clamp(1.7rem,2.6vw,2.2rem);line-height:.9;letter-spacing:.004em;
}
.covgroup-q{margin-top:.5rem;margin-bottom:1.1rem;color:var(--ink-2);font-size:.98rem;font-style:italic;max-width:60ch}
/* Cada grupo llena su fila exacta: 4, 5 y 1. Sin fila huerfana. */
@media (min-width:1120px){.covgroup .coverage{grid-template-columns:repeat(var(--cols),1fr)}}

/* ---------- bloques de cobertura ---------- */
.coverage{display:grid;grid-template-columns:1fr;border-top:1px solid var(--rule);border-left:1px solid var(--rule)}
@media (min-width:640px){.coverage{grid-template-columns:1fr 1fr}}
@media (min-width:1120px){.coverage{grid-template-columns:repeat(5,1fr)}}
.cov{
  padding:1.35rem 1.4rem 1.5rem;border-bottom:1px solid var(--rule);border-right:1px solid var(--rule);
  display:flex;flex-direction:column;gap:.55rem;text-decoration:none;
  transition:background-color .2s cubic-bezier(.22,1,.36,1);
}
.cov:hover,.cov:focus-visible{background:var(--paper-2)}
.cov.is-new{background:var(--band);color:var(--band-ink)}
.cov.is-new:hover,.cov.is-new:focus-visible{background:var(--paper-3)}
.cov.is-new .cov-id{color:var(--band-ink-2)}
.cov.is-new p{color:var(--band-ink-2)}
.cov.is-new .price{border-top-color:oklch(var(--hl)/.28);color:var(--accent-text)}
.cov.is-new .price.q{color:var(--band-ink-2)}
.cov.is-new .chip{border-color:var(--band-ink)}
.cov-top{display:flex;justify-content:space-between;align-items:center;gap:1rem}
.cov-id{font-size:var(--fs-meta);font-weight:700;letter-spacing:.16em;color:var(--ink-2)}
.chip{
  font-size:.6rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  padding:.24rem .5rem;border:1px solid var(--rule-strong);line-height:1;white-space:nowrap;
}
.chip.on{background:var(--accent-bg);border-color:var(--accent-bg);color:var(--accent-on)}
.chip.new{background:var(--ink);color:var(--paper)}
.cov h3{font-family:var(--disp);text-transform:uppercase;font-weight:700;font-size:1.55rem;line-height:.92;letter-spacing:.005em}
.cov p{color:var(--ink-2);font-size:.93rem;line-height:1.5}
.cov .price{margin-top:auto;padding-top:.85rem;border-top:1px dotted var(--rule);font-size:.82rem;font-weight:600}
.cov .price.q{color:var(--ink-2);font-weight:500}

/* ---------- tabla de tarifas ---------- */
/* T047 → T053. La tabla se cortaba en movil sin decirlo, y yo puse un aviso
   de arrastre con umbral. Diego lo resolvio de raiz en T053: la tabla no era
   grande, era RIGIDA —.desc con min-width y .fig/.dur con nowrap la clavaban
   en 848 px cupiese o no—. Soltando esas reglas se aprieta un 34% y por
   debajo de 38rem se apila. Medido: 0 px de arrastre en 114 comprobaciones,
   19 anchos x 6 paginas x 2 idiomas.
   Asi que el aviso, el umbral de 59rem y las 4.640 comprobaciones que lo
   validaban se van enteros: no queda arrastre del que avisar. Se quedan la
   .tablezone y el @container porque T053 los usa para decidir cuando relajar
   y cuando apilar — o sea que el andamio si sirvio, y ahora sostiene otra
   cosa.
   Lo que aprendimos y no se tira: un aviso permanente no es un aviso, es un
   sintoma. Lo dijo Alicia cuando el aviso salia siempre en las dos paginas de
   IA, y tenia razon: la senal de que el umbral no era el problema. */
.tablezone{container-type:inline-size}
table.rates{width:100%;border-collapse:collapse;min-width:44rem;font-size:.96rem}
table.rates th,table.rates td{text-align:left;padding:1.05rem 1.15rem;border-bottom:1px solid var(--rule);vertical-align:top}
table.rates thead th{
  background:var(--band);color:var(--band-ink);font-size:var(--fs-meta);font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;border-bottom:none;white-space:nowrap;
}
/* La ultima fila YA NO pierde el filete: la regla solo se lo quitaba a los
   <td> y el <th> de la fila lo conservaba, asi que quedaban 150 px de filete
   colgando bajo la primera columna (Diego, 16-oct). Toda la fila lo lleva. */
table.rates tbody tr:hover{background:var(--paper-2)}
table.rates .svc{font-family:var(--disp);text-transform:uppercase;font-weight:700;font-size:1.3rem;line-height:.95;letter-spacing:.005em}
table.rates .svc a{text-decoration:none}
table.rates .svc a:hover{text-decoration:underline;text-decoration-thickness:2px}
table.rates .fig{font-weight:700;white-space:nowrap;font-size:1.02rem}
table.rates .dur{color:var(--ink-2);white-space:nowrap;font-size:.9rem}
table.rates .desc{color:var(--ink-2);font-size:.92rem;min-width:20rem}
table.rates tr.pick td,table.rates tr.pick th{background:oklch(var(--accent-ch)/.16)}
/* El rótulo va en el marcado, no en content: — se traduce sin tocar el CSS. */
.svc-note{
  display:block;font-family:var(--sans);font-size:.55rem;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--accent-text);margin-top:.4rem;
}
.rates-foot{margin-top:1.1rem;color:var(--ink-2);font-size:.92rem;max-width:66ch}

/* T053 — DEJAR DE ARRASTRAR, EN VEZ DE AVISAR DE QUE SE ARRASTRA.
   Gate de Alicia, y es el correcto: que cada precio se lea ENTERO, sin
   desplazamiento horizontal, en los dos idiomas. No "que salga el aviso".

   Lo que fallaba no era el tamano de la tabla, era su RIGIDEZ: .desc con
   min-width:20rem y .fig/.dur con white-space:nowrap la clavaban en 848 px
   cupiese o no. Medido el ancho min-content de las SEIS tablas, tal cual y
   soltando esas tres reglas:
         /            848 -> 556      /es/            856 -> 555
         /services/   848 -> 556      /es/services/   856 -> 555
                      886 -> 545                      935 -> 591
   O sea que se aprietan un 34% sin tocar el contenido. La mas ancha relajada
   son 591 px.

   De ahi los dos umbrales, que ahora se derivan de una medida y no se eligen:
     <=59rem (944)  se relaja  -> la mas ancha rigida son 935, asi que por
                                 encima cabe rigida; por debajo cabe relajada
                                 desde 608.
     <=38rem (608)  se apila   -> ni relajada cabe (591 + margen). Ahi una
                                 tabla de cuatro columnas no es una tabla.
   Resultado: CERO arrastre horizontal a cualquier ancho, luego el precio se
   lee entero siempre, y por eso ya no hay nada de lo que avisar ni que
   arrastrar. Remedido por mi a doce anchos de 320 a 1920 en los dos idiomas:
   0 px de arrastre en todos. Retirados el aviso, su cadena, el umbral de
   59rem y el tab stop del marco — el nombre accesible se queda, pero ya no
   dice «se desplaza en horizontal», porque no. Leo, 2026-09-05. */
@container (max-width:59rem){
  table.rates{min-width:0}
  table.rates .desc{min-width:0}
  table.rates .fig,table.rates .dur{white-space:normal}
  }

/* Apilada. El precio sube al segundo lugar, detras del nombre: es lo que el
   comprador viene a buscar y era justo lo que se caia por la derecha. Las
   etiquetas salen de data-l, que ya viene traducido de la plantilla. */
@container (max-width:38rem){
  .tablewrap{overflow-x:visible;border:none}
  table.rates{display:block;font-size:1rem}
  table.rates thead{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
  table.rates tbody{display:block}
  table.rates tr{display:flex;flex-direction:column;border:1px solid var(--rule-strong);padding:1.1rem 1.15rem 1.25rem}
  table.rates tr + tr{margin-top:.85rem}
  table.rates tbody tr:hover{background:none}
  table.rates th,table.rates td{display:block;padding:0;border-bottom:none}
  table.rates .svc{order:1;font-size:1.45rem}
  table.rates .fig{order:2;margin-top:.45rem;font-family:var(--disp);font-size:1.5rem;line-height:1.06;letter-spacing:.004em}
  table.rates .dur{order:3;margin-top:.55rem}
  table.rates .desc{order:4;margin-top:.6rem}
  table.rates .fig::before,table.rates .dur::before{
    content:attr(data-l);display:block;margin-bottom:.15rem;
    font-family:var(--sans);font-size:var(--fs-meta);font-weight:700;
    letter-spacing:.14em;text-transform:uppercase;color:var(--ink-2);
  }
  table.rates tr.pick td,table.rates tr.pick th{background:none}
  table.rates tr.pick{background:oklch(var(--accent-ch)/.16)}
}



/* ---------- lo que cambia ---------- */
.swaps{border-top:1px solid var(--rule-strong)}
.swap{display:grid;grid-template-columns:1fr;gap:.5rem;padding-block:1.4rem;border-bottom:1px solid var(--rule)}
@media (min-width:900px){.swap{grid-template-columns:1fr 1fr;gap:3rem;align-items:start}}
.swap .before,.swap .after{display:flex;gap:.85rem;align-items:flex-start}
.swap .tagl{
  flex:none;font-size:.58rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  padding:.24rem .45rem;line-height:1;margin-top:.28rem;
}
/* «Before» en contorno, no en --alert: era el unico color calido de la portada y
   leia como error (Diego, 16-oct). --alert queda para formulario e .internal. */
.swap .before .tagl{background:transparent;border:1px solid var(--rule-soft);color:var(--ink-2)}
.swap .after .tagl{background:var(--accent-bg);color:var(--accent-on)}
.swap .before p{color:var(--ink-2)}
.swap .after p{font-weight:600}

/* ---------- proceso ---------- */
.process{display:grid;grid-template-columns:1fr;border-top:1px solid var(--rule-strong)}
@media (min-width:880px){.process{grid-template-columns:repeat(3,1fr)}}
.pstep{padding:1.7rem 1.5rem 1.9rem;border-bottom:1px solid var(--rule);border-right:1px solid var(--rule);position:relative}
.pstep:last-child{border-right:none}
.pstep .pn{font-family:var(--disp);font-size:clamp(3rem,5.5vw,4.4rem);font-weight:800;line-height:.8;color:var(--ink-3)}
.pstep h3{font-family:var(--disp);text-transform:uppercase;font-weight:700;font-size:1.75rem;line-height:.92;margin-top:.9rem}
.pstep p{margin-top:.7rem;color:var(--ink-2);font-size:.95rem;max-width:36ch}
.pstep .deliv{
  margin-top:1.2rem;padding-top:.75rem;border-top:1px solid var(--rule);
  font-size:var(--fs-meta);font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--accent-text);
}

/* ---------- clientes ---------- */
/* ---------- banda tecnica: el circuito del agente supervisado ----------
   El SVG trae fondo #eef0f2, que es exactamente --paper, asi que se funde
   con la pagina y no necesita marco. Retrato por debajo de 720 px. */
/* Banda de superficie a todo el ancho (Diego, 16-oct): sin precio en la 02, de
   #start a #clients eran ~3.580 px seguidos de marino. El panel del SVG es
   #0d1a3d, el mismo color, asi que se funde y solo queda el filete del <img>. */
.techband{margin:0;padding-block:clamp(2.5rem,6vw,5rem) clamp(2.5rem,6vw,4rem);background:var(--paper-2)}
/* La seccion que sigue es .tight (sin padding-top) y antes se apoyaba en el
   aire de la banda; con fondo propio el titulo quedaba pegado al borde. Mismo
   aire que bajo el hero. */
.techband + section.tight{padding-top:clamp(3rem,6vw,5rem)}
.techband .meta{color:var(--ink-2);margin-bottom:1rem}
.techband img{width:100%;height:auto;border:1px solid var(--rule-soft)}
.techband figcaption{
  margin-top:1rem;max-width:58ch;color:var(--ink-2);font-size:.95rem;
}

/* T040: sin filtro y sin velo. saturate/contrast/brightness son correccion
   de fotografia: existen para domar una imagen cuyos niveles no controlas.
   Los de esta trama van escritos dentro del SVG (blancos .045-.11, verde .10),
   asi que el filtro corregia dos veces y borraba las tres bandas verdes
   (delta 30 -> 7 contra su fondo). El velo tampoco hacia falta: sin el,
   .cn lee 12,2:1 y el .aside 8,4:1 sobre el pixel mas claro de la trama.
   Lo que si hacia falta era opacar las celdas (/.34 -> /.93): con la trama
   a su fuerza real, las filas tabulares cruzaban POR DENTRO del registro y
   leian como subrayados, y las bandas verdes caian sobre clientes concretos
   como si los marcasen. Opacas, la trama vuelve a estar detras. */
.clients{position:relative;color:var(--ink);background:var(--paper-2);overflow:hidden}
.clients .wrap{position:relative}
.clients .sec-head{border-bottom-color:oklch(var(--hl)/.35)}
.clients .sec-head .idx,.clients .sec-head .aside{color:var(--band-ink-2)}
/* minmax(0,1fr) y no `1fr` a secas, por la misma razon que .layout veinte
   lineas mas abajo: `1fr` es minmax(auto,1fr) y propaga el ancho min-content
   de la celda al grid. Con «Anheuser-Busch InBev» o «Nanosegundos S&I» en
   Big Shoulders a 1.45rem, a 320 px cada celda pedia 187 px y las dos
   columnas desbordaban la pagina. El nombre propio puede partirse antes que
   romper el ancho de la pagina: los clientes se leen igual en dos lineas. */
.ledger{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));border-top:1px solid oklch(var(--hl)/.3);border-left:1px solid oklch(var(--hl)/.3)}
/* Una columna por debajo de 380 px. Medido: la palabra más larga sin guion es
   «Nanosegundos», 120 px a 1.45rem, y con el padding de celda dos columnas
   necesitan 348 px de contenido. Por debajo de eso, o se parten nombres de
   cliente o se encoge el nombre a 1.05rem —un 28% menos— y el registro pierde
   la voz que justifica la sección. Se paga en scroll, que es lo barato. */
@media (max-width:379px){.ledger{grid-template-columns:minmax(0,1fr)}}
@media (min-width:760px){.ledger{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (min-width:1140px){.ledger{grid-template-columns:repeat(4,minmax(0,1fr))}}
.ledger div{
  padding:1.05rem 1.1rem 1.15rem;border-right:1px solid oklch(var(--hl)/.3);border-bottom:1px solid oklch(var(--hl)/.3);
  background:oklch(var(--night-ch)/.93);
}
/* SIN hyphens en el nombre del cliente, a diferencia de .cs. Partir
   «infraestructura» no cuesta nada; partir NANOSE-GUNDOS o HARMONY
   DEVELOP-MENT CENTER sí, en la sección cuyo argumento es que estos son los
   que responden por nosotros. break-word se queda solo como red: no debería
   dispararse nunca con la columna única de abajo. */
.ledger .cn{font-family:var(--disp);text-transform:uppercase;font-weight:700;font-size:1.45rem;line-height:.95;letter-spacing:.005em;overflow-wrap:break-word}
.ledger .cs{
  margin-top:.4rem;font-size:.68rem;font-weight:600;letter-spacing:.11em;text-transform:uppercase;
  color:var(--band-ink-2);
  /* «Infraestructura de telecomunicaciones» tiene una palabra de 18 letras que
     no cabe en la celda a 320 px. hyphens:auto parte por silabas (el lang esta
     puesto en <html>) y break-word es la red por si el idioma no tiene patron. */
  hyphens:auto;overflow-wrap:break-word;
  /* T163: nada de cortes que dejen 2 letras («AD-», «CAR-GA», «MÉ-DICOS»).
     6 3 3 = palabra de 6 letras como mínimo para partir y al menos 3 a cada lado.
     Chromium y Firefox usan hyphenate-limit-chars; Safari, los -webkit-. */
  hyphenate-limit-chars:6 3 3;-webkit-hyphenate-limit-before:3;-webkit-hyphenate-limit-after:3;
}

/* ---------- prosa de página interior ---------- */
/* minmax(0,1fr) y min-width:0, no `1fr` a secas: la tabla de tarifas tiene
   min-width:44rem y en una columna `1fr` (= minmax(auto,1fr)) esa medida
   minima se propaga al grid y desborda la pagina en movil, aunque .tablewrap
   tenga su propio overflow-x. */
.layout{display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(2.5rem,5vw,4.5rem)}
@media (min-width:1000px){.layout{grid-template-columns:minmax(0,1fr) minmax(0,20.5rem)}}
/* La medida de lectura la fijan los HIJOS, no `.prose`. Antes la fijaba el
   contenedor, y eso metia la tabla de tarifas de IA en 678 px: se cortaba 172 px
   a 1440 y la columna PRICE salia partida por la mitad —"$10" donde pone
   "$10,000 to $30,000"—, que no es un precio oculto, es un precio FALSO. La
   misma tabla en el wrap ancho de /services/ y de portada cabe sin tocarla.
   Asi cualquier contenido ancho futuro (tabla, figura, bloque de codigo) se
   sale de la medida sin necesitar un caso especial cada vez. */
.prose{max-width:none;min-width:0}
.prose > *{max-width:var(--prose)}
.prose > .tablezone{max-width:none}
.prose > * + *{margin-top:1.15rem}
.prose h2{
  font-family:var(--disp);text-transform:uppercase;font-weight:700;font-size:var(--fs-h2s);
  line-height:.9;letter-spacing:.004em;margin-top:clamp(2.4rem,4vw,3.4rem);
  padding-top:1.1rem;border-top:1px solid var(--rule-strong);
}
.prose h2:first-child{margin-top:0;border-top:none;padding-top:0}
.prose h3{font-family:var(--disp);text-transform:uppercase;font-weight:700;font-size:1.45rem;line-height:.95;margin-top:2rem}
.prose p{color:var(--ink)}
.prose p.lead{font-size:var(--fs-lead);line-height:1.5}
/* :not(.btn) — si no, `.prose a` (0,1,1) gana a `.btn-ink` (0,1,0) y el boton
   sale tinta sobre tinta, invisible. */
.prose a:not(.btn){color:var(--ink);text-decoration-thickness:1px;text-underline-offset:.18em}
.prose a:not(.btn):hover{background:var(--accent-bg);color:var(--accent-on);text-decoration:none}
.prose .btn{text-decoration:none;margin-top:.4rem}
.prose ul,.prose ol{margin-block:1.15rem;padding-left:0;list-style:none;display:grid;gap:.55rem}
.prose ul li{padding-left:1.35rem;position:relative;color:var(--ink-2)}
.prose ul li::before{content:"";position:absolute;left:0;top:.66em;width:.7rem;height:1px;background:var(--accent-text)}
.prose ol{counter-reset:n}
.prose ol li{padding-left:2.1rem;position:relative;counter-increment:n;color:var(--ink-2)}
.prose ol li::before{
  content:counter(n,decimal-leading-zero);position:absolute;left:0;top:0;
  font-size:var(--fs-meta);font-weight:700;letter-spacing:.1em;color:var(--accent-text);line-height:1.9;
}
.prose strong{font-weight:700;color:var(--ink)}

/* especificación en dos columnas: lo que en el sitio de 2019 era una lista suelta */
.spec{border-top:1px solid var(--rule-strong);margin-top:clamp(2.4rem,4vw,3.4rem)}
.specrow{display:grid;grid-template-columns:1fr;gap:.4rem 2.5rem;padding-block:1.05rem;border-bottom:1px solid var(--rule)}
@media (min-width:720px){.specrow{grid-template-columns:minmax(0,15rem) minmax(0,1fr)}}
.specrow dt{font-family:var(--disp);text-transform:uppercase;font-weight:700;font-size:1.25rem;line-height:.98;letter-spacing:.005em}
.specrow dd{margin:0;color:var(--ink-2);font-size:.95rem}

/* ---------- «Un equipo de agentes para cada persona» (16-oct) ----------
   Dentro de .prose de AI Agent Services. PROVISIONAL: parte de la idea 2 de
   las maquetas de Diego para el post (la lista, que aguanta 390 px mejor que
   la orbita). Sin imagenes ni avatares: la tarjeta es HTML y se traduce. */
.prose > .team{max-width:none}
.team > * + *{margin-top:1.15rem}
.team > h2{
  font-family:var(--disp);text-transform:uppercase;font-weight:700;font-size:var(--fs-h2s);
  line-height:.9;letter-spacing:.004em;margin-top:clamp(2.4rem,4vw,3.4rem);
  padding-top:1.1rem;border-top:1px solid var(--rule-strong);
}
.team > .lead{font-size:var(--fs-lead);line-height:1.5;max-width:var(--prose)}
.team-shift{margin-top:0}
/* Etiqueta ENCIMA del texto a cualquier ancho. La .specrow general pone la
   etiqueta en una columna de 15rem, que apretaba el texto (Lola, 16-oct). */
.team-shift .specrow{grid-template-columns:minmax(0,1fr);gap:.35rem}
.team-shift .specrow dd{max-width:var(--prose)}
.team > p{max-width:var(--prose)}
/* La orbita a todo el ancho de la columna, sin caja: el SVG es transparente y
   se apoya en --paper (Diego, 16-oct). Texto en una columna debajo. */
.team > .team-orbit{display:block;margin-block:2rem}
.team-orbit img{width:100%;height:auto}
/* Credito de la plataforma bajo la orbita (especificacion de Diego, 16-oct).
   `.prose .platform` delante para ganar a `.prose p` y `.prose a:not(.btn)`,
   que si no pisan el color de la atribucion y del enlace. */
.platform{display:grid;grid-template-columns:auto 1fr;column-gap:.85rem;row-gap:.6rem;align-items:center;margin-top:1.1rem;padding-top:1.1rem;border-top:1px solid var(--rule-soft)}
.platform img{width:44px;height:44px}
/* El Antes/Lo siguiente se apoyaba en el margen de la orbita; con el credito
   en medio, su filete quedaba pegado a la atribucion. */
.team > .platform + .team-shift{margin-top:2rem}
.platform .meta{display:block;color:var(--ink-2);margin:0 0 .15rem}
.platform b{font-size:1.25rem;font-weight:700;letter-spacing:-.02em;line-height:1.1}
.prose .platform p{grid-column:1/-1;margin:0;font-size:.85rem;line-height:1.45;color:var(--ink-2)}
.prose .platform a:not(.btn){color:var(--accent-text)}
@media (min-width:760px){.platform{grid-template-columns:auto auto 1fr;column-gap:1rem}.prose .platform p{grid-column:auto;padding-left:1rem;border-left:1px solid var(--rule-soft)}}
.team-slot{border:1px dashed var(--alert-text);color:var(--alert-text);padding:1.2rem;font-size:.8rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase}

/* aparato lateral */
.rail{display:grid;gap:1.5rem;align-content:start}
@media (min-width:1000px){.rail{position:sticky;top:6rem}}
.card{border:1px solid var(--rule-strong);padding:1.25rem 1.3rem 1.4rem}
.card.solid{background:var(--band);color:var(--band-ink);border-color:var(--rule)}
.card.solid h2,.card.solid .meta{color:var(--accent-text)}
.card.solid a:not(.btn){color:var(--band-ink)}  /* :not(.btn): si no, el boton signal sale papel sobre chartreuse, 1.23:1 */
.card h2{font-size:var(--fs-meta);font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-2)}
.card ul{list-style:none;margin:.9rem 0 0;padding:0;display:grid;gap:.05rem}
/* flex-wrap: en castellano el par etiqueta/valor no cabe a 320 px («Todas las
   lineas de servicio» + «Desde $1.800 / mes») y el valor se salia de la
   pagina. Envuelto, el valor cae debajo y se alinea a la izquierda. */
.card li a{
  display:flex;justify-content:space-between;gap:.15rem .8rem;align-items:baseline;flex-wrap:wrap;
  padding:.55rem 0;border-top:1px solid var(--rule);text-decoration:none;font-size:.93rem;
}
.card.solid li a{border-top-color:oklch(var(--hl)/.2)}
.card li a:hover{color:var(--accent-text)}
.card.solid li a:hover{color:var(--accent-text)}
.card li a[aria-current="page"]{font-weight:700}
.card li a .t{font-size:var(--fs-meta);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2);flex:none}
.card.solid li a .t{color:var(--band-ink-2)}
.card p{margin-top:.8rem;font-size:.93rem;color:var(--ink-2)}
.card.solid p{color:var(--band-ink-2)}
.card .btn{margin-top:1.1rem;width:100%;justify-content:center}
.card .bigphone{
  display:block;margin-top:.5rem;font-family:var(--disp);text-transform:uppercase;font-weight:800;
  font-size:1.9rem;line-height:1;text-decoration:none;
}
.card .bigphone:hover{color:var(--accent-text)}

/* ---------- formulario ---------- */
.form{display:grid;gap:1.15rem;max-width:38rem}
.field{display:grid;gap:.4rem}
.field label{font-size:var(--fs-meta);font-weight:700;letter-spacing:.14em;text-transform:uppercase}
.field .hint{font-size:.85rem;color:var(--ink-2);letter-spacing:0;text-transform:none;font-weight:400}
.field .req{color:var(--alert-text)}
.field input,.field select,.field textarea{
  font-family:inherit;font-size:1rem;color:var(--ink);background:var(--paper);
  border:1px solid var(--ink);padding:.8rem .9rem;width:100%;border-radius:0;
}
.field textarea{min-height:9rem;resize:vertical}
.field select{appearance:none;background-image:linear-gradient(45deg,transparent 49%,var(--ink) 50%),linear-gradient(-45deg,transparent 49%,var(--ink) 50%);background-position:calc(100% - 1.15rem) 1.35rem,calc(100% - .8rem) 1.35rem;background-size:.4rem .4rem;background-repeat:no-repeat;padding-right:2.6rem}
.field input:focus,.field select:focus,.field textarea:focus{outline:2px solid var(--accent-text);outline-offset:1px}
.hp{position:absolute;left:-9999px}
.form-note{font-size:.9rem;color:var(--ink-2);max-width:52ch}
.form-note a{color:var(--ink)}
/* Sin border-left de acento: un filete lateral de color es decoracion que
   finge jerarquia. El filete va debajo, donde si separa algo: la promesa
   del formulario. Arriba no separaba nada, era el principio de la columna. */
.promise{
  border-bottom:1px solid var(--rule-strong);padding:0 0 1.3rem;
  display:grid;gap:.55rem;margin-bottom:1.6rem;max-width:60ch;
}
.promise p{font-size:.95rem;color:var(--ink-2)}
.promise p strong{color:var(--ink)}

/* ---------- CTA ---------- */
.cta{background:var(--accent-bg);color:var(--accent-on)}
.cta-top{display:grid;grid-template-columns:1fr;gap:clamp(1.6rem,3vw,2.6rem);align-items:end}
@media (min-width:960px){.cta-top{grid-template-columns:minmax(0,1.35fr) minmax(0,.65fr)}}
.cta h2{font-family:var(--disp);text-transform:uppercase;font-weight:800;font-size:var(--fs-h2);line-height:.85}
/* .cta-top p y no .cta p: a secas (0,2,0) le ganaba a .crail-v y a .crail-n
   (0,1,0) y le metia tamano de lead al valor y a la nota del rail. */
.cta-top p{margin-top:1.1rem;max-width:46ch;font-size:var(--fs-lead);color:var(--accent-on)}
.cta .btn{justify-self:start;border-color:var(--accent-on)}
@media (min-width:960px){.cta .btn{justify-self:end}}
.cta .btn:hover{background:var(--ink);color:var(--paper)}

/* ---------- rail de contacto (emplazamiento 04, T041) ----------
   No hay fotografia del Weston Business Center y no la va a haber. El
   edificio ademas es un business center: una foto probaria que hay un
   edificio, no que hay una empresa. La prueba que busca un director de IT
   no es visual, es comprobable: un numero al que llamar, una puerta con
   numero de suite, un huso horario. El tipo hace el trabajo que iba a
   hacer la foto, a tamano de senaletica.
   line-height 1.06 y no <1: en /es/ las mayusculas acentuadas de Big
   Shoulders se solapan por debajo de 1.10 y aqui el valor puede crecer. */
.crail{
  --crail-mute:var(--ink-2);
  --crail-rule:var(--rule);
  display:grid;grid-template-columns:1fr;gap:0 clamp(1.5rem,3vw,3rem);
  border-top:2px solid currentColor;margin-top:clamp(2.2rem,4.5vw,3.4rem);
}
@media (min-width:720px){.crail{grid-template-columns:repeat(3,1fr)}}
.crail > div{padding-block:1.25rem 1.4rem}
@media (max-width:719px){.crail > div + div{border-top:1px solid var(--crail-rule)}}
.crail .meta{color:var(--crail-mute)}
.crail-v{
  display:block;margin-top:.55rem;font-style:normal;text-decoration:none;
  font-family:var(--disp);text-transform:uppercase;font-weight:700;
  font-size:clamp(1.5rem,2.6vw,2rem);line-height:1.06;letter-spacing:.004em;
}
a.crail-v{
  text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:.16em;
  text-decoration-color:transparent;
  transition:text-decoration-color .2s cubic-bezier(.22,1,.36,1);
}
a.crail-v:hover,a.crail-v:focus-visible{text-decoration-color:currentColor}
.crail-n{margin-top:.7rem;font-size:.92rem;line-height:1.5;color:var(--crail-mute);max-width:32ch}
.cta .crail{--crail-mute:var(--accent-on);--crail-rule:oklch(var(--hl)/.4)}

/* En /contact/ el rail va suelto, sin CTA que lo envuelva: esa pagina no
   necesita un boton de "pedir cotizacion", necesita la prueba. */
.contactband{padding-top:0}
.contactband .crail{margin-top:0}

/* ---------- footer ---------- */
footer{background:var(--paper-2);color:var(--band-ink-2);padding-block:clamp(2.5rem,5vw,4rem)}
footer .wrap{display:grid;gap:2rem;grid-template-columns:1fr}
/* T164 · M6: cuatro grupos de enlaces. Entre 820 y 1099 la marca va en su fila;
   desde 1100, las cinco columnas en una. */
@media (min-width:820px){footer .wrap.cols{grid-template-columns:repeat(4,1fr);gap:2.5rem}
  footer .wrap.cols > div:first-child{grid-column:1 / -1}}
@media (min-width:1100px){footer .wrap.cols{grid-template-columns:1.5fr repeat(4,1fr)}
  footer .wrap.cols > div:first-child{grid-column:auto}}
footer h2{font-size:var(--fs-meta);font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--accent-text);margin-bottom:.9rem}
footer ul{list-style:none;margin:0;padding:0;display:grid;gap:.5rem;font-size:.92rem}
footer a{text-decoration:none}
footer ul a{display:inline-block;padding-block:.28rem;margin-block:-.28rem}
footer a:hover{color:var(--ink)}
footer .mark{padding-block:.3rem}
footer address{font-style:normal;font-size:.92rem;line-height:1.5;margin-top:.9rem}
.partners h2{font-size:var(--fs-meta);font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--accent-text);margin-bottom:.9rem}
.partners{margin-top:clamp(2rem,4vw,3rem);padding-top:1.3rem;border-top:1px solid oklch(var(--hl)/.2)}
.partners .plist{display:flex;flex-wrap:wrap;gap:.6rem 1.6rem;font-size:.92rem}
.partners .plist li{color:var(--band-ink-2)}
.colophon{margin-top:clamp(2rem,4vw,3rem);padding-top:1.2rem;border-top:1px solid oklch(var(--hl)/.2);display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap}
.colophon ul{display:flex;gap:1.4rem;flex-wrap:wrap}
.status a[href^="tel:"]{display:inline-block;padding-block:.45rem;margin-block:-.45rem}

/* ---------- 404 ---------- */
.notfound{padding-block:clamp(4rem,10vw,8rem)}
.notfound h1{font-family:var(--disp);text-transform:uppercase;font-weight:800;font-size:var(--fs-h1s);line-height:.85}
.notfound p{margin-top:1.2rem;max-width:52ch;font-size:var(--fs-lead);color:var(--ink-2)}

@media (prefers-reduced-motion:no-preference){
  .rise{opacity:0;transform:translateY(16px);animation:rise .9s cubic-bezier(.16,1,.3,1) forwards}
  .rise:nth-child(2){animation-delay:.08s}
  .rise:nth-child(3){animation-delay:.16s}
  @keyframes rise{to{opacity:1;transform:none}}
}
@media print{
  .status,header.nav,.cta,.internal,.skip{display:none}
  body{background:#fff;color:#000}
}

/* ============================================================
   Castellano: mayúsculas acentuadas en los titulares condensados.

   Big Shoulders Display con line-height 0.83 deja una caja de línea
   de 125px a 1440; la tinta real de una mayúscula acentuada mide 147,
   y con una Q o una J en la línea de arriba el bloque llega a 166.
   En inglés no se nota porque no hay mayúsculas acentuadas: la tinta
   se queda en 124 contra una caja de 125, o sea que funciona por un
   píxel y por casualidad.

   Márgenes medidos por Diego sobre esta hoja, no estimados:
     .phead h1        lh .85   -21px a 1440, -14px a 834, -10px a 390
     .sec-head h2     lh .85   -17px a 1440
     h1.hero-h1       lh .83   -40px a 1440
     .prose h2        lh .90    -8px
     .pstep h3        lh .92    -4px
     .prose h3        lh .95    -3px
     .phead-facts dd  lh 1.00   -2px
   1.10 es el número al que el margen llega a cero.
   ============================================================ */
:lang(es) h1.hero-h1,
:lang(es) .phead h1,
:lang(es) .sec-head h2,
:lang(es) .cta h2,
:lang(es) .prose h2,
:lang(es) .team > h2,
:lang(es) .prose h3,
:lang(es) .pstep h3,
:lang(es) .cov h3,
:lang(es) .covgroup-h,
:lang(es) .ledger .cn,
:lang(es) .phead-facts dd,
:lang(es) .crail-v{line-height:1.10}

/* ============================================================
   TITULARES EN HOST GROTESK (antes «variante A», en type-a.css; Diego la
   eligio el 2026-10-16 y paso a ser la base).
   Big Shoulders era condensada y en mayusculas; Host Grotesk es ancha y la
   pieza del 15-oct la usa en caja baja, apretada y con interlineado ~1. Por
   eso aqui se quitan las mayusculas y el interlineado de condensada y se
   bajan tamanos. El H1 lo midio Diego: dos lineas en cinco anchos, EN y ES.
   `:root` delante para empatar con el bloque :lang(es) de arriba y ganarle
   por orden.
   ============================================================ */
:root{
  --fs-h1:  clamp(2.9rem, 7.4vw, 6.9rem);
  --fs-h1s: clamp(2.2rem, 5vw, 4.1rem);
  --fs-h2:  clamp(2rem, 4.4vw, 3.6rem);
  --fs-h2s: clamp(1.6rem, 2.8vw, 2.3rem);
}
:root .disp,:root .mark .m1,:root .menu > ul > li > a,:root h1.hero-h1,:root .phead h1,
:root .phead .phead-facts dd,:root .sec-head h2,:root .path h3,:root .covgroup-h,:root .cov h3,
:root table.rates .svc,:root .pstep h3,:root .ledger .cn,:root .prose h2,:root .prose h3,
:root .team > h2,:root .specrow dt,:root .card .bigphone,:root .cta h2,:root .crail-v,:root .notfound h1{
  text-transform:none;font-weight:700;letter-spacing:-.03em;line-height:1.02;
}
:root h1.hero-h1{max-width:15ch;letter-spacing:-.035em;line-height:1}
:root .phead h1{max-width:20ch}
:root .mark .m1{font-size:1.5rem}
:root .path h3{font-size:clamp(1.6rem,2.4vw,2rem)}
:root .covgroup-h{font-size:clamp(1.45rem,2.1vw,1.8rem)}
:root .cov h3{font-size:1.28rem}
:root table.rates .svc{font-size:1.1rem}
:root .pstep h3{font-size:1.45rem}
:root .ledger .cn{font-size:1.12rem}
:root .prose h3{font-size:1.2rem}
:root .specrow dt{font-size:1.05rem}
:root .card .bigphone{font-size:1.6rem}
:root .crail-v{font-size:clamp(1.25rem,2.1vw,1.6rem);line-height:1.15}
:root .phead .phead-facts dd{font-size:1.25rem}
:root .pstep .pn{font-weight:700;letter-spacing:-.04em}
@container (max-width:38rem){:root table.rates .fig{font-size:1.25rem;letter-spacing:-.02em}}

/* T145 C · AI Maestro: nota de la portada y etiqueta de la línea 09 */
.aim-note{max-width:68ch;margin-top:.9rem;color:var(--ink-2);font-size:.95rem}
table.rates .svc .svc-tag{display:block;margin-top:.5rem;font-family:var(--sans);text-transform:none;font-weight:500;font-size:.8rem;line-height:1.35;letter-spacing:0;color:var(--accent-text);text-decoration:underline;text-underline-offset:.18em}
table.rates .svc .svc-tag:hover{color:var(--ink)}

/* T145 B2 · logo (1c). La altura se ata a la mayúscula del nombre en texto de
   antes (1.5rem × 0.70): --hc es el alto del logo en mayúsculas, lo pone el
   SVG. Mismos escalones que el texto: 1.35rem a 620 px y un 9 % menos a
   400 px, donde «Pedir cotización» no deja ni un píxel (medido por Diego). */
.mark svg.logo{display:block;height:calc(var(--hc) * 1.05rem);width:auto;overflow:visible}
@media (max-width:620px){.mark svg.logo{height:calc(var(--hc) * .945rem)}}
@media (max-width:400px){.mark svg.logo{height:calc(var(--hc) * .86rem)}}

/* ---------- T145 A · diagramas con movimiento (1, 2 y 7) ----------
   Van en línea (build.py + diagramas/). Todo acotado a svg.dg: las clases
   cortas de la maqueta (.box, .m, .h…) no pueden tocar el resto del sitio.
   La figura elige orientación por su propio ancho, no por la ventana: la
   apaisada solo mientras su texto de 13 px no baje de 11 px reales
   (1240 × 0,85 = 1054 px); por debajo, la de retrato, que mide 320 de ancho
   y a 320 px de pantalla deja el texto pequeño en ~11 px (el SVG fijo de
   antes lo dejaba en ~8,5). Sin movimiento se ve el fotograma completo. */
.dgm{margin:2rem 0;background:var(--paper-2);container-type:inline-size;border:1px solid var(--rule-soft)}
.techband .dgm{margin:0}
.dgm svg.dg{display:block;width:100%;height:auto}
/* con svg.dg delante: si no, la regla de arriba (más específica) las enseña las dos */
.dgm svg.dg.svg-p{display:none}
@container (max-width:1053px){
  .dgm svg.dg.svg-l{display:none}
  .dgm svg.dg.svg-p{display:block;max-width:460px;margin:0 auto}
}
.dgm figcaption{font-size:.82rem;color:var(--ink-2);padding:.9rem 1rem;max-width:68ch;border-top:1px solid var(--rule-soft)}
svg.dg text{font-family:var(--sans)}
svg.dg .n{font-weight:500;font-size:13px;letter-spacing:2px;fill:var(--ink-2)}
svg.dg .h{font-weight:700;font-size:22px;letter-spacing:-.4px;fill:var(--ink)}
svg.dg .hs{font-weight:700;font-size:18px;letter-spacing:-.3px;fill:var(--ink)}
svg.dg .m{font-weight:500;font-size:13px;letter-spacing:1px;fill:var(--ink-2)}
svg.dg .k{font-weight:500;font-size:13px;letter-spacing:1.1px;fill:var(--accent-text)}
svg.dg .kw{font-weight:600;font-size:13px;letter-spacing:1.1px;fill:var(--ink)}
svg.dg .mb{font-weight:500;font-size:13px;letter-spacing:1px;fill:var(--ink)}
svg.dg.svg-p .m,svg.dg.svg-p .mb,svg.dg.svg-p .k,svg.dg.svg-p .kw{font-size:12.5px;letter-spacing:.9px}
svg.dg.svg-p .n{font-size:12.5px;letter-spacing:1.6px}
svg.dg.svg-p .hs{font-size:19px}
svg.dg .box{fill:none;stroke:var(--ink);stroke-width:1.8}
svg.dg .box.cond{stroke-dasharray:7 5;stroke:var(--ink-2)}
svg.dg .wire{fill:none;stroke:var(--ink);stroke-width:1.8}
svg.dg .wire.dash{stroke-dasharray:7 5;stroke:var(--ink-2)}
svg.dg .wire.soft{stroke:var(--rule)}
svg.dg .wire.acc{stroke:var(--accent-text)}
svg.dg .pulse{fill:none;stroke:var(--live);stroke-width:4;stroke-dasharray:8 100;stroke-dashoffset:8;opacity:0;stroke-linecap:butt}
svg.dg .fillon{fill:var(--accent-bg);opacity:0}
svg.dg .lamp{fill:var(--paper-2);stroke:var(--ink-2);stroke-width:1.4}
svg.dg .lamp-on{fill:var(--live);opacity:0}
svg.dg .lamp-al{fill:var(--alert-text);opacity:0}
@media (prefers-reduced-motion:reduce){svg.dg *{animation:none!important}}
/* En las fichas de servicio, con la barra lateral (≥1000 px), el retrato a
   460 px no cabía en pantalla: 978 px de alto el 1 y 1208 el 2 (Diego). A 340
   px el 1 queda en ~720 y el 2 en ~890, con el texto pequeño a 13,3 px reales.
   La otra salida, sacar la figura de la columna, choca con la barra lateral. */
@media (min-width:1000px){.prose .dgm svg.dg.svg-p{max-width:340px}}

/* T150: a8 (Infraestructura como Código). Lleva código y terminal, que no se
   leen a 340 px: tiene su propio corte. La variante ancha está dibujada para
   los ~720 px de la columna de una ficha y sale desde 640; por debajo, la
   estrecha, con su propio tope: 380 px (codigo a ~13 px). Sin tope, a 1024 la
   columna mide 563 y el codigo salia a 19 px con 1600 px de alto. Con id para
   ganar a las reglas generales de .dgm sin depender del orden. */
#dg-a8 svg.dg.svg-l{display:block}
#dg-a8 svg.dg.svg-p{display:none}
@container (max-width:639px){
  #dg-a8 svg.dg.svg-l{display:none}
  #dg-a8 svg.dg.svg-p{display:block;max-width:380px;margin:0 auto}
}

/* T149b: letra pequena al final de una ficha (la nota de marcas). */
.prose .fine{margin-top:2.2rem;font-size:.8rem;line-height:1.5;color:var(--ink-2);max-width:68ch}

/* T152: el «Repetir» de la animación de IaC va ahora con los botones comunes (T154, abajo). */

/* T154: la capa de datos de la órbita (diagramas/a9_orbita.py), encima de la
   imagen y del mismo tamaño; cada variante con la misma regla de ancho que el
   <source> del <picture>, para que capa e imagen sean siempre la misma. */
.team > .orb{margin-block:2rem}
.orb{position:relative}
.orb > .team-orbit{margin:0}
.orb-ov{position:absolute;left:0;top:0;width:100%;height:auto;pointer-events:none}
.orb-p{display:none}
/* T180 T5 (QA de Ricardo, decisión de Diego): vertical hasta 1299 px de ventana. En apaisado, la columna
   estrecha dejaba los rótulos en 8-11 px; con el tope de 600, la vertical nunca pasa de 750 de alto. */
@media (max-width:1299px){.orb-l{display:none}.orb-p{display:block}.team > .orb{max-width:600px;margin-inline:auto}}
/* Botones de los diagramas que se reproducen una vez (T154: órbita, circuito e IaC):
   mientras se mueve, «Pausar»; al acabar, «Repetir». Sin JS ni movimiento, ninguno. */
.dg-ctl{display:none;margin:.6rem 0 0}
.dg-ctl button{display:none}
.dgm .dg-ctl{margin:-.4rem 0 0;padding:0 1rem .9rem}
@media (prefers-reduced-motion:no-preference){
  #dg-orb.orb-js.orb-go .orb-ctl,#dg-a7.a7-js.a7-go .a7-ctl,#dg-a8.a8-js.a8-go .a8-ctl{display:block}
  #dg-orb.orb-js.orb-go:not(.orb-done) .orb-pause,#dg-orb.orb-js.orb-done .orb-replay,
  #dg-a7.a7-js.a7-go:not(.a7-done) .a7-pause,#dg-a7.a7-js.a7-done .a7-replay,
  #dg-a8.a8-js.a8-go:not(.a8-done) .a8-pause,#dg-a8.a8-js.a8-done .a8-replay{display:inline-block}
  /* Fase 0: los seis que dejaron de ir en bucle, con el mismo control */
  #dg-a1.a1-js.a1-go .a1-ctl,#dg-a2.a2-js.a2-go .a2-ctl,#dg-a3.a3-js.a3-go .a3-ctl,
  #dg-modelo.modelo-js.modelo-go .modelo-ctl,#dg-migracion.migracion-js.migracion-go .migracion-ctl,
  #dg-rc.rc-js.rc-go .rc-ctl{display:block}
  #dg-a1.a1-js.a1-go:not(.a1-done) .a1-pause,#dg-a1.a1-js.a1-done .a1-replay,
  #dg-a2.a2-js.a2-go:not(.a2-done) .a2-pause,#dg-a2.a2-js.a2-done .a2-replay,
  #dg-a3.a3-js.a3-go:not(.a3-done) .a3-pause,#dg-a3.a3-js.a3-done .a3-replay,
  #dg-modelo.modelo-js.modelo-go:not(.modelo-done) .modelo-pause,#dg-modelo.modelo-js.modelo-done .modelo-replay,
  #dg-migracion.migracion-js.migracion-go:not(.migracion-done) .migracion-pause,
  #dg-migracion.migracion-js.migracion-done .migracion-replay,
  #dg-rc.rc-js.rc-go:not(.rc-done) .rc-pause,#dg-rc.rc-js.rc-done .rc-replay{display:inline-block}
  .dg-ctl button{padding:.15rem .5rem;font:600 .68rem/1.4 var(--sans);letter-spacing:.12em;text-transform:uppercase;
    color:var(--ink-2);background:none;border:1px solid var(--rule);cursor:pointer}
  .dg-ctl button:hover,.dg-ctl button:focus-visible{color:var(--ink);border-color:var(--ink-2)}
}

/* ---------- T157: textos comerciales de la portada (18-oct) ----------
   Provisional hasta que Diego lo vea: reusa la caja de .paths y los botones
   que ya existen; no hay color ni tipo nuevos. */
.worked{border-bottom:1px solid var(--rule-soft)}
.worked .wrap{display:flex;flex-wrap:wrap;align-items:baseline;gap:.5rem 1.4rem;padding-block:1.3rem}
.worked .meta{color:var(--ink-2)}
.worked ul{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:.3rem 0;font-weight:600;font-size:.98rem}
/* QA de Ricardo (T157): el «·» entraba en el nombre accesible («AB InBev·»).
   El texto alternativo vacío lo saca; la primera línea es para navegadores sin él. */
.worked li:not(:last-child)::after{content:"·";content:"·" / "";padding-inline:.7rem;color:var(--ink-2)}
.worked + section{padding-top:clamp(3rem,6vw,5rem)}

.starts{display:grid;grid-template-columns:1fr;border-top:1px solid var(--rule-strong);border-left:1px solid var(--rule)}
@media (min-width:980px){.starts{grid-template-columns:repeat(3,1fr)}}
.start{display:flex;flex-direction:column;align-items:flex-start;gap:.8rem;padding:1.7rem 1.6rem 1.9rem;border-bottom:1px solid var(--rule);border-right:1px solid var(--rule)}
.start h3{font-family:var(--disp);text-transform:uppercase;font-weight:800;font-size:clamp(1.9rem,3vw,2.5rem);line-height:.88;letter-spacing:.004em}
.start .smeta{font-size:.85rem;font-weight:700}
.start .sdesc{font-size:.95rem;color:var(--ink-2);max-width:40ch}
.start .btn{margin-top:auto}

.sec-quote{margin-top:2rem}

.cta-act{display:grid;justify-items:start;gap:.9rem;align-self:end}
@media (min-width:960px){.cta-act{justify-self:end;justify-items:end;text-align:right}}
.cta-top .cta-note{margin-top:0;font-size:.95rem;max-width:32ch}

/* Barra fija abajo, solo en móvil; desde T164 (A4, Diego) en todas las páginas.
   Con poca altura (apaisado, zoom alto) no sale: taparía media pantalla. */
.mbar{display:none}
@media (max-width:719px) and (min-height:420px){
  .mbar{
    position:fixed;left:0;right:0;bottom:0;z-index:40;display:grid;grid-template-columns:1fr 1fr;gap:.6rem;
    padding:.6rem 16px calc(.6rem + env(safe-area-inset-bottom));
    background:var(--night);color:var(--ink);border-top:1px solid var(--rule-strong);
  }
  .mbar .btn{justify-content:center;padding:.85rem .8rem}
  body:has(.mbar){padding-bottom:calc(4.3rem + env(safe-area-inset-bottom))}
  /* QA de Ricardo (T157, WCAG 2.4.11): sin esto, al tabular el navegador
     dejaba el foco pegado al borde de abajo, debajo de la barra. */
  html:has(.mbar){scroll-padding-bottom:calc(4.3rem + env(safe-area-inset-bottom) + .75rem)}
  .mbar-1{grid-template-columns:1fr}
  /* T164 · A4 (Diego): un solo sistema en móvil. Con la barra de abajo
     haciendo de «Llamar | Pedir cotización», la cabecera pasa a una fila
     (logo + Menú) que no se queda fija, y la barra de estado a una línea:
     el teléfono ya está abajo. Ganan unos 100 px de pantalla útil. Mismo
     corte que .mbar: en apaisado sigue el sistema de antes, con el botón
     arriba, porque abajo no hay barra. */
  header.nav{position:relative}
  .nav-cta{display:none}
  .menu{border-top:0}
  .menu summary{position:absolute;top:0;right:0;height:3.9rem;gap:.6rem}
  .menu[open]{border-top:1px solid var(--rule)}
  .status .wrap{flex-wrap:nowrap;gap:.6rem}
  .status .meta{white-space:nowrap}
  .status-place{display:none}
}
@media (max-width:400px) and (min-height:420px){
  .st-long{display:none}
  .st-short{display:inline}
}

/* ============================================================
   T158 (Jaime, 19-oct): H1 nuevo en tres líneas fijas, con lo resaltado
   solo en la del medio: «Support, cloud and / AI agents / for your
   business.» y «Soporte, nube y / agentes de IA / para su empresa.».
   El <span> en bloque fija los dos cortes; el tamaño hace que cada línea
   quepa entera. Línea más ancha medida en Host Grotesk 700: 8,06 em en EN y
   7,32 em en ES; se divide entre 8,4 y 7,7 para dejar holgura. Sin nowrap:
   si alguien agranda solo el texto, la línea se parte en vez de desbordar.
   ============================================================ */
:root h1.hero-h1{max-width:none;font-size:min(var(--fs-h1),calc((100vw - 2.2rem) / 8.4))}
:root :lang(es) h1.hero-h1,:root h1.hero-h1:lang(es){font-size:min(var(--fs-h1),calc((100vw - 2.2rem) / 7.7))}
:root h1.hero-h1 span{display:block}

/* ============================================================
   T159 (Jaime, 19-oct): el registro de /clients/ por sector. Un .ledger por
   grupo; el título es su primera fila, a todo el ancho y con el mismo fondo
   que las celdas, para que no quede texto suelto sobre la textura de fondo.
   Color de kicker (--accent-text, 7,3:1), no el cian, que no va en texto.
   ============================================================ */
.ledgers{display:grid;gap:clamp(1.4rem,2.6vw,2rem)}
.ledger-h{
  grid-column:1/-1;margin:0;padding:.8rem 1.1rem;
  border-right:1px solid oklch(var(--hl)/.3);border-bottom:1px solid oklch(var(--hl)/.3);
  background:oklch(var(--night-ch)/.93);color:var(--accent-text);
  font-size:.74rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;line-height:1.3;
}
/* T5 · Clientes como libro registro (Diego, dirección B). Fuera la textura de filas falsas: el propio registro es la
   pauta, y la rejilla se completa a cualquier ancho.
   - Desde 760 px (3 y 4 columnas): la rejilla la dibuja el fondo del .ledger con el mismo paso que las celdas, así que
     los huecos de la última fila salen rayados, como las líneas libres de un libro. El paso de fila es fijo; medido
     con los 29 nombres, el más alto pide 95 px a 768 y 94 a 1440 (en español); dejo unos 6-9 px de aire.
   - Por debajo (2 columnas): las filas no pueden tener paso fijo (un nombre en tres líneas pide 130 px a 390), así
     que la última celda, si queda sola, ocupa las dos columnas. */
@media (max-width:759px){
  .ledger:not(:has(.ledger-h)) > div:last-child:nth-child(odd),
  .ledger:has(.ledger-h) > div:last-child:nth-child(even){grid-column:1/-1}
}
@media (min-width:760px){
  .ledger{
    --cols:3;--fila:6.5rem;--cab:0px;--raya:oklch(var(--hl)/.3);
    grid-auto-rows:var(--fila);
    background-color:oklch(var(--night-ch)/.93);
    background-image:linear-gradient(to left,var(--raya) 0 1px,transparent 1px),linear-gradient(to top,var(--raya) 0 1px,transparent 1px);
    background-size:calc(100% / var(--cols)) var(--fila);
    background-position:0 var(--cab);
  }
  .ledger:has(.ledger-h){--cab:2.7rem;grid-template-rows:var(--cab)}
  /* (QA de Ricardo) opaca: al 93 % se transparentaban las rayas de las columnas */
  .ledger-h{box-sizing:border-box;height:var(--cab);display:flex;align-items:center;background:oklch(var(--night-ch))}
}
@media (min-width:1140px){.ledger{--cols:4;--fila:6.3rem}}

/* ============================================================
   T160 (Jaime, 19-oct): imágenes propias en las páginas que no tenían.
   1. Marcas de cabecera (Diego, diagramas/marcas.py): un esquema por página
      en la mitad derecha de .phead, sin texto y aria-hidden. Solo a ≥1240 px:
      por debajo, el lead de 58ch llega al hueco. A 360×180 y alineadas con el
      antetítulo, nunca cruzan el filete de los datos (medido en las 24).
   ============================================================ */
.phead-mark{display:none}
@media (min-width:1240px){
  .phead-mark{display:block;position:absolute;right:var(--pad);top:clamp(2.6rem,6vw,5rem);
    width:360px;height:180px;pointer-events:none}
  .phead-mark svg{display:block;width:100%;height:100%;overflow:visible}
}
.phead-mark svg *{vector-effect:non-scaling-stroke}
/* 2. Los dos diagramas nuevos se dibujaron para la columna (680-700 de ancho):
      apaisados desde 600 px de figura, retrato con tope 340 por debajo. Con id,
      como #dg-a8, para ganar a la regla general de .dgm sin depender del orden. */
:is(#dg-modelo,#dg-migracion,#dg-consultoria,#dg-software,#dg-soluciones) svg.dg.svg-l{display:block}
:is(#dg-modelo,#dg-migracion,#dg-consultoria,#dg-software,#dg-soluciones) svg.dg.svg-p{display:none}
@container (max-width:599px){
  :is(#dg-modelo,#dg-migracion,#dg-consultoria,#dg-software,#dg-soluciones) svg.dg.svg-l{display:none}
  :is(#dg-modelo,#dg-migracion,#dg-consultoria,#dg-software,#dg-soluciones) svg.dg.svg-p{display:block;max-width:340px;margin:0 auto}
}
/* 3. (T160: la foto de Unsplash de IT Support. La sustituye T165, abajo.) */
/* 4. QA de Ricardo (T160). a3: los números 01–04 (.n, --ink-2) daban 2,77:1 con la
      caja iluminada en --accent-bg; en tinta dan 4,73. Y con solo el texto
      ampliado del navegador, el H1 y la entradilla rozaban la marca: se les
      deja sitio. Al 100 % no cambia ninguna línea (medido en las 24). */
#dg-a3 .n{fill:var(--ink)}
#dg-a2 .n{fill:var(--ink)}   /* «NOC · SOC»: el mismo 2,77:1 (Lola lo metió en T160) */
@media (min-width:1240px){
  :root .phead .phead-mark~h1{max-width:min(18ch,100% - 360px - 2rem)}
  :root .phead .phead-mark~p.lead{max-width:min(58ch,100% - 360px - 2rem)}
}
/* 5. (T160 tanda 2: la casilla «Pausar animación» de los diagramas en bucle. La quitó la
      Fase 0: ya no hay bucles y queda un solo control, el de a7/a8, arriba en .dg-ctl.) */

/* T164 · M5: la tarjeta de /services/ lleva cómo se factura debajo del precio,
   que es lo que decía la tabla de base de cálculo. */
.cov .price .bill{display:block;margin-top:.3rem;font-weight:500;color:var(--ink-2)}
.cov.is-new .price .bill{color:var(--band-ink-2)}

/* T164 · M1: las promesas de /contact/ pasan a la columna, como tarjeta. */
.card.promise{padding:1.25rem 1.3rem 1.4rem;margin-bottom:0;max-width:none}
.card.solid p + p{margin-top:.6rem}
/* T164 · M4: el enlace a las diez líneas, bajo las relacionadas. */
.rail-all{margin-top:1rem;font-size:.9rem;font-weight:600}
.rail-all a{text-underline-offset:.18em}
/* T164 · M13: índice de anclas en las fichas largas. Una lista corta, no una tarjeta. */
.toc{margin:0 0 2.2rem;padding-bottom:1.2rem;border-bottom:1px solid var(--rule)}
.toc ul{list-style:none;margin:.6rem 0 0;padding:0;display:flex;flex-wrap:wrap;gap:.35rem 1.2rem}
.toc a{font-size:.9rem;font-weight:600;text-underline-offset:.18em;display:inline-block;padding-block:.2rem}
.prose h2[id]{scroll-margin-top:6rem}

/* T164 · QA de Ricardo (1): las anclas no quedan bajo la cabecera fija
   (#levels, enlazada desde la portada, y los h2 del índice entre 568 y 1023 px). */
:root .prose h2[id],:root #levels{scroll-margin-top:8rem}
/* (2) WCAG 1.4.4: con el texto ampliado, la barra de estado vuelve a poder
   partirse y el logo cede sitio a «Menú». Al 100 % no cambia nada. */
@media (max-width:719px) and (min-height:420px){
  :root .status .wrap{flex-wrap:wrap}
  :root .status .meta{white-space:normal}
  :root header.nav .mark{min-width:0;max-width:calc(100% - 7.5rem)}
  :root .mark svg.logo{max-width:100%}
}
/* (3) Entre 320 y 357 px «Pedir cotización» se partía y la barra medía más que
   el scroll-padding. */
@media (max-width:359px) and (min-height:420px){:root .mbar:not(.mbar-1){grid-template-columns:2fr 3fr}}
:root .mbar .btn{text-align:center}

/* ============================================================
   T165 · Fotos reales (plan de Lola, OK de Jaime 21-oct).
   Una suelta va a su tamaño (el de width/height); parejas y tríos, en rejilla.
   ============================================================ */
.foto{margin:0}
.foto img{display:block;max-width:100%;height:auto;border:1px solid var(--rule-soft)}
.foto figcaption{margin-top:.5rem;font-size:var(--fs-meta);font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-2)}
.fotos{margin-block:2rem}
.prose > .fotos + *{margin-top:2rem}
.fotos-n{display:grid;gap:.8rem;grid-template-columns:repeat(2,minmax(0,1fr))}
.fotos-n .foto img{width:100%}
@media (min-width:560px){.fotos-3{grid-template-columns:repeat(3,minmax(0,1fr))}}
.fotos-before-after,.fotos-sequence{max-width:640px}
/* T167 (Diego): la pareja suelta (Operation, 08 y 12) con tope de 300 px por foto, que es
   su fichero 1x; sin él llegaba a 347-354 px y se reescalaba un 18 % a DPR 1. */
.fotos-2.fotos-group{max-width:calc(600px + .8rem)}
/* los tríos, a todo el ancho de la columna: con el tope del texto (--prose) salían a ~230 px */
:root .prose > .fotos-3,.fotos-3{max-width:none}
/* /services/ y /clients/: la foto en la cabecera, donde otras páginas llevan la
   marca. Solo desde 1000 px; por debajo no se pinta (y, con lazy, no se baja). */
.phead-foto{display:none}
@media (min-width:1000px){
  .phead-foto{display:block;position:absolute;right:var(--pad);top:clamp(2.6rem,6vw,5rem);width:15rem}
  .phead-foto img{width:100%}
  :root .phead .phead-foto~h1{max-width:min(18ch,100% - 15rem - 3rem)}
  :root .phead .phead-foto~p.lead{max-width:min(58ch,100% - 15rem - 3rem)}
  :root .phead .phead-foto~.phead-facts{max-width:calc(100% - 15rem - 3rem)}
  :root .phead:has(.phead-foto) .wrap{min-height:calc(20rem + clamp(2.6rem,6vw,5rem) + 2rem)}
}
/* ============================================================
   T172 (27-oct): página local A y página de IA para pymes B, de las maquetas
   de Diego (t-local-ia/_src/maquetas.py, MAQ_CSS sin el .pend de la maqueta).
   ============================================================ */
/* A · las líneas: seis, en 3 × 2 desde 1000 px (la rejilla de /services/ va a 5 y dejaba una huérfana) */
@media (min-width:1000px){.local-lines .coverage{grid-template-columns:repeat(3,1fr)}}
/* A · clientes en Weston: tres celdas y el enlace en la fila del registro */
.ledger-more{margin-top:1.4rem;font-size:.95rem}
.ledger-more a{color:var(--accent-text);text-underline-offset:.2em}
/* A · cómo trabajamos + la oficina */
.local-work{display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(2.4rem,5vw,4.5rem);align-items:start}
@media (min-width:1000px){.local-work{grid-template-columns:minmax(0,1fr) minmax(0,24rem)}}
.local-work .spec{margin-top:0}
.office{border:1px solid var(--rule);background:var(--paper-2);padding:clamp(1.4rem,3vw,2rem)}
.office address{font-style:normal;font-family:var(--disp);font-weight:700;font-size:clamp(1.6rem,2.6vw,2.1rem);
  line-height:1.08;letter-spacing:-.01em;margin-top:.9rem}
.office .note{color:var(--ink-2);margin-top:.8rem;font-size:.95rem}
.office .acts{margin-top:1.4rem}
.office .tel{display:block;margin-top:1.4rem;padding-top:1.1rem;border-top:1px solid var(--rule-soft)}
.office .tel a{font-weight:700;font-size:1.15rem;text-decoration:none}
/* B · el bloque de la ficha 09 y el «Part of» del lateral */
.fork{margin-block:clamp(2rem,4vw,3rem);padding:1.4rem 1.5rem;border:1px solid var(--rule);background:var(--paper-2)}
.fork .meta{color:var(--accent-text)}
.fork p + p{margin-top:.55rem;color:var(--ink-2)}
.fork .go{display:inline-block;margin-top:.9rem;font-weight:700;color:var(--ink);text-underline-offset:.22em}
.rail .card .rail-note{color:var(--ink-2);font-size:.88rem;margin-top:.7rem}
/* B · el diagrama: apaisado cuando la columna da para él (680 de dibujo), y no a 1054 como el resto */
#dg-rc svg.dg.svg-l{display:block}
#dg-rc svg.dg.svg-p{display:none}
@container (max-width:599px){
  #dg-rc svg.dg.svg-l{display:none}
  #dg-rc svg.dg.svg-p{display:block;max-width:380px;margin:0 auto}
}

/* ============================================================
   Oferta Primer Equipo (Jaime, 02-nov)
   ============================================================ */
/* Franja de la portada: arriba para quien llega de las piezas de la campaña. Sin precio. */
.pe-franja{background:var(--accent-bg);color:var(--accent-on)}
.pe-franja p{padding-block:.7rem;display:flex;flex-wrap:wrap;gap:.15rem .8rem;align-items:baseline;font-size:.95rem}
.pe-franja strong{font-weight:700}
.pe-franja a{color:inherit;font-weight:700;text-underline-offset:.22em;padding-block:.3rem}
/* QA de Ricardo (a), Lola 02-nov: toda la franja es el objetivo táctil (el enlace solo medía 33 px) */
.pe-franja{position:relative}
.pe-franja a::after{content:"";position:absolute;inset:0}
/* QA Ricardo: el foco del acento-texto daba 2,03:1 sobre la banda; --ink da 4,7:1 */
.pe-franja a:focus-visible{outline-color:var(--ink)}
/* T186 punto 4: enlace a la pagina local en el cuerpo */
.local-more{margin-top:1.3rem;color:var(--ink-2);font-size:.95rem;max-width:66ch}
.local-more a{color:var(--accent-text);font-weight:600;text-underline-offset:.18em;white-space:nowrap}
.local-more a:hover{color:var(--ink)}
/* Los robots de la campaña: debajo de los datos en móvil, a la derecha desde 1000 px */
.pe-robots{display:block;width:min(100%,24rem);height:auto;margin-top:1.8rem}
@media (min-width:1000px){
  .pe-robots{position:absolute;right:var(--pad);top:clamp(2.6rem,6vw,5rem);width:clamp(20rem,28vw,27rem);margin-top:0}
  :root .phead:has(.pe-robots) h1{max-width:min(18ch,100% - 27rem - 3rem)}
  :root .phead:has(.pe-robots) p.lead{max-width:min(58ch,100% - 27rem - 3rem)}
}
.pe-contacto p{margin-top:.8rem}
.pe-contacto a[href^="mailto:"]{overflow-wrap:anywhere;text-underline-offset:.2em}
