/* ============================================================================
   components — cabecera, botones, filas de servicio, franjas, testimonios,
   formularios, casos, pie
   ========================================================================== */

/* ------------------------------------------------------------- cabecera
   Hermana de <main> y del pie, nunca dentro de una seccion achaflanada. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}
.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  min-height: var(--header-h);
}
.site-header__brand { margin-right: auto; display: flex; align-items: center; }
.site-header__brand img { width: auto; height: clamp(1.75rem, 3vw, 2.25rem); }

.site-nav__list {
  display: flex;
  align-items: center;
  gap: clamp(var(--s-4), 2vw, var(--s-6));
}
.site-nav__link {
  display: inline-block;
  padding-block: var(--s-2);
  font-size: var(--fs-sm);
  font-weight: 500;
  text-decoration: none;
  color: var(--ink);
}
.site-nav__link:hover { color: var(--violet); }
.site-nav__link[aria-current="page"] {
  color: var(--violet);
  font-weight: 600;
  box-shadow: inset 0 -2px 0 0 var(--amber);
}

.nav-toggle {
  display: none;
  width: 2.75rem; height: 2.75rem;   /* 44px: area de toque minima */
  padding: 0;
  border: 1px solid var(--line);
  background: var(--paper);
  border-radius: var(--r-control);
  cursor: pointer;
}
.nav-toggle__bars, .nav-toggle__bars::before, .nav-toggle__bars::after {
  display: block;
  width: 1.125rem; height: 2px;
  margin-inline: auto;
  background: var(--ink);
  content: "";
}
.nav-toggle__bars::before { transform: translateY(-6px); }
.nav-toggle__bars::after  { transform: translateY(4px); }

/* El complemento EXACTO de min-width: 64rem. Escribir max-width: 63.99rem
   dejaria una franja muerta entre 1023,84 y 1024px sin navegacion de ningun
   tipo: ni la de escritorio ni la de movil. */
@media not all and (min-width: 64rem) {
  .nav-toggle { display: block; }
  .site-nav {
    position: fixed;
    /* +1px: la cabecera mide --header-h de min-height MAS su borde inferior.
       Sin esto el panel se comia esa linea y la cabecera se quedaba sin
       separacion mientras el menu estaba abierto. */
    inset: calc(var(--header-h) + 1px) 0 0 0;
    z-index: 40;
    padding: var(--s-6) var(--gutter) var(--s-8);
    background: var(--paper);
    overflow-y: auto;
    /* Sin esto, cuando el contenido del panel cabe entero y no tiene scroll
       propio, el gesto encadena al documento de detras: se cierra el menu y
       estas 1.200px mas abajo de donde estabas. inert no lo evita, porque
       bloquea interaccion y lector de pantalla, no el scroll. */
    overscroll-behavior: contain;
  }
  .site-nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }
  .site-nav__link {
    padding-block: var(--s-4);
    font-size: var(--fs-h3);
    border-bottom: 1px solid var(--line);
  }
  .site-nav__cta { margin-top: var(--s-5); }
}

/* Sin JavaScript el panel no puede quedar oculto: el boton no existe y la
   lista se ve apilada. El hidden solo manda cuando hay JS para quitarlo. */
html:not(.js) .site-nav[hidden] { display: block; }
html:not(.js) .nav-toggle { display: none; }

/* --------------------------------------------------------------- botones */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.875rem;
  padding: var(--s-3) var(--s-6);
  border: 2px solid transparent;
  border-radius: var(--r-control);
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: -0.01em;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-1) var(--ease-out),
              color var(--dur-1) var(--ease-out),
              border-color var(--dur-1) var(--ease-out);
}
/* Relleno ambar, tinta oscura. Nunca texto blanco sobre ambar: 1,9:1. */
.btn--amber { background: var(--amber); color: var(--ink); }
.btn--amber:hover { background: var(--amber-press); }

.btn--violet { background: var(--violet); color: var(--on-violet); }
.btn--violet:hover { background: var(--violet-deep); }

/* El contorno se pinta con --outline-c, que cada superficie oscura redefine.
   Listar los selectores uno a uno (.plane-violet .btn--outline, ...) fallaba en
   cuanto aparecia una superficie oscura nueva: el hero no lleva .plane-violet, y
   el boton salia violeta sobre violeta, invisible. */
.btn--outline {
  background: transparent;
  color: var(--outline-c, var(--violet));
  border-color: var(--outline-c, var(--violet));
}
.btn--outline:hover {
  background: var(--outline-c, var(--violet));
  color: var(--outline-on, var(--on-violet));
}

/* Toda superficie sobre la que el texto va en blanco declara aqui su contorno,
   y de paso el color del anillo de foco: sobre violeta o tinta, el violeta del
   anillo seria invisible y el ambar da 4,65:1 y 8,75:1. */
.plane-violet, .plane-deep, .hero, .page-head, .cta-panel, .site-footer {
  --outline-c: var(--on-violet);
  --outline-on: var(--violet);
  --focus-c: var(--amber);
}

.btn:disabled, .btn[disabled] { opacity: .55; cursor: progress; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--s-4); }

/* ------------------------------------------------- filas de servicio
   Servicios con nombres largos. Como filas se leen; troceados en tarjetas
   identicas se convierten en un muestrario. La lista no tiene tope: es una
   pila de filas con borde, y anadir una no pide tocar nada de aqui. */
