
/* Tokens. Ver DESIGN.md. */
:root{
  --tinta:       oklch(0.18 0.004 90);
  --papel:       oklch(1 0 0);           /* el fondo de la pagina es blanco */
  /* El gris de superficie salió del sitio el 9 de septiembre: al cliente no
     le gustó. Donde había un plano gris ahora hay blanco y un filete, y donde
     hacía falta una superficie tibia se usa --vino-tenue. El token se
     queda definido porque sigue sirviendo de referencia para mezclas, no como
     fondo de nada. */
  --obra:        oklch(0.962 0.002 90);
  --cemento:     oklch(0.50 0.004 90);   /* texto secundario, AA sobre papel */
  --linea-suave: oklch(0.80 0.003 90);   /* filetes, no lleva texto encima */
  --grafito:     oklch(0.32 0.004 90);

  /* Rojo vino. Sustituye a la vino el 11 de septiembre; antes de ella
     estaban la arena y el #CBBD93. La base cumple AA en las dos direcciones en
     que aparece un realce, escrita sobre blanco y como fondo con blanco
     encima: 9.91:1 en los dos casos, muy por encima del 4.5 que pide la norma.
     Al ser bastante mas oscura que la vino, ya no hay ninguna
     combinacion del sitio que se quede corta. Medido, no elegido a ojo. */
  --vino:       oklch(0.398 0.122 13.6);  /* #7B2233 */
  --vino-honda: oklch(0.318 0.100 13);    /* #5A1523, el hover */
  --vino-tenue: oklch(0.962 0.013 14);    /* #FBEFF0, fondos de aviso */
  --vino-filo:  oklch(0.72 0.085 14);     /* #D48F94, filetes de realce */
  /* Relleno de los estados marcados en el mapa. Estaba sin definir: el fill se
     quedaba en el valor heredado, que es negro, y por eso los estados salian
     casi del color de su propio contorno. */
  --destaque:        var(--vino);

  --filete: 1px;
  /* Dos familias con papeles distintos.

     Texto corriente: IBM Plex Sans. Es plana, de trazo casi sin modulación, y
     sobria sin ser anónima: la dibujó IBM para su propia documentación técnica
     y tiene carácter propio. No es ninguna de las que delatan una plantilla
     genérica —Inter, Roboto, Open Sans, Lato—, que están descartadas en la
     tabla de anti-patrones.

     Títulos grandes: Cormorant Garamond, en su peso ligero. Es lo más cercano
     que hay, ya dibujado y completo, a la letra del logo: romano de trazo
     capilar, remates finos y mucho contraste. La Euro Roman de verdad se probó
     y se descartó, ver DESIGN.md. */
  --texto: 'IBM Plex Sans', ui-sans-serif, system-ui, sans-serif;
  --display: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;

  --marca-tres: none;          /* none | block. Enciende + TRES en todo el sitio. */
  --marca-alto: 20px;
  --marca-tres-escala: 0.5;
  --marca-hueco: 0.30;

  --col: clamp(1.25rem, 4vw, 3.5rem);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;overflow-x:clip}
body{
  margin:0; background:var(--fondo); color:var(--tinta);
  /* Las entradas laterales empujan las imágenes fuera del borde antes de revelarse.
     Se recorta con clip y no con hidden: hidden rompería el rótulo pegajoso de la
     dirección Plano, que usa position:sticky. */
  overflow-x:clip;
  font-family:var(--texto); font-size:16.5px; line-height:1.62;
  font-synthesis-weight:none; -webkit-font-smoothing:antialiased;
}
img,video{display:block;max-width:100%}
a{color:inherit}
h1,h2,h3,h4{margin:0;font-weight:500;line-height:1.18;letter-spacing:-.006em}
/* Titular de sector que lleva las dos frases y no baja ninguna a apunte:
   va más chico para que no se amontone. Las dos clases juntas y el elemento
   delante, porque con solo h1.titular--largo empataba en especificidad con
   h1.titular y ganaba el que va después, que siempre es el otro. */
h1.titular.titular--largo{font-size:clamp(1.65rem,3.1vw,2.5rem);max-width:26ch}
p{margin:0}
ul{margin:0;padding:0;list-style:none}
:focus-visible{outline:2px solid var(--vino);outline-offset:3px}

.envoltura{width:min(1360px, calc(100% - var(--col) * 2));margin-inline:auto}
.angosto{width:min(74ch, calc(100% - var(--col) * 2));margin-inline:auto}
.num{font-variant-numeric:tabular-nums lining-nums}

/* Marca */

.marca{display:inline-flex;flex-direction:column;align-items:center;width:max-content;
  gap:calc(var(--marca-alto) * var(--marca-hueco));text-decoration:none;line-height:0}
.marca__wordmark{height:var(--marca-alto);width:auto}
/* Se dimensiona por altura, a la mitad de TANTUM. Con width:100% quedaba
   estirada al ancho del logo y más alta que él. */
.marca__tres{display:var(--marca-tres);
  height:calc(var(--marca-alto) * var(--marca-tres-escala));width:auto}
.marca--con-tres .marca__tres{display:block}
.marca--sin-tres .marca__tres{display:none}
.marca--izq{align-items:flex-start}
.marca--pie{--marca-alto:16px}
.marca--claro img{filter:invert(1)}


/* Huecos de imagen. Cada uno lleva rotulado el archivo que espera.
   El hueco es un plano tibio y no gris: fuera del sitio el gris, un marco sin
   foto tiene que seguir viéndose contra el blanco, y el único plano claro que
   queda en la paleta es el del vino rebajado. */
:root{--hueco:color-mix(in oklab,var(--vino) 6%,var(--papel))}
.foto{position:relative;overflow:hidden;background:var(--hueco);
  background-image:repeating-linear-gradient(135deg,transparent 0 11px,
    color-mix(in oklab, var(--cemento) 22%, transparent) 11px 12px);
  background-size:auto}
.foto::after{content:attr(data-archivo);position:absolute;inset:auto auto 0 0;
  font-size:.63rem;letter-spacing:.01em;padding:.28rem .5rem;color:var(--cemento);
  background:var(--papel);border-top:var(--filete) solid var(--cemento);
  border-right:var(--filete) solid var(--cemento);font-variant-numeric:tabular-nums}
.foto--muda{background-image:none;background:var(--hueco);
  box-shadow:inset 0 0 0 var(--filete) var(--linea-suave)}
.foto--muda::after{content:none}
.foto--puesta{background-image:none}
.foto--puesta::after{content:none}
.foto img{width:100%;height:100%;object-fit:cover}
.r32{aspect-ratio:3/2}.r43{aspect-ratio:4/3}.r11{aspect-ratio:1}
.r169{aspect-ratio:16/9}.r219{aspect-ratio:21/9}.r34{aspect-ratio:3/4}.r45{aspect-ratio:4/5}

/* Entrada de las imágenes al aparecer en pantalla. El estado oculto solo se aplica
   cuando hay JavaScript: sin él las fotos se ven de una vez, no desaparecen. */
.js .revelar{opacity:0}
.js .rev--sube{transform:translate3d(0,58px,0)}
.js .rev--izq{transform:translate3d(-58px,0,0)}
.js .rev--der{transform:translate3d(58px,0,0)}
.js .revelar.visto{opacity:1;transform:none;
  transition:opacity .9s ease, transform 1s cubic-bezier(.16,.7,.2,1)}

/* Deriva del hero: da movimiento a la imagen fija mientras llega el video.
   Va en lineal a propósito. Con ease-in-out pasaba casi todo el tiempo en los
   extremos, donde la velocidad es cero, y se percibía estática. */
@media (prefers-reduced-motion: no-preference){
  .hero-media img{animation:deriva 20s linear infinite alternate;transform-origin:50% 40%}
}
@keyframes deriva{
  from{transform:scale(1) translate3d(0,0,0)}
  to{transform:scale(1.18) translate3d(-2.4%,-1.8%,0)}
}

/* Video del hero. Si aún no hay archivo, se ve el hueco rotulado detrás. */
.hero-media{position:absolute;inset:0;overflow:hidden}
.hero-media img,.hero-media video{width:100%;height:100%;object-fit:cover;object-position:center 30%}
.hero-media video{position:absolute;inset:0}
@media (prefers-reduced-motion: reduce){
  .hero-media video{display:none}
  .js .revelar{opacity:1;transform:none}
  *{animation-duration:.001ms !important;transition-duration:.001ms !important}
}

/* Botones y enlaces de acción. Van en vino desde el principio y no solo
   al pasar el cursor: un botón que solo se distingue al tocarlo no se ve, y en
   una pantalla táctil no hay cursor que lo revele.

   El contorno se dibuja con currentColor, así que basta darle el color al
   texto. El botón del hero lleva el suyo escrito en el propio elemento, en
   blanco, porque ahí el fondo es un video oscuro y la vino no llega a
   contraste; ese estilo gana y el contorno lo sigue. */
.boton{display:inline-block;padding:.85rem 1.6rem;border:var(--filete) solid currentColor;
  color:var(--vino);background:var(--vino-tenue);
  text-decoration:none;font-size:.82rem;letter-spacing:.01em;font-weight:500;
  transition:background .18s ease, color .18s ease, border-color .18s ease}
/* Sobre el video del hero no cabe ni el relleno claro ni la vino: el
   blanco sobre un plano casi blanco no se lee, y la vino sobre el video
   oscuro tampoco. Ahí el botón es contorno blanco, y al pasar por encima sí
   se llena de vino, que con blanco encima cumple sobre cualquier fondo. */
.boton--claro{color:var(--papel);background:transparent}
/* El contorno se queda del color del texto que lo rodea: asi el boton del
   hero sigue leyendose en blanco sobre el video. La vino entra al pasar
   por encima, y en el boton lleno, que es el que manda en cada pagina. */
