/* ============================================================
   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>.
   ============================================================ */

:root{
  /* --- color: Full palette, claro (Diego, sin cambios) --- */
  --paper:     oklch(0.947 0.004 250);
  --paper-2:   oklch(0.905 0.005 250);
  --rule:      oklch(0.845 0.007 250);
  --rule-soft: oklch(0.895 0.006 250);
  --ink:       oklch(0.215 0.013 252);
  --ink-2:     oklch(0.455 0.012 252);
  --signal:    oklch(0.872 0.187 118);
  --signal-dk: oklch(0.495 0.125 128);
  --alert:     oklch(0.545 0.168 33);
  --night:     oklch(0.185 0.015 252);

  /* --- tipografía --- */
  --disp: 'Big Shoulders Display', 'Arial Narrow', 'Helvetica Neue Condensed', sans-serif;
  --sans: 'Schibsted 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(--signal);color:var(--ink)}
:where(a,button,input,select,textarea,summary):focus-visible{outline:2px solid var(--signal-dk);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(--ink);color:var(--paper);
  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(--paper);
  border-bottom:2px solid var(--ink);
}
.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(--paper)}

/* ---------- 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(0.95 0 0/.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(--signal);color:var(--ink);border-color:var(--signal)}
.langsw [aria-current="true"]{background:var(--signal);color:var(--ink);border-color:var(--signal)}

/* 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-underline-offset:.22em;
}

/* ---------- barra de estado ---------- */
.status{background:var(--ink);color:var(--paper)}
.status .wrap{display:flex;justify-content:space-between;align-items:center;gap:1rem;min-height:2.3rem;flex-wrap:wrap}
.status .meta{color:oklch(0.78 0.008 250)}
.status a{text-decoration:none}
.status a:hover{color:var(--signal)}
.dot{
  display:inline-block;width:.5rem;height:.5rem;background:var(--signal);
  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) infinite}
  @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(--ink)}
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(--ink);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(--signal)}
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}}

/* 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}
.nav-cta{
  display:flex;align-items:center;padding-inline:1.5rem;background:var(--ink);color:var(--paper);
  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(--signal);color:var(--ink)}

/* 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(--paper);overflow:hidden}
.hero-media{position:absolute;inset:0}
.hero-media img{width:100%;height:100%;object-fit:cover}
.hero-media::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,oklch(0.185 0.015 252/.86) 0%,oklch(0.185 0.015 252/.58) 42%,oklch(0.185 0.015 252/.92) 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(0.95 0 0/.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(--signal);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(--signal)}
.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:oklch(0.90 0.008 250)}
.hero-acts{display:flex;gap:.8rem;flex-wrap:wrap;margin-top:1.7rem}
.hero-card{border:1px solid oklch(0.95 0 0/.24);padding:1.15rem 1.25rem 1.3rem}
.hero-card .meta{color:var(--signal)}
.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(0.95 0 0/.2);padding-bottom:.45rem}
.hero-card dt{color:oklch(0.80 0.008 250);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(--signal);border-color:var(--signal);color:var(--ink)}
.btn-signal:hover,.btn-signal:focus-visible{background:var(--paper);border-color:var(--paper)}
.btn-ink{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.btn-ink:hover,.btn-ink:focus-visible{background:var(--signal);border-color:var(--signal);color:var(--ink)}
.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)}

/* ---------- cabecera de página interior ---------- */
.phead{background:var(--ink);color:var(--paper);position:relative;overflow:hidden}
.phead .wrap{position:relative;padding-block:clamp(2.6rem,6vw,5rem) clamp(2.2rem,5vw,4rem)}
.phead .hero-guides span{border-right-color:oklch(0.95 0 0/.07)}
.phead .kicker{color:var(--signal);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:oklch(0.88 0.008 250)}
.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(0.95 0 0/.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:oklch(0.78 0.008 250)}
.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{
  list-style:none;margin:0;padding-block:.75rem;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(--ink);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(--ink);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(--signal-dk)}
.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(--signal-dk)}
.path:hover .pgo{text-decoration:underline}