.service-list { border-top: 1px solid var(--line); }
.service-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-2) var(--s-6);
  padding-block: var(--s-6);
  border-bottom: 1px solid var(--line);
  text-decoration: none;
  color: inherit;
}
@media (min-width: 48rem) {
  .service-row { grid-template-columns: minmax(14rem, 20rem) 1fr auto; align-items: baseline; }
  /* El icono COMPARTE columna con el nombre, no lleva carril propio. Con carril
     propio sus 2rem mas el gap salen enteros de la descripcion, porque el 1fr es
     la unica pista flexible de las tres: la medida caia de ~44 a ~35 caracteres
     en todo el rango 768-1134px, y ahi el max-width de 52ch todavia no ata nada.
     Encima del nombre cuesta alto, que sobra, en vez de ancho, que no.
     De paso repite el orden que ya usa services.html: icono sobre el titulo.
     La marca abarca las dos filas para seguir centrada contra la fila entera,
     que es lo que hacia cuando la rejilla tenia una sola. */
  .service-row__icon { grid-column: 1; grid-row: 1; }
  .service-row__name { grid-column: 1; grid-row: 2; }
  .service-row__desc { grid-column: 2; grid-row: 2; }
  .service-row__mark { grid-column: 3; grid-row: 1 / span 2; }
}
.service-row__icon { width: 2rem; height: 2rem; }

.service-row__name {
  font-size: var(--fs-h3);
  font-weight: 700;
  letter-spacing: var(--tr-head);
  color: var(--violet);
}
.service-row__desc { color: var(--mute); max-width: 52ch; }
/* La marca de la fila: un chaflan pequeno que se rellena de ambar al
   apuntar. Es el unico movimiento no pedido por el usuario en la pagina. */
.service-row__mark {
  width: 1.25rem; height: 1.25rem;
  align-self: center;
  background: var(--violet-mist);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 35% 100%, 0 65%);
  transition: background-color var(--dur-1) var(--ease-out);
}
.service-row:hover .service-row__mark,
.service-row:focus-visible .service-row__mark { background: var(--amber); }

.service-row__name { text-decoration: underline; text-underline-offset: 4px; }

/* --------------------------------------------------------------- franjas
   Una franja tipografica: las certificaciones del equipo. La segunda, la de
   empresas, se fue a .company: alli las marcas SI llevan logo, y el nombre
   escrito al lado es lo que permite listar tambien a las que no lo tienen. */
.strip { display: flex; flex-wrap: wrap; gap: var(--s-3); }
.strip__item {
  padding: var(--s-2) var(--s-5);
  background: var(--violet-mist);
  color: var(--violet);
  font-size: var(--fs-sm);
  font-weight: 600;
  clip-path: polygon(0 0, calc(100% - .5rem) 0, 100% .5rem, 100% 100%, 0 100%);
}
.plane-violet .strip__item,
.plane-deep .strip__item { background: rgb(255 255 255 / .12); color: var(--on-violet); }


/* --------------------------------------------------- valores y pasos */
/* Flex y no grid a proposito. Con auto-fit, 7 valores dejaban una tarjeta
   huerfana ocupando el 32 % de la fila a 1024 y el 48 % a 768. Con flex, las
   de la ultima fila crecen y no queda hueco. */
.grid-cards {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-5);
}
.grid-cards > * { flex: 1 1 15rem; }
.value {
  padding: var(--s-5) var(--s-5) var(--s-6);
  background: var(--paper-2);
  border-top: 3px solid var(--violet);
}
.value__icon { width: 2.5rem; height: 2.5rem; margin-bottom: var(--s-4); }
.value__name { font-size: var(--fs-h3); margin-bottom: var(--s-2); }
.value__desc { color: var(--mute); font-size: var(--fs-sm); }

/* Sobre plano violeta. El velo blanco al 8 % compuesto sobre #6214a8 da
   rgb(111 39 175): blanco encima 8,12:1 y blanco al 78 % 5,56:1, los dos AA.
   Hay que componer el alfa a mano para saberlo; un medidor que lea
   rgba(255,255,255,.08) como si fuera opaco da 1:1 y miente. */
.value--on-violet {
  background: rgb(255 255 255 / .08);
  border-top-color: var(--amber);
}
.value--on-violet .value__desc { color: var(--on-violet-2); }

/* El proceso SI es una secuencia, asi que aqui el numero informa. En el
   resto del sitio no hay marcadores numerados. */
.steps { counter-reset: paso; display: grid; gap: var(--s-6); }
@media (min-width: 48rem) { .steps { grid-template-columns: repeat(3, 1fr); gap: var(--s-7); } }
.step { counter-increment: paso; }
.step::before {
  content: counter(paso);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem; height: 2.5rem;
  margin-bottom: var(--s-4);
  background: var(--amber);
  color: var(--ink);
  font-size: var(--fs-h3);
  font-weight: 700;
  clip-path: polygon(0 0, calc(100% - .625rem) 0, 100% .625rem, 100% 100%, 0 100%);
}
.step__name { font-size: var(--fs-h3); margin-bottom: var(--s-2); }
.step__desc { color: var(--mute); font-size: var(--fs-sm); }

/* ------------------------------------------------------------- casos */
.case { display: grid; gap: 0; }
@media (min-width: 56rem) { .case { grid-template-columns: 1fr 1fr; } }
.case__side { padding: var(--s-6) clamp(var(--s-5), 4vw, var(--s-8)); }
/* Sin esto el texto del caso ocupa los 693px enteros a 768px de viewport y
   salen 83 caracteres por linea. */
.case__side > .u-flow, .case__title { max-width: var(--w-prose); }
.case__side--challenge { background: var(--violet-mist); }
.case__side--solution { background: var(--paper-2); }
.case__kicker {
  margin-bottom: var(--s-3);
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--violet);
}
.case__title { margin-bottom: var(--s-5); }

/* ---------------------------------------------------------- formularios */
.field-row { display: grid; gap: var(--s-4); }
@media (min-width: 40rem) { .field-row--2 { grid-template-columns: 1fr 1fr; } }
@media (min-width: 40rem) { .field-row--3 { grid-template-columns: repeat(3, 1fr); } }