.boton:hover{background:var(--vino);color:var(--papel);border-color:var(--vino)}
.boton--lleno{background:var(--vino);color:var(--papel);border-color:var(--vino)}
.boton--lleno:hover{background:var(--vino-honda);border-color:var(--vino-honda)}

/* Formulario */
.form{display:grid;gap:1.4rem}
.form__par{display:grid;gap:1.4rem;grid-template-columns:1fr 1fr}
.campo{display:flex;flex-direction:column;gap:.42rem}
.campo label{font-size:.8rem;font-weight:500;color:var(--cemento)}
.campo label .req{color:var(--cemento)}
.campo input,.campo textarea{
  font:inherit;font-size:.95rem;color:var(--tinta);background:transparent;
  border:0;border-bottom:var(--filete) solid var(--cemento);padding:.55rem 0;
  border-radius:0;transition:border-color .18s ease}
.campo input:focus,.campo textarea:focus{outline:0;border-color:var(--vino)}
.campo textarea{resize:vertical;min-height:8.5rem}
/* Casilla de consentimiento. Va sin marcar de salida y es obligatoria: un
   consentimiento que viene marcado de fábrica no es un consentimiento, y sin
   permiso para usar el correo y el teléfono no hay con qué responder. Quien no
   quiera marcarla tiene el correo directo, que está al lado.

   No lleva la clase .campo a propósito. Esa pone los campos en columna y deja
   la etiqueta debajo del control, que es lo que se quiere en un campo de texto
   y justo lo contrario aquí. Teniendo las dos clases, la maquetación dependía
   de cuál ganara la cascada; sin .campo no hay nada que ganar. Las reglas van
   con el hijo directo por lo mismo: que no las pise el estilo de los campos. */
.campo--casilla{display:flex;align-items:flex-start;gap:.65rem;max-width:56ch}
.campo--casilla>input[type=checkbox]{appearance:auto;width:17px;height:17px;
  margin:.16rem 0 0;padding:0;border:0;border-radius:0;flex:0 0 17px;
  background:transparent;accent-color:var(--vino);cursor:pointer}
.campo--casilla>label{font-size:.86rem;color:var(--cemento);font-weight:400;
  line-height:1.5;cursor:pointer;margin:0}
.campo--casilla>input:focus-visible{outline:2px solid var(--vino);outline-offset:2px}
.form__aviso{font-size:.82rem;color:var(--cemento)}
.form__estado{font-size:.86rem;padding:.7rem 0;border-top:var(--filete) solid var(--cemento)}
.form__estado:empty{display:none}
.form__estado.ok{color:var(--tinta);font-weight:500}
.form__estado.error{color:oklch(0.45 0.14 28)}
.form.enviando{opacity:.6;pointer-events:none}
.form__aviso a{color:var(--vino)}
/* Enlaces dentro de un texto corrido: el aviso de privacidad, la nota del
   formulario y los párrafos de las semblanzas. En vino y subrayados, que
   es lo que hace reconocible un enlace sin depender del color. */
.cuerpo a,.entrada a,.rotulos a,.pildora__c a{color:var(--vino);
  text-decoration:underline;text-underline-offset:3px}

/* Pie */
/* El pie se va al negro de arriba abajo, suave y sin corte visible: el blanco
   de la pagina se mete un tercio dentro del degradado para que no haya una
   linea donde empieza. Lo que va escrito encima cambia de color con el fondo,
   asi que el texto de arriba es tinta y el de abajo es papel; el punto medio
   esta calculado para que ningun renglon caiga donde el contraste flaquea. */
/* El pie entra en negro por un degradado suave. La banda del degradado va
   antes del contenido y no debajo: escribir encima del propio degradado
   obligaba a acertar con el color de cada renglón según dónde cayera, y con el
   pie creciendo o encogiendo eso se rompe solo. Así hay una transición y, ya
   abajo, un fondo sólido sobre el que todo es blanco. */
.pie{position:relative;background:var(--tinta);color:var(--papel);
  padding:0 0 2.4rem;margin-top:0}
/* La banda de entrada al negro. Dos cosas la hacen suave y las dos hacen falta:
   es larga —más del doble que antes— y no es una rampa recta. Los pasos siguen
   una curva que arranca casi plana y se acelera al final, que es como el ojo
   espera que oscurezca; una rampa lineal en sRGB oscurece demasiado pronto y se
   ve el punto donde empieza. La mezcla va en oklab, que reparte los pasos por
   luminosidad percibida y no por número. */
.pie::before{content:'';display:block;height:clamp(13rem,26vw,22rem);
  background:linear-gradient(180deg,
    var(--papel) 0%,
    color-mix(in oklab,var(--tinta)  2%,var(--papel)) 16%,
    color-mix(in oklab,var(--tinta)  7%,var(--papel)) 31%,
    color-mix(in oklab,var(--tinta) 16%,var(--papel)) 45%,
    color-mix(in oklab,var(--tinta) 30%,var(--papel)) 58%,
    color-mix(in oklab,var(--tinta) 48%,var(--papel)) 70%,
    color-mix(in oklab,var(--tinta) 68%,var(--papel)) 81%,
    color-mix(in oklab,var(--tinta) 86%,var(--papel)) 91%,
    var(--tinta) 100%)}