/* ---------- 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(--ink);color:var(--paper)}
.cov.is-new:hover,.cov.is-new:focus-visible{background:var(--night)}
.cov.is-new .cov-id{color:oklch(0.76 0.008 250)}
.cov.is-new p{color:oklch(0.83 0.008 250)}
.cov.is-new .price{border-top-color:oklch(0.95 0 0/.28);color:var(--signal)}
.cov.is-new .price.q{color:oklch(0.82 0.06 118)}
.cov.is-new .chip{border-color:var(--paper)}
.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(--ink);line-height:1;white-space:nowrap;
}
.chip.on{background:var(--signal);border-color:var(--signal);color:var(--ink)}
.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(--ink);color:var(--paper);font-size:var(--fs-meta);font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;border-bottom:none;white-space:nowrap;
}
table.rates tbody tr:last-child td{border-bottom:none}
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(0.872 0.187 118/.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(--signal-dk);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(--ink);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(0.872 0.187 118/.16)}
}



/* ---------- lo que cambia ---------- */
.swaps{border-top:1px solid var(--ink)}
.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;
}
.swap .before .tagl{background:var(--alert);color:var(--paper)}
.swap .after .tagl{background:var(--signal);color:var(--ink)}
.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(--ink)}
@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:oklch(0.620 0.010 250)}
.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(--signal-dk);
}

/* ---------- 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. */
.techband{margin:0;padding-block:clamp(2.5rem,6vw,5rem) clamp(2.5rem,6vw,4rem)}
.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(--paper);background:var(--night);overflow:hidden}
.clients-media{position:absolute;inset:0}
.clients-media img{width:100%;height:100%;object-fit:cover}
.clients .wrap{position:relative}
.clients .sec-head{border-bottom-color:oklch(0.95 0 0/.35)}
.clients .sec-head .idx,.clients .sec-head .aside{color:oklch(0.83 0.008 250)}
/* 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(0.95 0 0/.3);border-left:1px solid oklch(0.95 0 0/.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(0.95 0 0/.3);border-bottom:1px solid oklch(0.95 0 0/.3);
  background:oklch(0.185 0.015 252/.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:oklch(0.80 0.06 118);
  /* «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;
}

/* ---------- 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(--ink);
}
.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(--signal);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(--signal-dk)}
.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(--signal-dk);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(--ink);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}

/* 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(--ink);padding:1.25rem 1.3rem 1.4rem}
.card.solid{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.card.solid h2,.card.solid .meta{color:var(--signal)}
.card.solid a:not(.btn){color:var(--paper)}  /* :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(0.95 0 0/.2)}
.card li a:hover{color:var(--signal-dk)}
.card.solid li a:hover{color:var(--signal)}
.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:oklch(0.78 0.008 250)}
.card p{margin-top:.8rem;font-size:.93rem;color:var(--ink-2)}
.card.solid p{color:oklch(0.85 0.008 250)}
.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(--signal)}

/* ---------- 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)}
.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(--signal-dk);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(--ink);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(--signal);color:var(--ink)}
.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:oklch(0.34 0.09 118)}
.cta .btn{justify-self:start;border-color:var(--ink)}
@media (min-width:960px){.cta .btn{justify-self:end}}
.cta .btn:hover{background:var(--ink);color:var(--signal)}

/* ---------- 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:oklch(0.36 0.08 118);--crail-rule:oklch(0.40 0.10 118/.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(--ink);color:oklch(0.76 0.008 250);padding-block:clamp(2.5rem,5vw,4rem)}
footer .wrap{display:grid;gap:2rem;grid-template-columns:1fr}
@media (min-width:820px){footer .wrap.cols{grid-template-columns:1.5fr 1fr 1fr 1fr;gap:2.5rem}}
footer h2{font-size:var(--fs-meta);font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--signal);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(--paper)}
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(--signal);margin-bottom:.9rem}
.partners{margin-top:clamp(2rem,4vw,3rem);padding-top:1.3rem;border-top:1px solid oklch(0.95 0 0/.2)}
.partners .plist{display:flex;flex-wrap:wrap;gap:.6rem 1.6rem;font-size:.92rem}
.partners .plist li{color:oklch(0.83 0.008 250)}
.colophon{margin-top:clamp(2rem,4vw,3rem);padding-top:1.2rem;border-top:1px solid oklch(0.95 0 0/.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) .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}