.field-label {
  display: block;
  margin-bottom: var(--s-2);
  font-size: var(--fs-sm);
  font-weight: 600;
}
.field {
  width: 100%;
  min-height: 2.875rem;
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--r-control);
  background: var(--paper);
}
.field:focus { border-color: var(--violet); }
textarea.field { min-height: 8rem; resize: vertical; }

.field-row + .field-row { margin-top: var(--s-4); }

.form-fieldset { border: 0; padding: 0; margin: var(--s-5) 0 0; }
.form-fieldset + .field-row { margin-top: var(--s-5); }
.form-fieldset legend { padding: 0; }

.choice { display: flex; align-items: center; gap: var(--s-3); padding-block: var(--s-2); }
.choice input { width: 1.125rem; height: 1.125rem; accent-color: var(--violet); }

.form-actions { margin-top: var(--s-6); }

.form-hp { position: absolute; left: -9999px; top: -9999px; }

/* ⚠ ESTA REGLA NO ES DECORATIVA.
   Venia de css/webflow.css, que este redisenio borra. js/form-submit.js solo
   hace display:block al enviar; nunca los oculta al cargar. Sin esta regla
   los mensajes de exito Y de error se ven a la vez, permanentemente, en las
   dos paginas con formulario, y sin lanzar ningun error en consola. */
.w-form-done, .w-form-fail { display: none; }

.w-form-done, .w-form-fail { padding: var(--s-5); border-radius: var(--r-control); }
.w-form-done { background: var(--violet-mist); color: var(--ink); }
.w-form-fail { background: var(--danger-bg); color: var(--danger); }

/* Lista de enlaces sobre fondo claro. .footer-list solo vale sobre el pie oscuro. */
.link-list li + li { margin-top: var(--s-3); }
.link-list a { color: var(--violet); font-weight: 600; text-decoration: none; }
.link-list a:hover { text-decoration: underline; text-underline-offset: 4px; }

/* Enumeracion sin enlaces. .link-list da el mismo hueco, pero todo lo demas que
   trae es para anclas y aqui no hay ninguna; y el reset quita el boliche a
   todos los li, asi que sin marca propia esto seria un parrafo troceado. La
   marca repite el chaflan de .service-row__mark, que es el gesto de la casa. */
.core-list li { position: relative; padding-left: var(--s-5); }
.core-list li + li { margin-top: var(--s-3); }
.core-list li::before {
  content: "";
  position: absolute;
  left: 0; top: .55em;
  width: .5rem; height: .5rem;
  background: var(--violet);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 35% 100%, 0 65%);
}

/* ----------------------------------------------------------------- pie */
/* overflow: clip es lo que recorta el mosaico contra los bordes (ver mas abajo);
   ademas es lo unico que impide que el sangrado derecho genere scroll horizontal,
   porque body no lleva overflow-x. CLIP y no HIDDEN: hidden convierte el pie en
   contenedor de scroll, y al tabular hasta un enlace el navegador puede desplazarlo
   con scrollIntoView; clip recorta igual sin crear contenedor. Y el arreglo NUNCA es
   overflow-x en html/body: la cabecera es sticky y scroll-padding-top vive en :root,
   asi que eso romperia las anclas de /services.
   isolation crea el contexto de apilamiento sin el cual ::after pintaria por encima
   del texto: el orden de pintado es ::before, .u-page, ::after, y los tres son
   elementos posicionados. */
.site-footer {
  position: relative;
  overflow: hidden;   /* respaldo para Safari < 16, que no conoce clip y tiraria la linea */
  overflow: clip;
  isolation: isolate;
  background: var(--ink);
  color: var(--on-violet);
}
.site-footer > .u-page { position: relative; z-index: 1; }
.site-footer a { color: var(--on-violet-2); text-decoration: none; }
.site-footer a:hover { color: var(--on-violet); text-decoration: underline; }
.footer-grid {
  display: grid;
  gap: var(--s-7);
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}
.footer-brand img { width: 11rem; }
.footer-brand p {
  margin-top: var(--s-5);
  font-size: var(--fs-sm);
  color: var(--on-violet-2);
}
/* El eslogan de marca, encima del descriptor de siempre.
   .footer-brand .footer-brand__slogan Y NO .footer-brand__slogan a secas:
   la regla de arriba es una clase MAS un tipo, o sea (0,1,1), y le gana a una
   clase sola. Escrito con un solo selector el color se pierde sin avisar y el
   eslogan sale blanco como el descriptor.

   EL AMBAR AQUI SE MIDIO SOBRE EL PIXEL PINTADO, no sobre la tabla. Componer
   el tinte mas claro del mosaico al 26 % sobre --ink da 4,27:1 y asusta, pero
   ese pixel NO EXISTE en el pie: las celdas claras son pequenas y se salen de
   cuadro. Rasterizados los dos pseudo-elementos con su geometria real, el peor
   pixel de todo el pie es rgb(75,59,89) y el ambar encima da 4,88:1; bajo el
   eslogan, que cae en la columna de marca, el mosaico ni llega y el par es
   8,71:1 sobre --ink desnudo.

   Aun asi va a 20px/700, que pasa el umbral de texto grande de WCAG (18,66px
   en negrita, minimo 3:1). Un eslogan pide cuerpo, y deja margen si algun dia
   se reencuadra el mosaico: lo que no puede cambiar es que se mida antes. */
.footer-brand .footer-brand__slogan {
  margin-top: var(--s-5);
  font-size: 1.25rem;
  font-weight: 700;
  line-height: var(--lh-head);
  letter-spacing: var(--tr-head);
  color: var(--amber);
}
/* el descriptor sigue al eslogan: los dos son un bloque, no dos parrafos */
.footer-brand .footer-brand__slogan + p { margin-top: var(--s-2); }