.pie__alto{padding-top:2.6rem}
.pie__alto{display:flex;flex-wrap:wrap;gap:2.5rem;justify-content:space-between;align-items:flex-start}
.pie__datos{display:grid;gap:.35rem;font-size:.92rem}
.pie__datos a{text-decoration:none;color:var(--vino)}
.pie__datos a:hover{text-decoration:underline;text-underline-offset:3px}
.pie__social{display:flex;gap:.6rem;margin-top:1rem}
:root{--linkedin:#0A66C2}
.pie__social a{width:38px;height:38px;display:grid;place-items:center;
  color:var(--linkedin);border:var(--filete) solid color-mix(in oklab,var(--linkedin) 45%,transparent);
  transition:background .18s ease, color .18s ease, border-color .18s ease}
.pie__social a:hover{background:var(--linkedin);color:var(--papel);border-color:var(--linkedin)}
.pie__social svg{width:15px;height:15px;fill:currentColor}
.pie__bajo{display:flex;flex-wrap:wrap;gap:1rem;justify-content:space-between;align-items:center;
  margin-top:2.6rem;padding-top:1.2rem;border-top:var(--filete) solid var(--linea);
  font-size:.78rem;color:var(--cemento)}
.pie__bajo a{text-decoration:none;color:var(--vino)}
.pie__bajo a:hover{text-decoration:underline;text-underline-offset:3px}
/* Lo que va sobre el negro del pie. Va al final del bloque a propósito: son
   anulaciones de las reglas de arriba, que dan por hecho fondo claro. */
.pie .marca img{filter:invert(1)}
/* Todo en blanco, del 14 de septiembre: el texto iba al 86% y al 66% y los
   enlaces en vino claro. Lo único que conserva su color es el círculo de
   LinkedIn, que lleva el azul de la marca.
   Y los enlaces subrayados siempre: en blanco sobre blanco, el color ya no los
   distingue del texto de al lado y el subrayado es lo único que queda. */
.pie__datos,.pie__datos a,.pie__bajo,.pie__bajo a{color:var(--papel)}
.pie__datos a,.pie__bajo a{text-decoration:underline;text-underline-offset:3px}
.pie__bajo{border-top-color:color-mix(in oklab,var(--papel) 22%,transparent)}

/* El interruptor de la vista previa de estados del mapa, escondido en la
   esquina de abajo a la derecha. Es para que el cliente pruebe las dos formas
   sin tocar el código, así que se ve lo justo para encontrarlo sabiendo que
   está: al 10% de opacidad, y entero al pasar por encima o al enfocarlo con el
   tabulador. Enfocable a propósito: esconderlo a la vista es lo que se pidió,
   esconderlo también del teclado sería otra cosa. */
.apagon{position:absolute;right:.55rem;bottom:.45rem;z-index:2;
  font:inherit;font-size:.7rem;line-height:1;
  background:0;border:0;padding:.45rem .5rem;cursor:pointer;
  color:var(--papel);opacity:.1;transition:opacity .2s ease}
.apagon:hover,.apagon:focus-visible{opacity:.85}
.apagon[aria-pressed="false"]{opacity:.06}
.apagon[aria-pressed="false"]:hover,.apagon[aria-pressed="false"]:focus-visible{opacity:.7}
.pie__social a{border-color:color-mix(in oklab,var(--linkedin) 62%,var(--papel))}

/* Navegación, base común */
.nav__lista{display:flex;gap:1.9rem;align-items:center}
.nav__lista>li{position:relative}
.nav__enlace{text-decoration:none;font-size:.87rem;font-weight:500;padding:.5rem 0;display:block}
/* La pagina en la que se esta, marcada con un filete de realce. Va en sombra
   interior y no en borde para no mover el renglon al encenderse. */
.nav__enlace[aria-current]{box-shadow:inset 0 -2px 0 var(--vino)}
.nav__sub{position:absolute;top:100%;left:-.9rem;min-width:15rem;padding:.4rem 0;
  background:var(--papel);border:var(--filete) solid var(--linea);
  opacity:0;visibility:hidden;transform:translateY(5px);transition:.16s ease;z-index:60}
li:hover>.nav__sub,li:focus-within>.nav__sub{opacity:1;visibility:visible;transform:none}
.nav__sub a{display:block;padding:.5rem .9rem;text-decoration:none;font-size:.84rem;color:var(--tinta)}
.nav__sub a:hover{background:var(--vino-tenue)}
/* Los últimos elementos del menú abren hacia la izquierda: si no, el desplegable
   se sale del borde derecho y genera scroll horizontal aunque esté oculto. */
.nav__lista>li:nth-last-child(-n+3)>.nav__sub{left:auto;right:-.9rem}
/* Selector de idioma. Va al final de la barra, separado por un filete, con el
   idioma en curso subrayado. Las siglas van en versalita óptica: en mayúsculas
   de caja alta a este cuerpo pesarían más que los propios enlaces del menú. */
.idiomas{display:inline-flex;align-items:center;gap:.15rem;margin-left:.85rem;
  padding-left:.85rem;border-left:var(--filete) solid currentColor}
.idiomas__op{font:inherit;font-size:.74rem;letter-spacing:.07em;font-weight:600;
  padding:.28rem .4rem;text-decoration:none;color:inherit;background:0;border:0;
  opacity:.55;transition:opacity .18s ease}
a.idiomas__op{cursor:pointer}
a.idiomas__op:hover{opacity:1}
.idiomas__op[aria-current]{opacity:1;text-decoration:underline;text-underline-offset:5px;
  text-decoration-thickness:var(--filete)}
.idiomas__op[aria-disabled=true]{opacity:.38;cursor:not-allowed}
.idiomas__op:focus-visible{outline:var(--filete) solid currentColor;outline-offset:2px}

.hamburguesa{display:none;background:0;border:0;cursor:pointer;color:inherit;
  width:44px;height:44px;padding:0;margin-right:-10px;
  align-items:center;justify-content:center;flex-direction:column;gap:5px}
.hamburguesa span{display:block;width:24px;height:2px;background:currentColor}

@media (max-width:1024px){
  .hamburguesa{display:flex}
  /* Sube su propia altura y además la de la cabecera. Con -102% quedaban
     asomando unos 59 px que tapaban el logo y el burger. */
  .nav{position:fixed;inset:var(--cab-alto) 0 auto 0;background:var(--papel);
    border-bottom:var(--filete) solid var(--linea);
    transform:translateY(calc(-100% - var(--cab-alto) - 8px));
    transition:transform .28s ease;max-height:80vh;overflow:auto;z-index:55}
  .nav.abierta{transform:none}
  .nav__lista{flex-direction:column;align-items:stretch;gap:0;padding:.6rem 0}
  .nav__enlace{padding:.8rem var(--col);color:var(--tinta)}
  .nav__sub{position:static;opacity:1;visibility:visible;transform:none;border:0;background:0;padding:0 0 .5rem}
  .nav__sub a{padding-left:calc(var(--col) + 1rem);color:var(--cemento)}
  .nav__idiomas{padding:.7rem var(--col) .2rem}
  .idiomas{margin:0;padding:0;border-left:0;border-top:var(--filete) solid var(--linea);
    padding-top:.7rem;width:100%}
  .idiomas__op{padding:.3rem .5rem .3rem 0;color:var(--tinta)}
  .form__par{grid-template-columns:1fr}
}

/* Un poco de nosotros: el mapa y las cifras que se cuentan solas.
   Todo el estado final está en el HTML y en el CSS base. El guion solo lo
   apaga cuando va a animarlo, así que sin JavaScript se ve el mapa marcado y
   las cifras en su número, no un cero. */
/* El mapa manda al centro y las cuatro cifras se reparten a su alrededor:
   años arriba a la derecha, estados a la derecha en medio, proyectos a la
   izquierda en medio y sectores abajo a la izquierda. Las de la izquierda van
   alineadas a la derecha y al revés, para que todas miren hacia el mapa. */
/* Quiénes somos: el texto ocupaba media caja y la otra media quedaba en
   blanco. La fotografía la llena, con el alto de la columna de texto —del
   encabezado al botón— y no con una proporción fija.
   El desvanecido no es una animación sino la propia imagen: una máscara la
   disuelve por su izquierda hasta dejar ver el fondo de la sección, que es
   papel. Como la máscara vive dentro de la columna de la foto, el blanco
   arranca justo donde terminan las letras y no llega a montarse encima ni del
   texto ni del botón. Sin hueco entre columnas: el hueco lo dibuja el propio
   desvanecido. */
/* La columna de la foto se estrechó el 17 de septiembre. Con el recuadro más
   angosto, "cubrir" lo llena con menos aumento y se recorta menos alto: de la
   vertical de Jaime Navarro se veía el 70% y ahora se ve el 87%, que es lo que
   hacía falta para que se entienda el volumen. */
.quienes{display:grid;grid-template-columns:minmax(0,1.24fr) minmax(0,.76fr);
  gap:0;align-items:stretch}
/* La foto no es un recuadro dentro del bloque: es el bloque por ese lado. Se
   sale hacia arriba y hacia abajo tanto como el aire del propio bloque, y por
   la derecha ocupa el margen del contenedor, que es exactamente lo que hay
   hasta el borde. Nunca más: por eso no puede provocar desplazamiento lateral. */
.quienes__foto{position:relative;min-height:20rem;
  margin:calc(-1 * var(--aire-bloque)) calc(-1 * var(--col)) calc(-1 * var(--aire-bloque)) 0}
/* Dos máscaras que se cruzan. La primera disuelve fuerte por la izquierda,
   donde están las letras, y la segunda recorta arriba y abajo. Cruzarlas con
   intersect y no sumarlas es lo que hace falta: sumadas, la parte opaca de una
   tapa el desvanecido de la otra y el borde vuelve a verse recto.
   El desvanecido de los otros tres lados es corto pero llega a transparente:
   si se quedara a medias habría una línea, que es justo lo que se quería
   quitar. Por la derecha es el más corto de los tres porque ahí la imagen ya
   muere en el borde de la pantalla y no hay ninguna línea que disimular; está
   solo por las pantallas anchas, donde el contenedor se topa antes del borde
   y sin él sí quedaría un corte recto. */
/* Y el encuadre, más arriba del centro: abajo solo hay maleza. */
.quienes__foto img{object-position:50% 38%}
.quienes__foto .foto{position:absolute;inset:0;aspect-ratio:auto;background:0;
  -webkit-mask-image:
    linear-gradient(90deg,transparent 0,transparent 5%,rgba(0,0,0,.26) 22%,
      rgba(0,0,0,.72) 42%,#000 62%,#000 97%,transparent 100%),
    linear-gradient(180deg,transparent 0,#000 8%,#000 92%,transparent 100%);
  -webkit-mask-composite:source-in;
  mask-image:
    linear-gradient(90deg,transparent 0,transparent 5%,rgba(0,0,0,.26) 22%,
      rgba(0,0,0,.72) 42%,#000 62%,#000 97%,transparent 100%),
    linear-gradient(180deg,transparent 0,#000 8%,#000 92%,transparent 100%);
  mask-composite:intersect}
/* En pantalla chica la foto va debajo del texto y ocupa todo el ancho: ahí el
   desvanecido se comería un tercio de la imagen sin separar nada. */
@media (max-width:900px){
  .quienes{grid-template-columns:1fr;gap:1.6rem}
  .quienes__foto{min-height:0;margin:0 calc(-1 * var(--col))}
  /* Aquí la foto va debajo del texto y a todo el ancho: el desvanecido fuerte
     de la izquierda se comería un tercio de la imagen sin separar nada. Queda
     solo el corto de los cuatro lados, que es lo que evita el borde recto. */
  .quienes__foto .foto{position:relative;aspect-ratio:16/10;
    -webkit-mask-image:
      linear-gradient(90deg,transparent 0,#000 7%,#000 93%,transparent 100%),
      linear-gradient(180deg,transparent 0,#000 8%,#000 92%,transparent 100%);
    -webkit-mask-composite:source-in;
    mask-image:
      linear-gradient(90deg,transparent 0,#000 7%,#000 93%,transparent 100%),
      linear-gradient(180deg,transparent 0,#000 8%,#000 92%,transparent 100%);
    mask-composite:intersect}
}

/* El mapa se quedó solo el 11 de septiembre: se fueron las tres cifras de
   alrededor y la lista de estados que se escribía al marcarlos. La única que
   sobrevive, la de proyectos, subió al lado del título. */
/* El título en un renglón y la cifra justo detrás, no colgada del borde
   derecho. Como van en la misma línea de base, la cifra se aplana: el número y
   su rótulo uno al lado del otro en vez de apilados. */
/* La cabeza, por encima del mapa pase lo que pase: ahí vive el botón de volver
   y ningún trozo de dibujo debe poder taparlo. */
.mapa__cabeza{position:relative;z-index:6;
  display:flex;align-items:baseline;justify-content:flex-start;
  gap:clamp(.9rem,2.4vw,1.8rem);flex-wrap:wrap}
#nosotros-mapa .titulo{max-width:none;font-size:clamp(1.25rem,2.35vw,1.95rem)}
.mapa__cabeza .cifra{background:0;padding:0;flex:0 0 auto;
  display:flex;align-items:baseline;gap:.45rem}
.mapa__cabeza .cifra b{font-size:clamp(1.35rem,2.4vw,2rem)}
.mapa__cabeza .cifra span{font-size:.8rem}
/* El mapa toma todo el ancho de la página y todo el alto que le quede: la
   sección mide la pantalla menos la barra, el título se lleva lo suyo y el
   resto de la fila es del mapa. Dentro de esa caja, el dibujo se ajusta solo
   —es lo que hace un SVG con su viewBox— y queda centrado sin deformarse, así
   que no hace falta saber aquí ni su proporción ni cuánto ocupa el título.

   Antes iba con esa cuenta a mano, el alto de la pantalla menos un apaño en
   rem, y encima un tope del 74% del ancho. El apaño había que corregirlo cada
   vez que cambiaba algo del título, y el tope dejaba el dibujo más estrecho
   que la página aunque sobrara sitio, que es lo que se veía. */
/* Alto exacto, no mínimo: con un mínimo, la fila del mapa se mide por lo que
   el dibujo pide y la sección crece hasta que asoma el pie. Con el alto puesto,
   la fila 1fr reparte lo que hay y el dibujo se ajusta a ello.
   Y poco aire arriba y abajo: cada píxel que se le quita al aire se lo lleva el
   mapa, que es lo que se quiere ver grande. */
#nosotros-mapa{height:calc(100svh - var(--cab-alto));
  padding-block:clamp(.9rem,1.8vw,1.6rem);
  display:grid;grid-template-rows:minmax(0,1fr)}
#nosotros-mapa .rejilla{align-items:stretch}
#nosotros-mapa .rejilla>div{display:grid;grid-template-rows:auto minmax(0,1fr);
  min-height:0}
.nosotros{display:grid;justify-items:center;align-content:stretch;
  margin-top:.7rem;min-height:0}
.mapa{opacity:1;width:100%;min-height:0}
.nosotros .num{font-variant-numeric:tabular-nums}
.js .mapa{opacity:0;transition:opacity .9s ease}
.js .mapa.dentro{opacity:1}
/* La cifra que queda al lado del titulo del mapa: el numero en vino y el
   rotulo en gris. */
.mapa__cabeza .cifra b{color:var(--vino)}
.js .mapa__cabeza .cifra{opacity:0;transform:translateY(9px);
  transition:opacity .45s ease, transform .5s cubic-bezier(.16,.7,.2,1)}
.js .mapa__cabeza .cifra.dentro{opacity:1;transform:none}
.mapa{position:relative}
/* Sin overflow visible. Con él, el dibujo acercado se pintaba fuera de su caja
   y, lo que es peor, seguía recibiendo el cursor ahí fuera: el contorno del
   estado ampliado se ponía por encima del botón de "Regresar al mapa" y se
   comía el clic. Era eso lo que hacía que el botón funcionara unas veces sí y
   otras no, según qué estado se hubiera abierto. */
.mapa svg{display:block;width:100%;height:100%}

/* ------------------------------------------------- mapa interactivo
   El acercamiento se hace con una transformación sobre el grupo que envuelve
   todo el dibujo, no cambiando el viewBox: así lo mueve el compositor y la
   animación no depende de cuántos contornos haya en pantalla. El grosor de
   los filetes no crece porque todos llevan vector-effect. */
.mapa__zoom{transform-box:view-box;transform-origin:0 0;
  transition:transform .85s cubic-bezier(.22,.61,.36,1)}
.js .mapa__grupo{cursor:pointer}
/* Todo lo que se dibuja encima del mapa se mide contra --esc, que es la escala
   del acercamiento en curso. Sin eso, el nombre del proyecto se multiplicaba
   por la escala: en un estado chico como Morelos el zoom pasa de ocho, y once
   píxeles de texto salían de noventa. Las líneas no lo necesitan: llevan
   vector-effect y no engordan. */
.mapa{--esc:1}
.mapa__punto{fill:var(--vino);stroke:var(--papel);stroke-width:1;
  r:calc(9px / var(--esc));
  vector-effect:non-scaling-stroke;transition:opacity .3s ease, r .3s ease}
/* El número de proyectos, dentro del punto. Se apaga con él. */
.mapa__cuantos{font-family:var(--texto);font-size:calc(10px / var(--esc));
  font-weight:600;fill:var(--papel);text-anchor:middle;dominant-baseline:central;
  pointer-events:none;transition:opacity .3s ease}
.js .mapa__cuantos{opacity:0}
.js .mapa__estado.puesto ~ .mapa__cuantos{opacity:1}
.mapa__grupo:focus{outline:0}
.mapa__grupo:focus-visible .mapa__punto{stroke:var(--vino);stroke-width:3}
/* El punto aparece con su estado: el guion marca el contorno y el punto es su
   hermano inmediato, así que basta seguirlo desde el CSS y no hay que tocar la
   coreografía de marcado. */
.js .mapa__punto{opacity:0}
.js .mapa__estado.puesto + .mapa__punto{opacity:1}
.js .mapa__grupo:hover .mapa__punto{r:calc(10.5px / var(--esc))}
/* Con el mapa acercado, los estados que no son el elegido se van casi del
   todo: se quedan como una sombra que sitúa al que sí está. */
.mapa--dentro .mapa__fondo{opacity:.12;transition:opacity .5s ease}
.mapa--dentro .mapa__grupo{opacity:0;pointer-events:none;transition:opacity .5s ease}
.mapa--dentro .mapa__grupo.elegido{opacity:1}
.mapa--dentro .mapa__grupo.elegido .mapa__punto,
.mapa--dentro .mapa__cuantos{opacity:0}

/* Los puntos de proyecto y sus etiquetas. Solo existen con el mapa acercado. */
.mapa__detalle{opacity:0;pointer-events:none;transition:opacity .4s ease .35s}
.mapa__detalle.puesto{opacity:1;pointer-events:auto}
.js .mapa__pin{cursor:pointer}
.mapa__pinta{fill:var(--vino);stroke:var(--papel);stroke-width:1.2;
  r:calc(5px / var(--esc));
  vector-effect:non-scaling-stroke;transition:r .2s ease}
.mapa__pin:hover .mapa__pinta,.mapa__pin:focus .mapa__pinta{r:calc(7px / var(--esc))}
.mapa__hilo{fill:none;stroke:var(--vino);stroke-width:1;
  vector-effect:non-scaling-stroke;opacity:.55}
.mapa__nombre{font-family:var(--texto);font-size:calc(11px / var(--esc));fill:var(--tinta);
  paint-order:stroke;stroke:var(--papel);stroke-width:calc(3px / var(--esc));
  stroke-linejoin:round}
.mapa__pin:hover .mapa__nombre,.mapa__pin:focus .mapa__nombre{fill:var(--vino)}
.mapa__pin:focus{outline:0}
.mapa__pin:focus-visible .mapa__pinta{stroke:var(--vino);stroke-width:3}

/* La marquesina de un proyecto, encima del mapa. Se arma al abrirla y se
   vacía al cerrarla: son noventa fotos entre todos los proyectos y no tiene
   sentido tenerlas puestas en la portada desde el principio. */
/* A la derecha y arriba, no centrada abajo: centrada tapaba justo el mapa, que
   es lo que se está mirando. Ahí solo cubre el margen que el acercamiento deja
   libre por ese lado. */
.mapa__tira{position:absolute;right:0;top:4%;
  width:min(23rem,42%);background:var(--papel);
  box-shadow:0 12px 40px rgba(0,0,0,.18);border:var(--filete) solid var(--vino-filo);
  padding:.55rem;display:grid;gap:.45rem;z-index:5}
.mapa__tira[hidden]{display:none}
.mapa__tira__t{font-size:.8rem;font-weight:600;color:var(--vino);
  display:flex;justify-content:space-between;gap:1rem;align-items:baseline}
.mapa__tira__t a{color:var(--vino);text-decoration:underline;text-underline-offset:3px}
.mapa__tira__n{font-weight:400;color:var(--cemento)}
/* La ficha entera es el enlace al proyecto, no solo el rótulo de la esquina:
   en el teléfono no hay cursor que pasar por encima y el primer toque abre la
   ficha, así que el segundo tiene que valer en cualquier parte de ella. */
.mapa__tira__ir{display:grid;gap:.45rem;text-decoration:none;color:inherit}
.mapa__tira__ir:hover .mapa__tira__t span:last-child{text-decoration:underline;
  text-underline-offset:3px}

/* Los proyectos de un estado, al pasar por encima sin entrar. */
.mapa__lista{list-style:none;margin:0;padding:0;display:grid;gap:.2rem}
.mapa__lista a{display:flex;align-items:center;gap:.55rem;text-decoration:none;
  color:var(--tinta);font-size:.78rem;line-height:1.25;padding:.22rem;
  border-radius:6px;transition:background .16s ease, color .16s ease}
.mapa__lista a:hover,.mapa__lista a:focus-visible{background:var(--hueco);color:var(--vino)}
.mapa__lista img{width:3.1rem;height:2.2rem;object-fit:cover;flex:0 0 auto;
  border-radius:4px;display:block}
.mapa__cinta{overflow:hidden}
.mapa__cinta>div{display:flex;gap:.45rem;width:max-content;
  animation:rodar calc(var(--piezas,6) * 3s) linear infinite}
.mapa__cinta img{height:clamp(4rem,7vw,5.6rem);width:auto;display:block}
.mapa__cinta:hover>div{animation-play-state:paused}

.mapa__volver{font:inherit;font-size:.8rem;font-weight:500;letter-spacing:.01em;
  color:var(--vino);background:transparent;border:var(--filete) solid var(--vino);
  padding:.4rem .9rem;border-radius:999px;cursor:pointer;
  transition:background .18s ease, color .18s ease}
.mapa__volver:hover{background:var(--vino);color:var(--papel)}
.mapa__volver[hidden]{display:none}

@media (prefers-reduced-motion: reduce){
  .mapa__zoom{transition:none}
  .mapa__cinta>div{animation:none}
}
.mapa__fondo path{fill:var(--mapa-tierra);stroke:var(--mapa-linea);stroke-width:1;
  vector-effect:non-scaling-stroke}
/* Sin punto encima: tapaba justo a los estados chicos, que es a los que se les
   quería ayudar. El realce es un filete más marcado en el propio contorno, que
   es lo que deja leer a la Ciudad de México sin cubrirla. */
.mapa__estado{fill:var(--destaque);stroke:var(--tinta);stroke-width:1.6;
  vector-effect:non-scaling-stroke;stroke-linejoin:round}
.js .mapa__estado{opacity:0;transition:opacity .42s ease}
.js .mapa__estado.puesto{opacity:1}
@media (prefers-reduced-motion: reduce){
  .js .mapa{opacity:1}
  .js .mapa__estado{opacity:1}
  .js .mapa__cabeza .cifra{opacity:1;transform:none}
}
/* Pantalla de escritorio pero baja, del tipo 1366x768: se aprieta el bloque
   para que, tras la bajada automática, quepan de una vez el encabezado, el
   título y el mapa entero. */
@media (min-width:901px) and (max-height:820px){
  /* Portátil de 1366x768: queda menos alto todavía. */
  .nosotros{margin-top:.5rem}
  #nosotros-mapa{padding-block:.8rem}
}

@media (max-width:900px){
  /* En pantalla chica el título necesita sus dos o tres renglones y la cifra
     baja debajo. El mapa recupera el ancho: con la mitad no se vería nada. */
  .mapa__cabeza{gap:.5rem 1rem}
  /* En pantalla chica manda el ancho y el alto lo pone el propio dibujo. */
  #nosotros-mapa{height:auto;min-height:0;grid-template-rows:auto;
    padding-block:var(--aire-bloque)}
  #nosotros-mapa .rejilla>div{grid-template-rows:auto auto}
  .mapa svg{height:auto}
  .mapa__cabeza .cifra b{font-size:clamp(1.5rem,6.5vw,2rem);line-height:1.1}
}

/* Áreas. Los renglones entran flotando hacia arriba con desvanecimiento, poco
   recorrido, y escalonados por nth-child. En pantalla chica no entran de golpe:
   los pone uno a uno el desplazamiento, así que ahí el escalonado sobra y se
   apaga, o cada renglón esperaría su turno dos veces.
   Sin JavaScript se ven todos, siempre. */
.js .area li{opacity:0;transform:translateY(9px);
  transition:opacity .5s ease, transform .55s cubic-bezier(.16,.7,.2,1)}
.js .area li.dentro{opacity:1;transform:none}
.js .area{transition:background .4s ease, box-shadow .4s ease}
@media (min-width:901px){
  .js .area.dentro li:nth-child(1){transition-delay:.04s}
  .js .area.dentro li:nth-child(2){transition-delay:.14s}
  .js .area.dentro li:nth-child(3){transition-delay:.24s}
  .js .area.dentro li:nth-child(4){transition-delay:.34s}
}
/* El recuadro blanco del área que toca, solo en móvil. */
@media (max-width:900px){
  .js .area.abierta{background:var(--papel);box-shadow:0 1px 0 var(--vino-filo),0 10px 30px rgba(0,0,0,.07)}
}
@media (prefers-reduced-motion: reduce){
  .js .area li{opacity:1;transform:none}
}

/* Equipo. Dejó de ser una lista de fichas abiertas el 9 de septiembre: ahora
   es una rejilla de retratos con el nombre debajo, y todo el texto se abre en
   un cuadro encima al pulsar el retrato o el nombre.

   Los cuatro en un renglón desde el 14 de septiembre. Iban dos y dos mientras
   faltaba una persona por publicar.

   Vive aquí, en la hoja común, y no en la de una dirección: .persona estaba
   definida por separado en Obra y en Plano, con declaraciones distintas, así
   que al colgar la animación de una de las dos se quedó solo en Plano. La
   animación existía, el guion ponía la clase, y en Obra no había nada que
   animar. */
/* Los retratos, en renglones de distinto largo pero todos del mismo tamaño.
   La rejilla tiene el doble de columnas que retratos caben en el renglón más
   largo, cada retrato ocupa dos, y el renglón que no llena empieza corrido:
   con dos arriba y tres abajo, los de arriba van en las columnas 2-3 y 4-5 y
   quedan centrados. El reparto lo dice EQUIPO_FILAS en contenido.py. */
.equipo{--equipo-hueco:clamp(1.1rem,2.4vw,1.9rem);
  display:grid;gap:calc(var(--equipo-hueco) * 1.5) var(--equipo-hueco);
  grid-template-columns:repeat(var(--columnas,6),1fr);margin-top:1.8rem}
.persona{grid-column:span 2}
.persona--abre-fila{grid-column:var(--col) / span 2}
.persona{margin:0;padding:0;border:0}
.persona__abre{display:grid;gap:.65rem;text-decoration:none;color:inherit}
/* El retrato entero, en tres cuartos. El recorte ya viene hecho de
   generar_retratos.py, a la altura del cierre del pantalón, así que aquí no
   hay que encuadrar nada: se enseña tal cual. Era un cuadro con encuadre de
   busto hasta el 14 de septiembre. */
.persona__abre .foto{aspect-ratio:3/4;border-radius:10px}
.persona__nombre{display:block;font-size:1.02rem;font-weight:600;line-height:1.25}
.persona__cargo{display:block}
.persona__abre:hover .persona__nombre{color:var(--vino)}
.persona__abre:focus-visible{outline:2px solid var(--vino);outline-offset:4px}

/* La ficha completa vive en la página, debajo de su tarjeta. Con guion se
   esconde y se abre dentro del cuadro; sin guion se queda a la vista y la
   rejilla pasa a una columna, que es la única forma de que un texto largo se
   lea en el sitio de una tarjeta.

   El reparto es el que tenía antes de pasar a rejilla: retrato a un lado y el
   texto al otro. Es lo que pidió el cliente conservar. */
.persona__ficha{display:grid;grid-template-columns:minmax(11rem,25%) 1fr;
  gap:clamp(1.4rem,3vw,2.6rem);align-items:start}
.persona__ficha .persona__nombre{font-size:clamp(1.4rem,2.6vw,1.9rem);font-weight:500;
  font-family:var(--display);line-height:1.18}
.persona__texto{display:grid;gap:1rem}
.persona__resumen{font-size:1.05rem}
.js .persona__ficha{display:none}
.js .retrato .persona__ficha{display:grid}
html:not(.js) .equipo{grid-template-columns:1fr}
html:not(.js) .persona,html:not(.js) .persona--abre-fila{grid-column:auto}
html:not(.js) .persona__ficha{margin-top:1.2rem}
@media (max-width:700px){
  .persona__ficha{grid-template-columns:1fr}
  .persona__retrato{max-width:12rem}
}

/* El cuadro. Mismo lenguaje que el visor de imágenes: fondo oscurecido, mando
   arriba a la izquierda, clic en el fondo para cerrar. Lo que cambia es que
   dentro va texto y no una imagen, así que el panel es claro y desplazable. */
.retrato{position:fixed;inset:0;z-index:210;display:grid;place-items:center;
  padding:4.5rem 1rem 2rem;background:color-mix(in oklab,var(--tinta) 90%,transparent);
  cursor:pointer}
.retrato[hidden]{display:none}
.js .retrato{opacity:0;transition:opacity .26s ease}
.js .retrato.puesto{opacity:1}
.retrato__panel{background:var(--papel);color:var(--tinta);border-radius:14px;
  width:min(56rem,94vw);max-height:86vh;overflow:auto;cursor:default;
  padding:clamp(1.5rem,3.2vw,2.8rem)}
.retrato__cerrar{position:fixed;top:1rem;left:1rem}
/* La animación que tenía la ficha, ahora al abrir el cuadro: el retrato se
   revela y los renglones entran desde la derecha, escalonados. La clase la
   pone el guion un cuadro después de mostrar el cuadro, para que la
   transición arranque desde el estado de partida y no se la salte. */
.js .retrato .persona__retrato .foto{opacity:0;transition:opacity .8s ease}
.js .retrato.anima .persona__retrato .foto{opacity:1}
.js .retrato .persona__texto>*{opacity:0;transform:translateX(30px);
  transition:opacity .6s ease, transform .75s cubic-bezier(.16,.7,.2,1)}
.js .retrato.anima .persona__texto>*{opacity:1;transform:none}
.js .retrato.anima .persona__texto>*:nth-child(1){transition-delay:.06s}
.js .retrato.anima .persona__texto>*:nth-child(2){transition-delay:.16s}
.js .retrato.anima .persona__texto>*:nth-child(3){transition-delay:.26s}
.js .retrato.anima .persona__texto>*:nth-child(4){transition-delay:.36s}
.js .retrato.anima .persona__texto>*:nth-child(5){transition-delay:.46s}
.js .retrato.anima .persona__texto>*:nth-child(6){transition-delay:.56s}
@media (prefers-reduced-motion: reduce){
  .js .retrato .persona__retrato .foto,.js .retrato .persona__texto>*{
    opacity:1;transform:none}
}

.js .persona .foto{opacity:0;transition:opacity .85s ease}
.js .persona.dentro .foto{opacity:1}
.js .persona__abre>span{opacity:0;transform:translateX(26px);
  transition:opacity .6s ease, transform .75s cubic-bezier(.16,.7,.2,1)}
.js .persona.dentro .persona__abre>span{opacity:1;transform:none}
.js .persona.dentro .persona__abre>span:nth-of-type(1){transition-delay:.05s}
.js .persona.dentro .persona__abre>span:nth-of-type(2){transition-delay:.15s}
@media (prefers-reduced-motion: reduce){
  .js .persona .foto,.js .persona__abre>span{opacity:1;transform:none}
}
@media (max-width:900px){
  /* En pantalla chica caben dos por renglón, y los cinco de corrido: a un
     tercio de 375 px un retrato es una miniatura. */
  .equipo{grid-template-columns:repeat(2,1fr)}
  .persona,.persona--abre-fila{grid-column:auto}
  .retrato{padding:4rem .7rem 1rem}
}

/* Marquesina de aliados. Hoy son recuadros con el nombre; mañana serán los
   logotipos y solo hay que cambiar lo de dentro de cada pieza. El gris sale de
   la propia paleta, subido lo justo para que el cuadrado se lea contra el fondo
   de la sección y no se pierda la forma. */
:root{
  --aliado-fondo: color-mix(in oklab, var(--vino) 10%, var(--papel));
  --aliado-linea: var(--vino-filo);
}
.desfile{overflow:hidden;margin-top:.4rem;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 5%,#000 95%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 5%,#000 95%,transparent)}
.desfile__cinta{display:flex;width:max-content;animation:desfilar 62s linear infinite}
.desfile__grupo{display:flex;gap:.9rem;padding-right:.9rem;margin:0;list-style:none}
.desfile__pieza{flex:0 0 auto;display:grid;place-items:center;text-align:center;
  width:11.5rem;height:5.4rem;padding:.6rem .9rem;line-height:1.25;
  font-size:.83rem;color:var(--cemento);
  background:var(--aliado-fondo);border:var(--filete) solid var(--aliado-linea)}
@keyframes desfilar{from{transform:translate3d(0,0,0)}to{transform:translate3d(-50%,0,0)}}
/* Se detiene al pasar por encima: si alguien quiere leer un nombre, puede. */
.desfile:hover .desfile__cinta,.desfile:focus-within .desfile__cinta{animation-play-state:paused}
@media (prefers-reduced-motion: reduce){
  .desfile{overflow:visible;-webkit-mask-image:none;mask-image:none}
  .desfile__cinta{animation:none;width:auto;flex-wrap:wrap}
  .desfile__grupo{flex-wrap:wrap;gap:.6rem;padding:0}
  .desfile__cinta .desfile__grupo:last-child{display:none}
}
@media (max-width:700px){
  .desfile__pieza{width:9.5rem;height:4.6rem;font-size:.78rem}
}

/* Visor de imágenes. Se abre al pulsar una foto de la galería de un proyecto:
   el fondo se oscurece, la imagen se ve grande y se pasa de una a otra con las
   flechas. Sin miniaturas: la retícula de la página ya cumple ese papel y
   repetirla dentro le quita sitio a lo que se vino a ver. */
.visor{position:fixed;inset:0;z-index:200;display:grid;place-items:center;padding:4.5rem 1rem 2rem;
  background:color-mix(in oklab,var(--tinta) 93%,transparent);cursor:zoom-out}
.visor[hidden]{display:none}
.js .visor{opacity:0;transition:opacity .28s ease}
.js .visor.puesto{opacity:1}
.visor__img{max-width:min(1400px,94vw);max-height:88vh;width:auto;height:auto;
  object-fit:contain;cursor:default;box-shadow:0 24px 70px rgba(0,0,0,.45)}
.visor__mandos{position:fixed;top:1rem;left:1rem;display:flex;align-items:center;gap:1rem;
  color:var(--papel);cursor:default}
.visor__cuenta{font-size:.82rem;font-variant-numeric:tabular-nums;
  color:color-mix(in oklab,var(--papel) 72%,transparent)}
.visor__boton{width:40px;height:40px;display:grid;place-items:center;cursor:pointer;
  background:transparent;border:var(--filete) solid color-mix(in oklab,var(--papel) 45%,transparent);
  color:var(--papel);border-radius:0;padding:0;transition:border-color .18s ease,background .18s ease}
.visor__boton:hover{background:color-mix(in oklab,var(--papel) 14%,transparent);border-color:var(--papel)}
.visor__boton:focus-visible{outline:var(--filete) solid var(--papel);outline-offset:3px}
/* La equis y las puntas se dibujan con filetes, no con caracteres: el mismo
   criterio que el enlace de regreso. */
.visor__cerrar::before,.visor__cerrar::after{content:'';position:absolute;width:15px;height:1.5px;
  background:currentColor}
.visor__cerrar{position:relative}
.visor__cerrar::before{transform:rotate(45deg)}
.visor__cerrar::after{transform:rotate(-45deg)}
.visor__flecha{position:fixed;top:50%;transform:translateY(-50%);width:52px;height:52px}
.visor__flecha--izq{left:1rem}
.visor__flecha--der{right:1rem}
.visor__flecha::before{content:'';width:13px;height:13px;
  border-left:1.5px solid currentColor;border-bottom:1.5px solid currentColor}
.visor__flecha--izq::before{transform:rotate(45deg) translate(2px,-2px)}
.visor__flecha--der::before{transform:rotate(-135deg) translate(2px,-2px)}
.visor__pie{position:fixed;left:0;right:0;bottom:6.2rem;text-align:center;font-size:.84rem;
  padding:0 5rem;color:color-mix(in oklab,var(--papel) 78%,transparent);cursor:default}
.galeria .foto--puesta{cursor:zoom-in}
/* Tira de miniaturas al pie del visor. El cliente la pidió el 11 de
   septiembre; en junio había pedido lo contrario, solo flechas. */
.visor__tira{position:fixed;left:0;right:0;bottom:.7rem;display:flex;gap:.4rem;
  justify-content:center;flex-wrap:wrap;padding:0 1rem;max-height:5.2rem;overflow:auto}
.visor__tira[hidden]{display:none}
.visor__mini{width:64px;height:44px;padding:0;border:0;border-radius:0;cursor:pointer;
  background:transparent;opacity:.45;transition:opacity .18s ease, box-shadow .18s ease}
.visor__mini img{width:100%;height:100%;object-fit:cover}
.visor__mini:hover{opacity:.8}
.visor__mini.puesta{opacity:1;box-shadow:0 0 0 2px var(--papel)}
.visor__mini:focus-visible{outline:2px solid var(--papel);outline-offset:2px}
@media (max-width:700px){
  .visor__mini{width:48px;height:34px}
}
@media (max-width:700px){
  .visor{padding:4rem .6rem 4.5rem}
  .visor__flecha{width:44px;height:44px;top:auto;bottom:1rem;transform:none}
  .visor__flecha--izq{left:.8rem}
  .visor__flecha--der{right:.8rem}
  .visor__pie{bottom:5rem;padding:0 1rem}
}

/* Regreso al índice desde la página de un proyecto. La punta se dibuja con dos
   filetes, no con una flecha de texto: el carácter pegado al enlace es uno de
   los tics que delatan una plantilla generada. */
.volver{margin-bottom:1.8rem}
.atras{display:inline-flex;align-items:center;gap:.55rem;font-size:.82rem;font-weight:500;
  letter-spacing:.01em;color:var(--vino);text-decoration:none;padding-bottom:.2rem;
  border-bottom:var(--filete) solid transparent;transition:color .18s ease, border-color .18s ease}
.atras::before{content:'';width:.48rem;height:.48rem;flex:0 0 auto;
  border-left:var(--filete) solid currentColor;border-bottom:var(--filete) solid currentColor;
  transform:rotate(45deg)}
.atras:hover,.atras:focus-visible{color:var(--vino-honda);
  border-bottom-color:var(--vino-honda)}

/* Misión y visión, una al lado de la otra y solo texto. */
.pares{display:grid;grid-template-columns:1fr 1fr;
  gap:clamp(1.6rem,4vw,3.4rem);margin-top:clamp(1.6rem,3.4vw,2.8rem)}
.par h3{font-size:1.3rem;font-weight:600;margin-bottom:.7rem}
.par p{color:var(--cemento);max-width:52ch;font-size:1.02rem}

/* La línea que sustituye al rótulo de "Servicio integral". Fina y dentro de la
   envoltura: las divisorias de borde a borde se quitaron en septiembre. */
.raya{border:0;height:0;border-top:var(--filete) solid var(--linea);
  margin:0 0 clamp(1.6rem,3.4vw,2.6rem)}

/* El botón de "Ver proyectos" va sobre el mapa, pegado a la derecha y abajo, y
   no debajo: colgado del flujo le quitaba alto al mapa, que es lo que se
   quería evitar. Ahí cae sobre el margen que el dibujo deja libre por ese
   lado, así que no tapa nada. */
.mapa__pie{position:absolute;right:0;bottom:6%;margin:0;z-index:4}
.mapa__pie .boton{padding:.55rem 1.1rem;font-size:.74rem}
@media (max-width:900px){
  /* En pantalla chica el mapa ocupa todo el ancho y no hay margen libre: el
     botón vuelve a la corriente, debajo. */
  .mapa__pie{position:static;text-align:center;margin-top:1.2rem}
  .mapa__tira{position:static;width:auto;margin-top:1rem;transform:none}
  /* El número dentro del punto no se lee a este tamaño: el dibujo mide 335 px
     y diez píxeles de texto se quedan en tres. */
  .mapa__cuantos{display:none}
}

/* El ciclo integral, en dos columnas. Llegó de servicios.html, que
   desapareció, y ahí ocupaba una columna y media pantalla. Mismos pasos y
   misma animación: lo único que cambia es cuántos caben por renglón. */
.ciclo--par{grid-template-columns:1fr 1fr}

/* ---------------------------------------------------------------- proyecto */
/* Dos columnas: las fotos y la ficha. 65 y 35 por ciento, que es lo que se
   pidió. Debajo de 900 px se apilan, primero las fotos. */
/* Las pistas van en minmax(0,...) y no en 65fr a secas: dentro hay una cinta
   de ancho max-content y, sin el mínimo en cero, la columna crece hasta
   caber entera y deja a la ficha en cien píxeles. */
.proyecto{display:grid;grid-template-columns:minmax(0,40fr) minmax(0,60fr);
  gap:clamp(1.6rem,4vw,3.4rem);align-items:start}
.proyecto--sola{grid-template-columns:minmax(0,1fr)}
.proyecto__entrada{max-width:46ch;margin:0}

/* La cabecera del proyecto: el carrusel a todo el ancho de la página, que es
   lo que pidió el cliente. Va fuera de la envoltura porque la envoltura se
   topa en 1360 px, y el enlace de regreso se cuelga de su esquina: la maqueta
   no deja sitio por encima. */
.cima{position:relative}
.volver--cima{position:absolute;top:clamp(.7rem,2vw,1.2rem);
  left:clamp(1rem,4vw,3rem);margin:0;z-index:3}
.volver--cima .atras{background:color-mix(in oklab,var(--papel) 92%,transparent);
  padding:.42rem .85rem .42rem .75rem;border-radius:999px;border-bottom:0}
.volver--cima .atras:hover{background:var(--papel)}
.proyecto__cuerpo{min-width:0}
/* El título de cada parte, cuando un proyecto trae más de una. Va a todo el
   ancho, encima de sus dos columnas, y con aire por arriba para que se lea
   como lo que es: el principio de otra cosa. */
.proyecto__parte{font-family:var(--titulo);font-size:clamp(1.3rem,2.6vw,1.9rem);
  font-weight:500;color:var(--vino);margin:clamp(2rem,4vw,3.2rem) 0 1.1rem;
  padding-bottom:.5rem;border-bottom:var(--filete) solid var(--vino-filo)}
.proyecto__parte:first-of-type{margin-top:clamp(1.4rem,3vw,2.2rem)}

/* El pase de imágenes de la cabecera de un proyecto: una sola foto a todo el
   ancho de la ventana y la siguiente cada dos segundos. Era una cinta que se
   desplazaba sola hasta el 17 de septiembre.

   La que sale se queda visible mientras dura el fundido y solo entonces pasa a
   visibility:hidden. Eso es lo que hace que el clic del visor caiga siempre en
   la foto que se está viendo y no en una de las que están debajo. */
.carrusel{position:relative;overflow:hidden;background:var(--hueco);
  height:clamp(20rem,68vh,48rem)}
.carrusel__cinta{position:absolute;inset:0}
.carrusel__pieza{position:absolute;inset:0;opacity:0;visibility:hidden;
  transition:opacity .8s ease, visibility 0s linear .8s}
.carrusel__pieza.ahora{opacity:1;visibility:visible;
  transition:opacity .8s ease, visibility 0s}
html:not(.js) .carrusel__pieza:first-child{opacity:1;visibility:visible}
.carrusel__pieza .foto{width:100%;height:100%;aspect-ratio:auto;cursor:zoom-in}
.carrusel__pieza .foto img{width:100%;height:100%;max-width:none;object-fit:cover}
@keyframes rodar{from{transform:translate3d(0,0,0)}
  to{transform:translate3d(calc(-100% / var(--copias,2)),0,0)}}
@media (prefers-reduced-motion: reduce){
  .carrusel__pieza{transition:none}
}
/* El nombre del proyecto encima, a media transparencia. Lleva una sombra
   suave porque debajo pasa cualquier fotografía: sin ella, sobre un cielo
   claro desaparecía. */
.carrusel__nombre{position:absolute;inset:0;display:grid;place-items:center;
  pointer-events:none;font-family:var(--display);font-weight:500;
  font-size:clamp(2rem,5.2vw,4.2rem);line-height:1;text-align:center;
  padding:0 1rem;color:color-mix(in oklab,var(--papel) 50%,transparent);
  text-shadow:0 2px 26px rgba(0,0,0,.45)}
@media (prefers-reduced-motion: reduce){
  .carrusel__cinta{animation:none}
  .carrusel{overflow-x:auto}
}

/* La ficha técnica, abierta. Un solo filete entre aspectos: la lista de
   créditos de dentro traía el suyo por abajo y el del aspecto siguiente venía
   por arriba, así que salían dos rayas pegadas. Se quita el de la lista.
   Y va apretada, porque su columna es estrecha y larga: si se estira más que
   el carrusel deja un vacío enorme a su izquierda. */
/* En columnas, y con el filete por debajo de cada aspecto y no por encima:
   así el primero de cada columna no queda descabezado ni hace falta descontar
   el de arriba. */
/* Sin tope de ancho: son los titulares que el cliente quiere en una sola línea.
   Va en la hoja común y no en la de cada dirección, que es donde estaba y por
   eso solo hacía efecto en una: las dos tienen su propio h2.titulo con su tope
   en ch, y una regla de más peso tiene que existir en las dos. En pantalla
   estrecha el tamaño baja solo y el renglón se parte, que ahí no cabe de otra
   manera. */
h2.titulo.titulo--ancho,h1.titular.titulo--ancho{max-width:none}

/* La marca de colaboración, detrás del nombre del proyecto en las listas y
   debajo de los créditos del equipo dentro de su ficha. */
.colabora{color:var(--vino);font-weight:500;white-space:nowrap}
.indice__nombre .colabora{margin-left:.4em;font-size:.86em}
.ficha-tec__c .colabora{display:block;margin-top:.4rem;font-size:.84rem}
.mapa__lista .colabora{margin-left:.35em;font-size:.92em}

.ficha-tec{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:0 clamp(1.2rem,2.4vw,2.2rem);align-content:start}
.ficha-tec__parte{padding:.55rem 0;border-bottom:var(--filete) solid var(--linea)}
.ficha-tec__t{font-size:.74rem;letter-spacing:.08em;text-transform:uppercase;
  font-weight:600;color:var(--vino);margin-bottom:.3rem}
.ficha-tec__c{font-size:.88rem;line-height:1.45}
.ficha-tec__c p{color:var(--cemento)}
.ficha-tec__c .rotulos{border-top:0;font-size:.84rem}
.ficha-tec__c .rotulos div{grid-template-columns:1fr;gap:0;padding:.18rem 0;border-bottom:0}
.ficha-tec__c .datos{gap:.9rem 1.4rem}
.ficha-tec__c .dato b{font-size:1.15rem}
.ficha-tec__c .dato span{font-size:.74rem}
.ficha-tec__c .aliados{gap:.3rem}
.ficha-tec__c .aliados li{font-size:.75rem;padding:.2rem .5rem}
.ficha-tec__c>*+*{margin-top:.5rem}

/* Las fotos que no caben en el carrusel, una por renglón y centradas, cada una
   con su proporción. Eran un renglón de altura común hasta el 17 de
   septiembre. El tope es doble —de ancho para las apaisadas y de alto para las
   verticales— porque una vertical a 56rem de ancho mediría metro y medio. */
.abajo{display:grid;justify-items:center;
  gap:clamp(1.4rem,3.4vw,2.8rem);margin-top:clamp(1.8rem,4vw,3.2rem)}
.abajo__pieza{width:min(100%,56rem)}
.abajo__pieza .foto{width:100%;height:auto;aspect-ratio:auto;cursor:zoom-in}
.abajo__pieza .foto img{display:block;width:100%;height:auto;object-fit:contain}

@media (max-width:900px){
  .pares,.ciclo--par,.proyecto{grid-template-columns:1fr}
  .ficha-tec{grid-template-columns:repeat(2,minmax(0,1fr))}
  .carrusel{height:clamp(15rem,50vh,24rem)}
  .abajo__pieza{height:11rem}
}

/* Las cifras de un proyecto son de las pocas cosas que piden realce. */
.dato b{color:var(--vino)}

/* Fotos que son un enlace. Una imagen no se ve enlace por sí sola: al pasar
   por encima se tiñe de vino y aparece el rótulo. El velo no intercepta
   el cursor, así que el enlace de debajo sigue recibiendo el clic. */
.velo{position:absolute;inset:0;display:grid;place-items:center;pointer-events:none;
  background:color-mix(in oklab,var(--vino) 30%,transparent);
  opacity:0;transition:opacity .22s ease}
/* El rótulo va sobre vino llena y no sobre el velo: encima de una foto
   cualquiera el contraste es imprevisible, y sobre la vino llena el
   blanco cumple AA siempre. */
.velo>span{font-size:.68rem;letter-spacing:.09em;text-transform:uppercase;font-weight:600;
  color:var(--papel);background:var(--vino);padding:.34rem .8rem;border-radius:999px}
a:hover .velo,a:focus-visible .velo{opacity:1}
@media (hover:none){
  /* Sin cursor no hay nada que revelar y el velo no llegaría a verse nunca. */
  .velo{display:none}
}

/* Identificador de qué se está viendo: fotografía de obra, render o plano. Va
   sobre un fondo oscuro traslúcido porque tiene que leerse encima de cualquier
   imagen, clara u oscura. El punto de delante distingue de un vistazo: lleno
   para lo construido, hueco para lo que todavía es un dibujo. */
.tipo{position:absolute;top:.7rem;right:.7rem;display:inline-flex;align-items:center;gap:.4rem;
  font-size:.66rem;letter-spacing:.08em;text-transform:uppercase;font-weight:600;
  color:var(--papel);background:color-mix(in oklab,var(--tinta) 72%,transparent);
  padding:.3rem .62rem;border-radius:999px;backdrop-filter:blur(3px)}
.tipo::before{content:'';width:.42rem;height:.42rem;border-radius:50%;
  border:1.5px solid currentColor}
.tipo--real::before{background:currentColor}
.tipo--plano::before{border-radius:1px}

/* ---------------------------------------------------------------------------
   B · Obra. La fotografía manda: ocupa el ancho completo y el tipo se coloca
   encima o en una columna angosta. Fondo blanco y bandas grises alternas.
   --------------------------------------------------------------------------- */
/* Todo blanco. La alternancia de bandas se quitó el 9 de septiembre porque el
   gris no gustó, así que lo único que separa un bloque del siguiente es el
   filete, igual que en Plano. */
:root{--fondo:var(--papel);--linea:color-mix(in oklab, var(--cemento) 30%, transparent);--cab-alto:72px}

/* Barra blanca con el logotipo en negro desde el 11 de septiembre. Antes era
   negra con el logotipo invertido, y sobre el video del hero eso era medio
   cartel; ahora el hero empieza justo debajo de la barra. */
.cabecera{position:fixed;inset:0 0 auto 0;z-index:50;height:var(--cab-alto);
  display:flex;align-items:center;color:var(--tinta);
  background:var(--papel);border-bottom:var(--filete) solid var(--linea);
  transition:background .25s ease, color .25s ease}
.cabecera.fija,.cabecera--solida{background:var(--papel);color:var(--tinta)}
body.con-cabecera-solida{padding-top:var(--cab-alto)}
.cabecera__fila{display:flex;align-items:center;justify-content:space-between;gap:2rem}
.cabecera .nav__sub{background:var(--papel);border-color:var(--linea)}
.cabecera .nav__sub a{color:var(--tinta)}
.cabecera .nav__sub a:hover{background:var(--vino-tenue)}

:root{--aire-bloque:clamp(2.2rem,4.6vw,4.2rem)}
.bloque{padding:var(--aire-bloque) 0}
.bloque--apunte{padding:calc(var(--aire-bloque) * .34) 0}
/* Dos bloques que en realidad son el mismo paso de lectura: el nombre de un
   proyecto y sus fotos, o la ficha y el cierre. Con el aire entero de cada uno
   quedaban catorce rem de blanco en medio, que se lee como si faltara algo.
   El de arriba corta su aire de abajo y se queda sin filete; el de abajo
   arranca pegado. */
.bloque--corta-abajo{padding-bottom:calc(var(--aire-bloque) * .45);border-bottom:0}
.bloque--corta-arriba{padding-top:calc(var(--aire-bloque) * .15)}
/* La clase sigue puesta en el HTML y ya no pinta nada: se conserva para no
   tocar los generadores de todas las páginas y porque el día que vuelva a
   haber una banda, este es su sitio. */
.bloque--claro{background:transparent}
.bloque--oscuro{background:var(--tinta);color:var(--papel)}
.bloque--oscuro .entrada,.bloque--oscuro .cuerpo p{color:color-mix(in oklab,var(--papel) 72%, transparent)}
.bloque--oscuro .foto::after{background:var(--tinta);color:color-mix(in oklab,var(--papel) 60%,transparent)}

.rejilla{display:grid;grid-template-columns:1fr;gap:clamp(1.5rem,3vw,2.5rem)}
.rotulo{display:flex;gap:1rem;align-items:baseline;padding-bottom:.4rem;
  font-size:.82rem;color:var(--cemento)}
.rotulo b{color:inherit;font-weight:600;font-size:.95rem}
.rotulo .clave{font-variant-numeric:tabular-nums;color:var(--cemento)}
.bloque--oscuro .rotulo{color:color-mix(in oklab,var(--papel) 62%,transparent)}

h1.titular{font-family:var(--display);font-size:clamp(2rem,4.1vw,3.3rem);font-weight:500;
  letter-spacing:-.006em;line-height:1.1;max-width:23ch}
h2.titulo{font-family:var(--display);font-size:clamp(1.55rem,2.7vw,2.3rem);font-weight:500;
  letter-spacing:-.004em;line-height:1.16;max-width:28ch}
h3.sub{font-size:1.15rem;font-weight:600}
.entrada{font-size:clamp(1.02rem,1.5vw,1.22rem);color:var(--cemento);max-width:58ch}
.cuerpo{display:grid;gap:1rem;max-width:66ch}

/* Hero a sangre, el video carga todo el peso */
.hero{position:relative;min-height:calc(100svh - var(--cab-alto));display:flex;align-items:flex-end;
  color:var(--papel);overflow:hidden}
.hero::after{content:'';position:absolute;inset:0;z-index:1;
  background:linear-gradient(to top,
             color-mix(in oklab,var(--tinta) 80%, transparent) 0%,
             color-mix(in oklab,var(--tinta) 72%, transparent) 22%,
             color-mix(in oklab,var(--tinta) 44%, transparent) 44%,
             color-mix(in oklab,var(--tinta) 14%, transparent) 62%,
             transparent 76%)}
.hero .hero-media{z-index:0}
.hero__texto{position:relative;z-index:2;padding-bottom:clamp(2.5rem,7vh,5rem)}
/* El titular del hero es el único que se queda grande, pero cabiendo en tres
   renglones: se le da más ancho de caja en vez de más cuerpo. */
/* El titular del hero va en versales: el cliente lo escribió así. El texto se
   guarda con sus mayúsculas y minúsculas de verdad, que es lo que leen el
   buscador y el lector de pantalla, y las versales las pone el CSS.

   Medido para que caiga en tres renglones y no en cuatro. La caja se da en ch,
   que es el ancho del cero, y en versales cada letra ocupa bastante más que
   eso: por eso 26ch dan unos veinte caracteres por renglón y no veintiséis. */
.hero .titular{font-size:clamp(1.55rem,3vw,2.35rem);max-width:26ch;
  text-transform:uppercase;letter-spacing:.005em;line-height:1.16}
.hero__pie{display:grid;grid-template-columns:1fr auto;gap:2rem;align-items:end;margin-top:1.8rem}
/* Sin el renglón que había a la izquierda, el botón se queda solo y va al
   principio, no colgando del borde derecho. */
.hero__pie--solo{grid-template-columns:auto;justify-content:start}
.hero__datos{display:flex;flex-wrap:wrap;gap:1.2rem 2.4rem}

.cifras{display:grid;grid-template-columns:repeat(4,1fr);gap:2rem}
.cifra b{display:block;font-size:clamp(1.9rem,4vw,3rem);font-weight:300;letter-spacing:-.035em;
  font-variant-numeric:tabular-nums}
.cifra span{font-size:.82rem;color:var(--cemento)}
.bloque--oscuro .cifra span,.hero .cifra span{color:color-mix(in oklab,var(--papel) 62%,transparent)}

/* Proyectos como mosaico de foto, no como tabla */
.indice{display:grid;grid-template-columns:repeat(auto-fill,minmax(21rem,1fr));gap:1.2rem}
.indice__fila{display:block;text-decoration:none;color:inherit;position:relative}
.indice__fila .foto{aspect-ratio:4/3;margin-bottom:.8rem}
.indice__clave{font-size:.78rem;color:var(--cemento);font-variant-numeric:tabular-nums}
.indice__nombre{font-size:1.2rem;font-weight:500;margin-top:.15rem}
.indice__meta{font-size:.84rem;color:var(--cemento);display:block}

.fichas{display:grid;grid-template-columns:repeat(auto-fill,minmax(20rem,1fr));gap:1.2rem}
.ficha{text-decoration:none;color:inherit;display:grid;gap:.7rem;align-content:start}
.ficha .foto{aspect-ratio:3/2}
.ficha__clave{font-size:.78rem;color:var(--cemento);font-variant-numeric:tabular-nums}
.ficha__nombre{font-size:1.24rem;font-weight:500}
.ficha__meta{font-size:.84rem;color:var(--cemento)}

.rotulos{font-size:.88rem}
.rotulos div{display:grid;grid-template-columns:minmax(8rem,34%) 1fr;gap:1rem;
  padding:.5rem 0;border-bottom:var(--filete) solid var(--linea)}
.rotulos dt{color:var(--cemento)}
.rotulos dd{margin:0;font-weight:500}

.datos{display:flex;flex-wrap:wrap;gap:2.4rem}
.dato b{display:block;font-size:clamp(1.5rem,3vw,2.3rem);font-weight:300;letter-spacing:-.035em;
  font-variant-numeric:tabular-nums}
.dato span{font-size:.8rem;color:var(--cemento);max-width:16ch;display:block}

.galeria{display:grid;grid-template-columns:repeat(auto-fill,minmax(17rem,1fr));gap:1.2rem}
.galeria--sangre{width:100%;grid-template-columns:repeat(auto-fill,minmax(22rem,1fr));gap:2px}

.ciclo{counter-reset:paso;display:grid;gap:2px;background:var(--linea-suave)}
.ciclo__paso{display:grid;grid-template-columns:4.5rem 1fr;gap:1.5rem;background:var(--vino-tenue);
  color:var(--tinta);padding:1.7rem;opacity:0;transform:translateY(10px);
  transition:opacity .5s ease, transform .5s ease}
.ciclo__paso.visible{opacity:1;transform:none}
.ciclo__n{font-size:.84rem;color:color-mix(in oklab,var(--tinta) 62%,transparent);
  font-variant-numeric:tabular-nums}
.ciclo__paso h3{font-size:1.15rem;font-weight:600;margin-bottom:.4rem}
/* Sin tope de ancho: en una columna de media pantalla, 62ch cortaban el texto
   a la mitad de su caja y parecía un error de maqueta. Quien pone el límite de
   línea aquí es la propia columna. */
.ciclo__paso p{color:color-mix(in oklab,var(--tinta) 78%,transparent)}

:root{--mapa-tierra:color-mix(in oklab,var(--vino) 13%,var(--papel));
  --mapa-linea:color-mix(in oklab,var(--vino) 38%,transparent)}
.areas{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:1.5rem}
.area{background:var(--papel);border:var(--filete) solid var(--linea);
  padding:1.6rem;display:grid;gap:.8rem;align-content:start}
.area h3{font-size:1.08rem;font-weight:600;padding-bottom:.6rem;
  border-bottom:var(--filete) solid var(--vino-filo)}
.area li{font-size:.88rem;color:var(--cemento);padding:.28rem 0}

.principios{display:grid;grid-template-columns:repeat(auto-fit,minmax(19rem,1fr));gap:2rem 2.5rem}
.principio h3{font-size:1.04rem;font-weight:600;margin-bottom:.5rem}
.principio p{font-size:.9rem;color:var(--cemento)}

.persona__cargo{font-size:.88rem;color:var(--cemento)}
.persona__cifras{display:flex;gap:1.6rem;margin:1rem 0}
.persona__caps{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:1.2rem}
.persona__caps li{font-size:.78rem;padding:.28rem .65rem;color:var(--cemento);
  border:var(--filete) solid var(--vino-filo)}

.aliados{display:flex;flex-wrap:wrap;gap:.5rem}
.aliados li{font-size:.83rem;padding:.35rem .75rem;color:var(--cemento);
  border:var(--filete) solid var(--vino-filo)}

.contacto{display:grid;grid-template-columns:minmax(16rem,34%) 1fr;gap:clamp(2rem,5vw,4rem);align-items:start}
.pendientes{background:var(--vino-tenue);color:var(--tinta);padding:1.5rem 1.7rem;font-size:.86rem;display:grid;gap:.6rem}
.pendientes b{font-weight:600}
.pendientes li{padding-left:1rem;position:relative}
.pendientes li::before{content:'';position:absolute;left:0;top:.62em;width:5px;height:5px;background:var(--tinta)}

@media (max-width:900px){
  .contacto{grid-template-columns:1fr}
  .cifras{grid-template-columns:repeat(2,1fr)}
  .hero__pie{grid-template-columns:1fr}
}