.footer-title {
  margin-bottom: var(--s-4);
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--on-violet);
}
.footer-list li + li { margin-top: var(--s-3); }
.footer-list a { font-size: var(--fs-sm); }
.footer-bottom {
  display: flex; flex-wrap: wrap; gap: var(--s-4);
  align-items: center; justify-content: space-between;
  margin-top: var(--s-8); padding-top: var(--s-5);
  border-top: 1px solid rgb(255 255 255 / .16);
  font-size: var(--fs-xs);
  color: var(--on-violet-2);
}
/* La firma de Senavia, debajo del copyright. .footer-credit gana a `p + p` de base.css,
   que la separaria 1rem. El enlace va dentro de una frase y con el mismo color que el
   texto, asi que el subrayado es lo unico que lo distingue (WCAG 1.4.1): tiene que ir
   DESPUES de `.site-footer a`, que lo quita con la misma especificidad. */
.footer-credit { margin-top: var(--s-1); }
.footer-credit a { text-decoration: underline; text-underline-offset: .18em; }
.social { display: flex; gap: var(--s-4); }
.social a { display: grid; place-items: center; width: 2.75rem; height: 2.75rem; }
.social svg { width: 1.25rem; height: 1.25rem; fill: currentColor; }

/* ------------------------------------------------ el mosaico del pie
   El isotipo es un triangulo subdividido en triangulos. Aqui se pinta ENORME y
   recortado por los bordes del pie, para que se lea como una esquina de algo mucho
   mayor y no como una textura. Es el mismo SVG dos veces, girado distinto.

   Va en pseudo-elementos y no en markup porque el pie esta duplicado en las 8
   paginas, byte a byte: en CSS entra una vez y no se desincroniza.

   EL 26 % NO ES UN NUMERO DECORATIVO. Sobre --ink, el tinte mas claro del mosaico
   compuesto al 26 % deja el texto al 78 % en 6,2:1 y el anillo de foco ambar en
   4,3:1. El que rompe antes es el ANILLO (WCAG 1.4.11 le pide 3:1, no 4,5:1): a
   partir de 0,37 el mosaico incumple. Lo sujeta test/contraste.test.js, que lee
   esta cifra de aqui, asi que subirla rompe la build. Si hace falta que se vea
   mas, se cambia el encuadre, no la opacidad.

   Los apices van hacia FUERA: el tinte claro se sale de cuadro y el fragmento se
   disuelve en la tinta segun se acerca al texto. */
.site-footer::before,
.site-footer::after {
  content: "";
  position: absolute;
  z-index: 0;
  pointer-events: none;
  opacity: .26;
  aspect-ratio: 720 / 623.54;   /* el del SVG; alto derivado del ancho, nunca al reves */
  /* cover y no contain: con la caja y el viewBox en la misma proporcion son
     equivalentes, salvo que el redondeo deje medio pixel transparente en un lado.
     En un fragmento que sangra, recortar ese medio pixel es gratis; el hueco se ve. */
  background: url('../images/footer-mosaic.svg') no-repeat center / cover;
}

/* Movil: solo el fragmento inferior izquierdo, y por debajo del bloque de
   direccion y horario. El segundo entra a partir de 48rem. */
.site-footer::before {
  left: -16vw;
  bottom: -26vw;
  width: clamp(15rem, 52vw, 22rem);
  transform: rotate(198deg);
}
.site-footer::after { display: none; }

@media (min-width: 48rem) {
  .site-footer::before {
    left: -10vw;
    bottom: -7vw;
    width: clamp(15rem, 26vw, 30rem);
  }
  .site-footer::after {
    display: block;
    right: -13vw;
    top: -11vw;
    width: clamp(20rem, 36vw, 46rem);
    transform: rotate(26deg) scaleX(-1);
  }
}

/* ------------------------------------------------- franja de logos (marquesina)
   Las 22 empresas donde trabajo la fundadora, en movimiento continuo. Cada
   celda es un .company: la marca arriba y el nombre debajo.

   EL ENCABEZADO SE VE. Dice "Companies Yohanna has worked with", no "our
   clients" ni "trusted by": son marcas de terceros y esa frase es lo unico
   que las situa como un hecho de la carrera de Yohanna y no como una cartera
   de clientes. Estuvo en .u-visually-hidden y se ha sacado a la vista porque
   el riesgo que dejaba abierto era de lectura: una fila de logos corporativos
   bajo el hero y sin pie se lee por convencion como clientela. Ahora de eso
   responde el propio h2, delante y a la vista, y por eso tiene que seguir
   diciendo exactamente lo que dice.

   Y LOS NOMBRES VAN EN TIPOGRAFIA dentro de cada celda, no solo en el alt.
   Las 22 tienen ya su marca, pero el nombre se queda por tres motivos: media
   docena de estos logos son monogramas sin palabra -Trazza, Dell, HP, AT&T- y
   en gris al 58 % no los identifica nadie; la lista es dato editorial y
   cualquier alta futura puede llegar sin fichero; y el alt va vacio a
   proposito, porque el nombre ya esta al lado y un alt con texto haria que un
   lector de pantalla dijera cada empresa dos veces.
   Es texto de verdad, en --mute (6,79:1 sobre --paper-2) y no bajado con
   opacidad, que es lo que se le hace a un logo y no se le puede hacer a una
   palabra que hay que leer.

   Esta franja sustituyo a la lista .wordmarks en la home, y .company-grid la
   sustituye tambien en leadership.html: .wordmarks se quedo sin un solo uso
   en el repositorio y se borro con este cambio.

   Sin flechas ni puntos a proposito: no es contenido que haya que recorrer,
   es fondo de credibilidad. La unica interaccion es parar al pasar el raton
   para poder mirar uno.

   LAS ALTURAS NO SON IGUALES, y es deliberado. Se renderizo cada SVG, se
   midio el area de tinta real y se interpolo a medias (media geometrica)
   entre "misma altura" y "misma area de tinta":
     - con misma altura, el circulo macizo de Dell pesa ~4x lo que el
       logotipo de Oracle, que es una linea de letras finas;
     - con misma area, Oracle bajaba a 13 px de alto y dejaba de leerse.
   Y ademas --k corrige el RELLENO INTERNO del fichero: se mide la tinta,
   pero quien recibe la altura es la caja del <img>. El SVG de Cisco trae un
   13 % de aire dentro del viewBox y sin esa correccion se veia un 13 % mas
   pequeno que el resto; los otros nueve vienen a hueso.

   El resultado por logo va en --k, inline en el HTML, junto al logo que
   describe. Hay que RECALCULARLO si se cambia algun SVG, porque depende del
   recorte del fichero y no de la marca: se dibuja cada logo en un canvas
   normalizado a 100 px de tinta, se mide area y caja, se interpola y se
   divide por la fraccion de alto que ocupa la tinta.

   DOS EXCEPCIONES MEDIDAS A OJO, y las dos por el mismo motivo: son los unicos
   lockups APILADOS. La formula los compara con logotipos horizontales, que son
   anchos y bajos, y al apilado le sale un alto ridiculo.
     - AT&T (globo arriba, nombre debajo): la formula le daba 26 px de alto y 19
       de ancho, ilegible. Va a 1.45, que lo pone a la altura de los otros dos
       marcos redondos, Dell y HP.
     - Tech.us ("tech" arriba, ".us" debajo): la formula le daba 1.102, o sea
       35 px. Va a 1.41, que lo deja en 45 px de tinta, la misma que AT&T.
   La banda mide 3rem (48 px), asi que ningun --k de un apilado puede pasar de
   1.5. Cualquier logo apilado que se anada tendra el mismo problema, la misma
   solucion y el mismo techo.
   -------------------------------------------------------------------------- */
/* El encabezado ya no esta oculto, asi que necesita separarse de la cinta:
   pegados, la entradilla parecia el pie de la primera fila de logos. */
.clients > .u-page { margin-bottom: var(--s-6); }

.clients {
  background: var(--paper-2);
  padding-block: clamp(var(--s-6), 4vw, var(--s-8));
  /* corta el track, que es mas ancho que la pagina, antes de que llegue a
     provocar scroll horizontal en el documento */
  overflow: hidden;
}


.clients__viewport {
  /* El desvanecido lateral es funcional, no adorno: sin el, los logos se
     cortan a hachazo contra el borde de la pantalla al entrar y salir. */
  --fade: clamp(1.5rem, 6vw, 5rem);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--fade), #000 calc(100% - var(--fade)), transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 var(--fade), #000 calc(100% - var(--fade)), transparent 100%);
}

.clients__track {
  display: flex;
  width: max-content;
  will-change: transform;
}

/* TRES tandas identicas, no dos. El bucle desplaza el track un tercio de su
   ancho, o sea exactamente una tanda, asi que por detras del borde derecho
   tiene que quedar siempre al menos una tanda entera.

   Con las celdas de .company una tanda mide 3494 px en escritorio (medido a
   1440: 22 celdas a su ancho de contenido mas 22 huecos de 56 px), asi que con
   tres copias el techo esta en un viewport de 2*3494 = 6988 px CSS. Con diez
   logos sueltos la tanda media 1410 px y el techo, 2820, se agotaba en un 4K a
   escala 100 %; 6988 cubre de sobra un 4K y aun un 5K. Crecer la lista ENSANCHA
   la tanda, o sea que sube el techo: anadir empresas es seguro. Encogerla no:
   si algun dia se quedan menos de ~10, hay que volver a mirar este numero.

   OJO: la tanda cambia de ancho tambien SIN tocar la lista, porque la celda se
   ajusta a su contenido. Cambiar un logo por otro mas ancho, o una celda de
   texto por una con marca, la mueve. Se mide y se recalcula la duracion. */
.clients__row {
  --clients-gap: clamp(2rem, 5vw, 3.5rem);
  display: flex;
  /* stretch y no center: cada celda mide lo que la mas alta de su fila, y es
     .company quien coloca dentro. Con center, una celda de nombre corto se
     centraria dentro de esa altura y bajaria su logo Y su nombre respecto a
     la celda cuyo nombre parte en dos lineas: se irian las dos bandas a la vez. */
  align-items: stretch;
  gap: var(--clients-gap);
  /* el hueco final va DENTRO de la tanda: asi las tres miden exactamente lo
     mismo y el -33.3333% cae en el inicio de la siguiente, no a medio hueco */
  padding: 0 var(--clients-gap) 0 0;
  margin: 0;
  list-style: none;
  flex: 0 0 auto;
}


/* El sitio anade movimiento bajo no-preference en vez de quitarlo bajo
   reduce (misma convencion que .timeline en pages.css). */
@media (prefers-reduced-motion: no-preference) {
  /* 150s, no 60s. Lo que manda es la VELOCIDAD LINEAL, no la duracion: 23,5 px/s
     es lo que daban diez logos en 60s y es lo que deja leer un nombre al pasar.
     La tanda mide 3494 px medidos a 1440, asi que 3494 / 23,5 = 149s, que se deja
     en 150 (23,3 px/s, dentro del 1 %). Si cambia el numero de empresas O el ancho de las celdas,
     se vuelve a medir la tanda y se recalcula: a 60s esto iria a 57 px/s y los
     nombres -que antes no existian- pasarian sin darte tiempo. */
  .clients__track { animation: clients-marquee 150s linear infinite; }
  .clients:hover .clients__track,
  .clients:focus-within .clients__track { animation-play-state: paused; }
}

/* Quieto no puede significar inaccesible. Antes la cinta pasaba a deslizarse
   a mano, pero con 22 celdas una tanda mide 2633 px a 375: siete pantallas de
   arrastre para llegar a la ultima empresa, y nadie llega. Se pliega, que es
   exactamente lo que hace .company-grid en /leadership. El desvanecido lateral
   se quita: plegado no entra ni sale nada por los bordes y solo taparia la
   primera y la ultima celda de cada fila. */
@media (prefers-reduced-motion: reduce) {
  .clients__viewport {
    -webkit-mask-image: none;
            mask-image: none;
  }
  .clients__track { width: auto; }
  .clients__row {
    flex-wrap: wrap;
    justify-content: center;
    row-gap: var(--s-6);
    padding-right: 0;   /* el hueco de costura solo sirve con el bucle andando */
  }
  .clients__row + .clients__row { display: none; }
}

@keyframes clients-marquee {
  from { transform: translate3d(0, 0, 0); }
  /* calc(-100% / 3), no -33.3333%: el literal deja 0,01 px de desajuste
     contra el ancho de una tanda y el bucle podria enseñar una costura de
     un pixel al reiniciar. Dividido, es exacto a cualquier ancho. */
  to   { transform: translate3d(calc(-100% / 3), 0, 0); }
}

/* ------------------------------------------------ la celda de una empresa
   UNA sola celda para los dos sitios donde salen las empresas: dentro de la
   marquesina de la home y dentro de .company-grid en /leadership. La
   presentacion cambia, los datos no.

   No hay forma de compartir la lista: no hay build, no hay CMS, y la regla de
   la casa es que la visibilidad del contenido no dependa de JavaScript. Las
   dos listas son markup duplicado, igual que ya lo son el nav y el pie. Cada
   una lleva un comentario apuntando a la otra.

   Las DOS MEDIDAS viven en el padre y no en .company, porque .company-grid
   necesita --company-w para su propio grid-template-columns y una custom
   property no se lee hacia arriba. Si algun dia hay un .company fuera de
   estos dos padres, hay que anadir su contenedor a esta lista. */
.clients__row,
.company-grid {
  --company-slot: 3rem;   /* banda reservada a la marca. AT&T mide 46,4 px a 1440 */
  --company-w:   11rem;   /* ancho de celda. Oracle mide 170,7 px a 1440 y es el mas ancho */
}

.company {
  display: grid;
  grid-template-rows: var(--company-slot) auto;
  /* start, NO center. La fila es align-items:stretch, o sea que todas las
     celdas miden lo que la mas alta. Con center, una celda de nombre corto se
     centraria dentro de esa altura y bajaria su marca y su nombre ~9 px
     respecto a la celda cuyo nombre parte en dos lineas: se romperian las dos
     bandas a la vez, y a 150s de recorrido un nombre que se hunde al pasar se
     ve como lo que seria, un fallo. Con start, la marca arranca siempre en 0
     y el nombre siempre debajo de la banda, parta el nombre o no. */
  align-content: start;
  justify-items: center;
  gap: var(--s-2);
  /* ANCHO DE CONTENIDO, no fijo, y --company-w pasa a ser solo el tope.
     Con 11rem clavadas y el contenido centrado, el hueco de CAJA salia
     perfecto (56 px siempre) y el hueco OPTICO no: cada marca deja dentro de
     su propia celda el sobrante que no ocupa, asi que entre la tinta de HP
     (35 px de ancho) y la de AT&T habia 182 px, y entre Oracle (172 px) y
     Google 56. Mas del triple de diferencia leyendo la misma fila.
     Ajustando la celda a su contenido, ese sobrante desaparece y el ritmo lo
     marca el hueco, que es el mismo para todas. El tope sigue haciendo falta:
     un nombre largo sin el se iria a 230 px y no partiria nunca de linea. */
  width: max-content;
  max-width: var(--company-w);
  text-align: center;
}

.company__logo {
  --lh: clamp(1.5rem, 1.15rem + 1.1vw, 2rem);   /* 24 -> 32 */
  height: calc(var(--lh) * var(--k, 1));
  width: auto;
  /* la banda mide 3rem y cada marca su propio alto: se centran entre ellas */
  align-self: center;
  /* la celda mide 11rem clavadas. Si un SVG futuro sale mas ancho, el
     max-width del reset lo recorta, y con el height fijo del --k ese recorte
     lo APLASTARIA en vez de encogerlo. contain lo encaja. El arreglo de
     verdad, si pasa, es subir --company-w y no tocar el --k. */
  object-fit: contain;
  /* Gris y bajados de intensidad: son respaldo de fondo, no reclamos. El
     color vuelve al pasar el raton, que es tambien cuando se para la cinta. */
  filter: grayscale(1);
  opacity: .58;
  transition: filter var(--dur-2) var(--ease-out), opacity var(--dur-2) var(--ease-out);
}

@media (hover: hover) {
  .company__logo:hover { filter: none; opacity: 1; }
}

.company__name {
  /* Fila 2 SIEMPRE, y a mano. En una celda sin <img> el colocado automatico
     mete el nombre en la banda de la marca y su linea base sube 56 px respecto
     a la de al lado. Puesto aqui y no en .company--text, la colocacion sigue
     siendo correcta aunque alguien se deje la clase modificadora. */
  grid-row: 2;
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: -0.01em;
  /* --mute, NO opacidad. Sobre --paper-2 da 6,79:1 y cumple AA como texto; el
     mismo --ink al 58 % que llevan los logos daria 4,36:1 y no llega. Una
     imagen no tiene que cumplir el minimo de texto; un nombre escrito si. */
  color: var(--mute);
  /* --lh-body (1,62) abre 24,3 px por linea y un nombre de dos palabras se
     desparrama; ademas encarece cada salto de linea dentro de la rejilla. */
  line-height: 1.25;
  text-wrap: balance;   /* si parte en dos, que parta por la mitad */
}

/* .company--text, para una empresa sin marca utilizable. HOY NO LA USA NADIE:
   las 22 tienen logo. Se documenta porque la lista es dato editorial y la
   proxima alta puede llegar sin fichero, y porque conviene saber que ya
   funciona y no hay que inventarlo otra vez.
   La clase es un marcador de markup y NO lleva declaraciones a proposito: todo
   lo que hace falta para que el nombre caiga en su sitio esta en .company__name
   (grid-row: 2), y la banda de 3rem es una pista FIJA, asi que ocupa su alto
   haya algo dentro o no. Celda con logo y celda sin el miden igual. */

/* Las mismas celdas, quietas y en rejilla, para /leadership.
   El numero de columnas va a mano y nunca es 3: son 22 empresas (2 x 11), asi
   que con 2, 4 o 5 la ultima fila sale entera o a medias, y con 3 se queda con
   UNA sola celda y el 67 % del ancho vacio. Es el mismo defecto que ya obligo
   a retocar la difunta .wordmarks. */
/* En la rejilla es al reves que en la cinta: lo que se lee es la COLUMNA, y
   los nombres tienen que caer alineados unos debajo de otros. Asi que aqui la
   celda ocupa su pista entera en vez de encogerse a su contenido. */
.company-grid .company { width: 100%; max-width: none; }

.company-grid {
  display: grid;
  /* minmax(0, ...) y no la medida a secas: la celda cede ancho antes de
     desbordar. A 1440 el contenido de .u-page mide 1168 px y cinco celdas de
     11rem con --s-5 de hueco caben holgadas, pero a 1024 no, y sin minmax el
     desborde saldria por la derecha. */
  grid-template-columns: repeat(2, minmax(0, var(--company-w)));
  justify-content: center;
  gap: var(--s-6) var(--s-5);
}

@media (min-width: 48rem) {
  .company-grid { grid-template-columns: repeat(4, minmax(0, var(--company-w))); }
}

@media (min-width: 64rem) {
  /* Cinco y no seis: a 1024 el contenido mide 947 px y seis columnas dejarian
     la celda en 138 px, por debajo de los 158 que mide Oracle ahi. Se
     recortaria justo el logo que ya es el mas dificil de leer. */
  .company-grid { grid-template-columns: repeat(5, minmax(0, var(--company-w))); }
}

/* ------------------------------------- las facetas de los planos violeta
   Hermano del mosaico del pie, y su OPUESTO. Sobre --ink el mosaico aclara;
   sobre --violet hundir es lo unico que se puede hacer sin pagar contraste.

   POR QUE NO SE COPIA EL RECURSO DEL PIE. Medido, no supuesto: sobre violeta el
   que rompe primero NO es el anillo de foco sino el texto al 78 %, y las dos
   superficies violeta no comparten techo. Con un mosaico de tinte claro el hero
   aguanta hasta opacidad .22, pero el plano de las tarjetas solo .138, porque el
   velo blanco del 8 % de .value--on-violet SUMA su aclarado al del mosaico: el
   par de dentro de la tarjeta parte de 5,57 en vez de 6,33 y gasta 0,76 puntos
   antes de empezar. El .26 del pie trasplantado aqui deja esa entradilla en
   3,66:1 y el borde ambar de la tarjeta en 2,36:1. Incumple las dos.

   POR QUE ESTE SI VALE A CUALQUIER OPACIDAD. images/facet-violet.svg esta hecho
   con la rampa --violet -> --violet-deep. Todas sus celdas tienen luminancia
   menor o igual que el plano, asi que componerlas solo puede SUBIR el contraste:
   a la opacidad que se envia (.62) el texto al 78 % pasa de 6,33 a 7,98 sobre el plano y
   de 5,57 a 6,88 dentro de la tarjeta, y el borde ambar de 3,92 a 4,96. En el PEOR pixel
   la ganancia es cero, porque la celda del apice ES --violet: el minimo del sistema lo
   sigue marcando el plano desnudo, y por eso la puerta mide celda a celda. Por eso el recurso puede pasar
   POR DEBAJO de las tarjetas sin recortarlo, que era la otra salida y costaba
   markup. Lo sujeta test/contraste.test.js midiendo el apilado de tres capas.

   Los tintes claros del logo NO son intercambiables aqui: #8243B8 tiene el doble
   de luminancia que --violet y al 100 % ya incumple; #6215A8 ES --violet.
   -------------------------------------------------------------------------- */
.hero, .plane-violet, .page-head { position: relative; isolation: isolate; }

/* LAS TRES lo necesitan, .plane-violet incluida. Su clip-path de .notch-tr recorta
   lo que se PINTA, pero no quita al pseudo-elemento del area de scroll: medido, sin
   esta linea el documento se iba 55px a 375 y 243px a 1920. Y no vale arreglarlo con
   overflow-x en html/body, porque la cabecera es sticky y scroll-padding-top vive en
   :root: eso romperia las anclas de /services. clip y no hidden, por lo mismo que el
   pie — hidden convierte la seccion en contenedor de scroll y al tabular hacia dentro
   el navegador puede desplazarla. */
.hero, .plane-violet, .page-head { overflow: hidden; overflow: clip; }

.hero > *, .plane-violet > *, .page-head > * { position: relative; z-index: 1; }

/* Y el copy tambien, por su cuenta: .hero__copy lleva container-type, que implica
   contencion de layout y por tanto ES un contexto de apilamiento propio. Dentro de el
   su ::after posicionado pinta por delante del texto en flujo, asi que sin esta linea
   la faceta de movil sale ENCIMA del titular y del boton ambar. */
.hero__copy > * { position: relative; z-index: 1; }

/* El hero necesita DOS anclajes porque cambia de forma con el ancho, y el resto no.
   Por debajo de 56rem es UNA columna, asi que .hero abarca el copy Y la fotografia:
   anclar por bottom al hero deja la faceta detras de la foto, que es exactamente
   donde no se ve. A ese ancho cuelga del propio bloque de copy, que es el unico que
   lleva violeta. Por encima de 56rem el copy es la columna izquierda y el bottom del
   hero ya es el bottom del plano, asi que vuelve a .hero para poder sangrar por el
   borde de la ventana: .hero__copy tiene max-width y esta metido hacia dentro (96px
   a 1440, 336px a 1920), y recortar ahi dejaria un corte vertical a media pantalla. */
.hero__copy { position: relative; }

.hero__copy::after,
.hero::after,
.plane-violet::after,
.page-head::after {
  content: "";
  position: absolute;
  z-index: 0;
  pointer-events: none;
  opacity: .62;
  aspect-ratio: 720 / 623.54;   /* el del SVG; alto derivado del ancho, nunca al reves */
  background: url('../images/facet-violet.svg') no-repeat center / cover;
}

/* Las tres superficies tienen el mismo hueco: el texto se acaba mucho antes que
   el plano. En .page-head y .plane-violet ese hueco es la MITAD DERECHA (51 % y
   60 % libres a 1440), asi que la faceta entra por ahi. Ojo, no nace del chaflan:
   ninguna .page-head lleva clase notch-*, y en .plane-violet el chaflan es notch-tr,
   arriba a la derecha, mientras la faceta entra por abajo. El
   hero es la excepcion: a la derecha esta la fotografia, de modo que alli entra
   por abajo a la izquierda, en la banda de 115 px que queda bajo los botones. */
/* EL INSET SE CONGELA DONDE SE CONGELA EL ANCHO. El ancho topa con el maximo del
   clamp, asi que si el desplazamiento sigue en vw puro son dos escalas distintas en la
   misma regla y el encuadre se desliza fuera segun crece la ventana. Medido con la
   version anterior en .page-head: ocupaba el 85 % de la banda a 1440, el 63 % a 1920,
   el 28 % a 2560 y el 0 % a 3440, donde la faceta desaparecia entera de las siete
   interiores. El max() deja mandar al vw por debajo del cruce —o sea que de 375 a
   1524 no cambia ni un pixel— y congela por encima. La fraccion de --w es el valor
   que tiene el vw JUSTO en el cruce, asi que la transicion es continua y no hay salto
   a ningun ancho. */
.page-head::after {
  --w: clamp(18rem, 42vw, 40rem);
  width: var(--w);
  right: max(calc(var(--w) * -.286), -12vw);
  top: max(calc(var(--w) * -.429), -18vw);
  transform: rotate(18deg);
}

.plane-violet::after {
  --w: clamp(20rem, 52vw, 58rem);
  width: var(--w);
  right: max(calc(var(--w) * -.192), -10vw);
  bottom: max(calc(var(--w) * -.192), -10vw);
  transform: rotate(-8deg) scaleX(-1);
}

.hero__copy::after {
  --w: clamp(17rem, 76vw, 26rem);
  width: var(--w);
  /* Tres regimenes en una linea, y los tres hacen falta. De 375 a 547 manda el vw. De
     547 a ~600 el ancho ya topo en 26rem y congela el inset, como en las otras tres.
     Y de 624 en adelante manda el tercer termino: .hero__copy tiene max-width 39rem y
     margin-left auto, asi que deja de llenar la ventana y se va a la derecha llevandose
     la faceta con el — a 820 lo pintado arrancaba en x=190, sin morder ningun borde, y
     se leia como un sello y no como una esquina. El termino deshace ese desplazamiento
     y sangra 7rem mas, de modo que el corte por la izquierda se mantiene hasta que a
     56rem toma el relevo .hero::after. min() y max() hacen las dos transiciones
     continuas: no hay salto a ningun ancho, y por eso no hace falta media query. */
  left: min(max(calc(var(--w) * -.211), -16vw), calc(var(--w-page) / 2 - 100vw - 7rem));
  bottom: max(calc(var(--w) * -.158), -12vw);
  transform: rotate(202deg);
}
.hero::after { display: none; }

@media (min-width: 56rem) {
  /* Por encima de 56rem el hero parte en dos columnas y la faceta se queda en la
     violeta: la foto empieza exactamente en el 50 %. */
  .hero__copy::after { display: none; }
  .hero::after {
    display: block;
    --w: clamp(18rem, 34vw, 40rem);
    width: var(--w);
    left: max(calc(var(--w) * -.294), -10vw);
    bottom: max(calc(var(--w) * -.235), -8vw);
    transform: rotate(202deg);
  }
}

/* En forced-colors el navegador fuerza background-color y color, pero NO quita
   background-image: las facetas seguirian pintando sus violetas cableados sobre el
   Canvas del sistema. Y ahi hundir SI cuesta, porque el primer plano pasa a ser oscuro:
   negro sobre la celda mas profunda al .62 da 4,53:1, y a opacidad 1 cae a 1,46:1. Es
   decoracion pura y en ese modo no aporta nada, asi que se retira entera, tambien la
   del pie. */
@media (forced-colors: active) {
  .hero__copy::after,
  .hero::after,
  .plane-violet::after,
  .page-head::after,
  .site-footer::before,
  .site-footer::after { display: none; }
}
