﻿/* ==========================================================================
   cinco.css â€” pagina de caso, en clave de galeria
   --------------------------------------------------------------------------
   Misma arquitectura que `cinco.css`: hoja unica, sin dependencias, con TODO
   colgado de una clase para que sirva suelta y dentro del sitio. Lo que cambia
   es la marca que se presenta, no el sistema.

   TRES DECISIONES QUE EXPLICAN TODO LO DEMAS

   1. Un solo tema, blanco.  Las piezas de Cinco de Mayo estan compuestas sobre
      damasco negro y madera clara. Sobre fondo oscuro pierden su propio fondo
      y compiten. La pagina se pinta de blanco porque es galeria: el blanco
      deja que el negro damasco y el amarillo mostaza respiren sin ensuciarse.

   2. La pagina calla para que el trabajo hable.  Sin cajas, sin sombras, sin
      degradados, sin rotulos sobre las imagenes. El amarillo mostaza (#8A6500)
      es el unico acento y tiene un solo trabajo: los titulos de seccion y el boton.
      Amarillo = lo que pone Cinco de Mayo. Negro = lo que dice el estudio.

   3. Radio 0 en todo, sin excepcion.  Incluido el boton. Un borde redondeado
      dentro de una rejilla de cuadrados es ruido.

   PALETA â€” muestreada de los 35 JPG originales, no elegida de un catalogo:
     #FFB800  amarillo vivo de la estrella y triángulos    #0A0A0A  negro damasco de fondo
   El verde vivo da 2,29:1 sobre blanco y NO se usa en interfaz en ningun sitio:
   con texto encima es ilegible en cualquier direccion. El token de acento es
   #8A6500, el mismo verde bajado hasta 5,26:1, que es exactamente el mismo
   contraste con el que trabaja el rojo de Barkys.

   TIPOGRAFIAS â€” son de la marca presentada, no de Ballestastudio. Lo unico
   propio es el logo:
     Montserrat 600/700   la que usan los titulares de las piezas: geometrica,
                          ancha, de terminales PLANAS, con la A de vertice
                          plano y las O casi circulares. Se saco mirando las
                          letras ampliadas de "LAVADO DE MANOS", "DONACION" y
                          "LOS RINONES", no del logotipo
     Source Sans 3 400    humanista y neutra. Contrasta con la geometria del
                          titular en vez de duplicarla, y es la que la base de
                          `ui-ux-pro-max` marca para salud y accesibilidad,
                          que es el registro real de esta cuenta
     IBM Plex Mono        "1 / 4" es especificacion, no titulo. La mono lo hace
                          leer como ficha tecnica. Es la misma que usan los
                          demas casos: el unico rasgo tipografico que el
                          estudio conserva de pagina a pagina

   > OJO: la primera version de esta hoja usaba Nunito, de terminales
   > REDONDEADAS, deducida del logotipo. Estaba mal: el logotipo de Cinco de Mayo es
   > un lockup con script y no dice nada de la tipografia del sistema. Las
   > piezas mandan, y las piezas son geometricas de terminal plana. Corregido
   > en ago 2026.
   ========================================================================== */

/* TODO cuelga de `.caso-cinco`, no de `:root` ni de `body`. Asi la misma
   hoja sirve para la pagina suelta y para el fragmento incrustado en el sitio,
   sin pisar los tokens ni la tipografia de ballestastudio.com. Integrar es
   enlazar esta hoja y envolver el cuerpo en <div class="caso-cinco">. */
.caso-cinco {
  color-scheme: light;

  --tinta:        #131313;   /* 18,58:1 sobre blanco */
  --tinta-media:  #5c5c5c;   /* 6,69:1 sobre blanco */
  --tinta-suave:  #767676;   /* 4,54:1 sobre blanco: el minimo para texto */
  --linea:        #e8e8e8;
  --papel:        #ffffff;
  --papel-alt:    #fafafa;
  --verde:        #FFB800;   /* amarillo vivo del landing — se conserva intacto */
  --verde-oscuro: #E8A500;   /* hover del boton amarillo, texto negro encima */
  --verde-hondo:  #0A0A0A;   /* fondo del hero, bajo las tiras */
  --amarillo:     #FFB800;   /* alias vivo */
  --amarillo-profundo: #8A6500; /* amarillo bajado a 5,26:1 para texto sobre blanco */
  --rojo-greca:   #E53935;

  /* Escala de espacio. Todo el ritmo vertical sale de aqui. */
  --e1: .5rem;  --e2: 1rem;   --e3: 1.5rem;  --e4: 2.5rem;
  --e5: 4rem;   --e6: 6rem;   --e7: clamp(5rem, 12vw, 9rem);

  --ancho: 1240px;
  --margen: clamp(1.25rem, 5vw, 3.5rem);

  --display: "Montserrat", ui-sans-serif, system-ui, sans-serif;
  --texto:   "Source Sans 3", "Source Sans Pro", ui-sans-serif, system-ui, sans-serif;
  --dato:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --salida: cubic-bezier(.16, 1, .3, 1);
}

.caso-cinco, .caso-cinco *, .caso-cinco *::before, .caso-cinco *::after {
  box-sizing: border-box;
}

.caso-cinco {
  background: var(--papel);
  color: var(--tinta);
  font-family: var(--texto);
  /* 400 y no 300 como en Barkys: Outfit aguanta el 300, Source Sans 3 es
     humanista y de menos contraste, y a 300 el gris del cuerpo se lava. */
  font-weight: 400;
  font-size: clamp(1rem, .96rem + .2vw, 1.075rem);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* La pagina suelta no tiene mas contenido que el caso, asi que el papel sube
   al <body> para que cubra la ventana entera. En el sitio esta regla no
   aplica: alli el fondo lo pone el sitio. */
body:has(> .caso-cinco) { margin: 0; background: var(--papel); }

.caso-cinco img { display: block; max-width: 100%; }

.caso-cinco a { color: inherit; }

.caso-cinco ::selection { background: var(--amarillo); color: #0A0A0A; }

.caso-cinco :focus-visible { outline: 2px solid var(--amarillo); outline-offset: 3px; }

.contenedor { max-width: var(--ancho); margin-inline: auto; padding-inline: var(--margen); }

.salta { position: absolute; left: -9999px; }
.salta:focus {
  left: var(--margen); top: var(--e2); z-index: 60;
  padding: .7rem 1.1rem; background: var(--tinta); color: #fff;
  font-family: var(--dato); font-size: .82rem;
}

/* --- Apertura -----------------------------------------------------------
   El FONDO son las piezas reales desplazandose en tiras a distintas
   velocidades, y encima va una frase corta que invita a bajar. El fondo es el
   trabajo, que es lo que se vino a ver, y no una animacion abstracta pegada
   encima.

   La lamina 01 de la presentacion NO se usa aqui, por la misma razon que en
   Barkys: mide 1920 px de ancho y el hero ocupa el ancho de la ventana, asi
   que en cualquier monitor grande se estira y se ve blanda. Sigue existiendo,
   pero como og:image, que es donde ese tamano alcanza de sobra.

   Cuatro tiras y no mas: pasada esa cantidad el efecto no gana profundidad y
   si multiplica el coste de pintado. */

.portada {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: min(78dvh, 760px);
  overflow: hidden;
  background: var(--verde-hondo);
  isolation: isolate;
}

.portada__fondo {
  position: absolute; inset: 0;
  z-index: -2;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(8px, 1.2vw, 16px);
  padding: clamp(8px, 1.2vw, 16px);
}
@media (max-width: 699px) {
  .portada__fondo { grid-template-columns: repeat(2, 1fr); }
  .portada__fondo > :nth-child(n+3) { display: none; }
}

.tira {
  display: grid;
  gap: clamp(8px, 1.2vw, 16px);
  align-content: start;
  /* La tira se sale por arriba y por abajo a proposito: asi el bucle nunca
     ensena un borde. El contenedor recorta. */
  will-change: transform;
}
.tira img { width: 100%; height: auto; }

/* El velo. Va aparte del fondo y no como sombra sobre el texto, porque tiene
   que cubrir 18 imagenes de valores muy distintos por igual.

   CONTRASTE GARANTIZADO POR CONSTRUCCION. A 0,88 sobre el peor caso posible
   â€”un pixel blanco de una piezaâ€” el resultado es rgb(18 18 18), que con texto
   blanco encima da 6,45:1. Cualquier pixel mas oscuro da mas. No depende de
   que imagen toque en cada momento del bucle.

   Se queda en 0,88 y no en 0,90 a proposito: las piezas de Cinco de Mayo ya son
   verdes, y un velo verde mas cerrado las borra del todo. */
.portada__velo {
  position: absolute; inset: 0;
  z-index: -1;
  background:
    linear-gradient(to top, rgb(0 0 0 / .55), transparent 62%),
    rgb(10 10 10 / .88);
}

.portada__texto {
  position: relative;
  width: 100%;
  padding-block: clamp(6rem, 14vw, 9rem) clamp(2.5rem, 6vw, 4.5rem);
  color: #fff;
}
.portada__rotulo {
  margin: 0 0 var(--e2);
  font-family: var(--dato);
  font-size: .74rem; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase;
  color: rgb(255 255 255 / .82);
}
.portada__titulo {
  margin: 0;
  max-width: 22ch;
  font-family: var(--display); font-weight: 700;
  font-size: clamp(2.1rem, 5.2vw, 3.9rem);
  line-height: 1.06; letter-spacing: -.03em;
  color: #fff;
  /* `balance` reparte el titular en lineas parejas. Se prefiere a un <br>
     fijo, que corta bien en un idioma y mal en el otro y se rompe en cuanto
     cambia el ancho. */
  text-wrap: balance;
}
.portada__bajada {
  margin: var(--e3) 0 0;
  max-width: 46ch;
  font-size: clamp(1.02rem, .95rem + .35vw, 1.2rem);
  color: rgb(255 255 255 / .92);
  text-wrap: balance;
}

/* --- La marca -----------------------------------------------------------
   El logo y nada mas: sin barra, sin fondo, sin linea y sin quedarse pegado al
   hacer scroll. Va montado sobre el hero, alineado con el margen del
   contenedor. Mismo tratamiento que en Exopartes y en Barkys.

   Usa el lockup INVERTIDO a una tinta. El logo normal es negro con "STUDIO" en
   turquesa, y sobre el verde institucional ese turquesa se pierde. Un logo a
   una tinta para fondos de color es un recurso normal de manual de marca. */

.marca {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 3;
  max-width: var(--ancho);
  margin-inline: auto;
  padding: clamp(var(--e2), 2.5vw, var(--e4)) var(--margen);
}
/* El enlace se cine al logo. Si la caja clicable fuera toda la franja, medio
   pantallazo llevaria al inicio sin avisar. */
.marca a { display: inline-block; }
.marca img { width: clamp(104px, 11vw, 132px); height: auto; }


/* --- Lamina a sangre ----------------------------------------------------
   Ancho completo de la VENTANA, no del contenedor. Las laminas ya estan
   compuestas sobre blanco, asi que no necesitan marco ni pie: se sientan sobre
   el papel de la pagina y el corte no se ve. Sin pie de foto a proposito: una
   linea gris debajo de una imagen que ocupa la pantalla la convierte en una
   ilustracion con leyenda y le quita la fuerza.

   Sin trucos de 100vw: la figura es hija directa de <main>, que ya ocupa todo
   el ancho del documento. Un `width: 100vw` aqui solo serviria para sumar los
   pixeles de la barra de scroll y provocar desborde horizontal. */

.lamina {
  margin-block: clamp(2.75rem, 5.5vw, 4.25rem);
  /* El navegador le da a <figure> un margen lateral de 40 px por su cuenta.
     `margin-block` no lo toca, asi que hay que anularlo a mano o la lamina se
     queda 80 px angosta y deja de ir a sangre. */
  margin-inline: 0;
  overflow: hidden;
}
.lamina img { width: 100%; height: auto; }

/* --- Bloques de texto ---------------------------------------------------- */

/* 4,25rem y no 5,5rem: medido en Chrome, el ritmo anterior dejaba 83 px
   parejos entre TODAS las secciones (la maqueta nunca estuvo desigual, lo que
   se veia desigual era la animacion de entrada a medio camino). 83 px en una
   pagina que es casi toda imagenes hacia que cada seccion pareciera flotar
   suelta. A 68 px las secciones siguen separadas y la galeria se lee seguida. */
.bloque { margin-block: clamp(2.75rem, 5.5vw, 4.25rem); }

/* Los titulos van en el verde de la marca. Es el sistema de acento de la
   pagina: verde = lo que Cinco de Mayo pone, negro = lo que dice el estudio. Da
   5,26:1 sobre blanco, de sobra para AA incluso a este tamano. */
.bloque__titulo {
  margin: 0 0 var(--e3);
  font-family: var(--display); font-weight: 700;
  font-size: clamp(1.9rem, 1.2rem + 2.6vw, 3.1rem);
  line-height: 1.05; letter-spacing: -.03em;
  color: var(--tinta);
  position: relative;
}
.bloque__titulo .accent {
  background: var(--amarillo);
  color: #0A0A0A;
  padding: 0 .12em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
.bloque__titulo::after {
  content: "";
  display: block;
  width: 48px;
  height: 4px;
  background: var(--amarillo);
  margin-top: .55rem;
}
.bloque__titulo--solo::after {
  margin-inline: auto;
}
.bloque--centrado .bloque__titulo::after {
  margin-inline: auto;
}
.bloque__titulo .accent {
  background: var(--amarillo);
  color: #0A0A0A;
  padding: 0 .12em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
.portada__titulo .accent-hero {
  color: var(--amarillo);
  background: transparent;
  /* El guion de TEX-MEX es un punto de corte valido para el navegador, asi que
     el titulo se partia en "TEX-" / "MEX". Es un nombre, no una palabra: o cabe
     entero o pasa entero a la linea siguiente. */
  white-space: nowrap;
}
.remate__cierre h2 .accent {
  background: var(--amarillo);
  color: #0A0A0A;
  padding: 0 .12em;
}

/* Cuando el titulo es lo unico que lleva la seccion, respira mas abajo y va
   centrado: sin texto al lado, un titulo suelto pegado a la izquierda deja un
   vacio raro a su derecha. */
.bloque__titulo--solo {
  margin-bottom: var(--e3);
  text-align: center;
}

/* Los bloques del carrusel y de los pares centran titulo y linea, pero NO las
   piezas: esas siguen su propia rejilla. */
.bloque--centrado > .bloque__titulo,
.bloque--centrado > .bloque__texto {
  text-align: center;
  margin-inline: auto;
}
/* La misma separacion que el feed y stories llevan en su propio estilo: sin
   esto el parrafo del carrusel quedaba pegado a la primera fila de piezas. */
.bloque--centrado > .bloque__texto {
  margin-bottom: var(--e3);
}
.bloque__texto {
  margin: 0;
  max-width: 62ch;
  color: var(--tinta-media);
}
.bloque__texto + .bloque__texto { margin-top: var(--e2); }

/* Dos columnas para el encargo. Es el unico texto largo de la pagina y en una
   sola columna a 1240 px quedaria una linea de 140 caracteres. */
.dos-columnas {
  display: grid; gap: var(--e3) var(--e5);
  grid-template-columns: 1fr;
}
@media (min-width: 900px) {
  .dos-columnas { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); align-items: start; }
}

.alcance { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--e2); }
.alcance li {
  padding-top: var(--e2);
  border-top: 1px solid var(--linea);
  color: var(--tinta-media);
}

/* --- Rejilla de galeria -------------------------------------------------
   Ni pies, ni nombres, ni fechas: solo la imagen y el zoom. Lo que hace una
   galeria es dejar mirar; cada rotulo que se agrega es una interrupcion. La
   descripcion sigue existiendo en el `alt` de cada imagen, o sea que un lector
   de pantalla la lee aunque no se vea. */

.galeria {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(14px, 1.6vw, 24px);
  margin: 0; padding: 0; list-style: none;
  /* `dense` es obligatorio con spans mezclados: sin el, la rejilla deja el
     hueco donde la pieza grande no cabia y se lee como celda vacia. */
  grid-auto-flow: dense;
}

/* Una de cada seis ocupa 2x2. No es decoracion: dieciocho cuadrados iguales en
   fila se leen como hoja de contactos, y lo que se quiere es una galeria. La
   estructura sale de "Bento Box Grid"; su decoracion (radio 24 px, sombras,
   fondo gris) NO se toma, porque esta pagina va a radio 0 y sin sombras. */
@media (min-width: 900px) {
  .galeria:not(.galeria--vertical) > li:nth-child(1),
.galeria:not(.galeria--vertical) > li:nth-child(6) {
    grid-column: span 2;
    grid-row: span 2;
  }
}

/* Las stories van en UNA sola fila y con piezas que se distingan entre si, no
   en la rejilla de cuatro del feed. La razon es de contenido: el archivo tiene
   9 verticales y solo 6 distintas (cuatro son variaciones del carrusel del
   yoga); cuatro de esas seis se van a los pares y aqui quedan dos. Rellenar
   celdas obligaria a repetir la misma story.

   Por eso la fila NO usa fracciones: usa columnas de ancho fijo centradas. Asi
   la seccion se ve deliberada con dos piezas o con cinco, y ninguna se estira
   a media pantalla solo porque sobre sitio. 290 px es el ancho al que una
   story de 9:16 sigue leyendose y queda cerca del de la story de los pares. */
.galeria--vertical {
  grid-auto-flow: row;
  grid-template-columns: repeat(auto-fit, minmax(0, 290px));
  justify-content: center;
}

/* En movil las dos rejillas van a dos columnas, la del feed y la de stories.
   Las stories se nombran aparte a proposito y no por herencia de la cascada:
   a 375 px cada una queda en 163 px, el mismo ancho que una pieza del feed, y
   la seccion cabe entera en media pantalla. La alternativa era conservar los
   290 px fijos, que en un telefono obliga a apilarlas y estira una seccion de
   dos piezas a dos pantallas de scroll. */
@media (max-width: 899px) {
  .galeria,
  .galeria--vertical { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* La pieza es un boton que envuelve la imagen. Sin JS sigue siendo un boton
   inerte y la imagen se ve igual: la galeria nunca depende del script para
   mostrar el trabajo. */
.pieza {
  position: relative;
  display: block; width: 100%; padding: 0;
  border: 0; background: var(--papel-alt);
  cursor: zoom-in;
  overflow: hidden;
}
.pieza img {
  width: 100%; height: auto;
  transition: transform .5s var(--salida), opacity .3s ease;
}
.pieza:hover img, .pieza:focus-visible img { transform: scale(1.06); }

/* --- El carrusel --------------------------------------------------------
   Cuatro piezas en UNA fila, siempre, y con numero encima. Es la unica parte
   de la pagina donde el orden es informacion: si se mezclan en la galeria del
   feed y una de ellas cae en la celda 2x2, la secuencia se pierde y se leen
   como cuatro piezas sueltas.

   El numero es la unica etiqueta que sobrevive en toda la pagina, y esta
   justificada: sin el, "se leen en orden" es una afirmacion que el visitante
   no puede comprobar. Va en la mono, como los demas datos.

   En movil pasa a dos columnas y no a scroll horizontal: un carrusel dentro de
   un carrusel obliga a arrastrar para ver algo que cabe. */

.carrusel {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(14px, 1.6vw, 24px);
  margin: 0; padding: 0; list-style: none;
  counter-reset: paso;
}
@media (max-width: 699px) { .carrusel { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.carrusel > li { counter-increment: paso; margin: 0; }
.carrusel > li::before {
  content: counter(paso) " / 4";
  display: block;
  margin-bottom: .55rem;
  font-family: var(--dato); font-size: .72rem; letter-spacing: .1em;
  color: var(--tinta-suave);
}
/* Variante tight para carrusel: sin numeros, imagenes pegadas como feed */
.carrusel--tight {
  gap: 4px;
}
.carrusel--tight > li::before {
  display: none !important;
  content: none !important;
}
@media (max-width: 699px) {
  .carrusel--tight { gap: 3px; }
}

/* --- Pares 1:1 y 9:16 ---------------------------------------------------
   El bloque que sostiene la pagina. Las dos columnas estan en proporcion
   1 : 0.5625, o sea la del 9:16 frente al cuadrado: asi las dos imagenes
   terminan exactamente a la misma altura y la comparacion es honesta. Si se
   dejaran a anchos iguales, la story se veria mas alta y pareceria otra cosa.
   En movil se apilan y la story se topa, porque a ancho completo mide casi dos
   pantallas ella sola. */

/* Cuatro pares en 2x2. Antes iban tres apilados a lo largo y con `--e6` (6rem)
   de separacion: la seccion se hacia larguisima y cada par quedaba solo en
   pantalla, sin nada con que compararse, que es justo lo contrario de lo que
   este bloque existe para hacer. En dos filas de dos se ven dos casos a la vez
   y se lee como un sistema, no como tres ejemplos sueltos.

   Al caber dos por fila, la separacion baja de `--e6` a `--e4`: con la mitad de
   ancho, 6rem de aire vertical dejaban un hueco mas alto que las propias
   piezas. */
.pares {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--e5);
  margin: 0; padding: 0; list-style: none;
}
@media (min-width: 900px) {
  .pares {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--e4) var(--e5);
  }
}
.par { margin: 0; }
.par__visor { display: grid; gap: clamp(14px, 1.6vw, 24px); align-items: end; }
@media (min-width: 700px) { .par__visor { grid-template-columns: 1fr .5625fr; } }
@media (max-width: 699px) { .par__lado--story { max-width: 58%; } }

.par__lado { min-width: 0; }

/* --- Nota de creditos ---------------------------------------------------- */

.creditos {
  max-width: 68ch;
  margin: 0;
  padding-left: var(--e3);
  border-left: 3px solid var(--amarillo);
  font-size: .95rem;
  color: var(--tinta-media);
}
.creditos strong { font-weight: 600; color: var(--tinta); }

/* --- Remate: creditos y llamado, en una sola linea -----------------------
   Antes eran dos secciones apiladas y entre las dos se comian casi una
   pantalla para decir dos cosas cortas. Puestas lado a lado se leen igual y la
   pagina termina donde termina el trabajo: la letra chica a la izquierda, la
   invitacion a la derecha, que es donde cae el ojo al final de la fila. */

.remate {
  margin-block: clamp(2.5rem, 5vw, 4rem) 0;
  padding-block: clamp(2.25rem, 4vw, 3.25rem) clamp(2.5rem, 5vw, 3.5rem);
  border-top: 1px solid var(--linea);
}
.remate__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(var(--e4), 4vw, var(--e6));
  align-items: start;
}
.remate__cierre h2 {
  margin: 0 0 var(--e2);
  color: var(--verde);
  max-width: none;
  font-family: var(--display); font-weight: 600;
  font-size: clamp(1.75rem, 1.2rem + 2vw, 2.75rem);
  line-height: 1.1; letter-spacing: -.025em;
}
.remate__cierre p { margin: 0 0 var(--e3); max-width: 46ch; color: var(--tinta-media); }

/* El titulo de creditos ya no compite con el del cierre: baja de tamano y se
   queda como lo que es, un encabezado de letra chica. */
.bloque__titulo--chico {
  font-size: clamp(1.15rem, .9rem + .7vw, 1.5rem);
}
.bloque__titulo--chico::after { width: 32px; height: 3px; }

/* En movil vuelven a apilarse: dos columnas de 46ch no caben, y partirlas mas
   dejaria dos parrafos flacos uno al lado del otro. */
@media (max-width: 899px) {
  .remate__grid { grid-template-columns: minmax(0, 1fr); gap: var(--e5); }
  .remate__cierre p { max-width: 60ch; }
}

.boton {
  display: inline-block;
  padding: .95rem 2rem;
  background: var(--amarillo); color: #0A0A0A;
  font-family: var(--texto); font-weight: 600; font-size: 1rem;
  text-decoration: none;
  transition: background .2s var(--salida), transform .2s var(--salida);
}
.boton:hover { background: var(--verde-oscuro); }
.boton:active { transform: translateY(1px); }

/* --- El pie -------------------------------------------------------------
   El mismo patron de Editorial Circulo Cultural y de Barkys, que es el pie de
   las paginas de caso y de las landings: filete con la marca partiendo la
   linea, menu del sitio separado por filetes verticales, linea legal y nota de
   que trabajo fue y de que ano.

   Viaja DENTRO del fragmento, no en `shared-components`: al integrar, esta
   pagina conserva el suyo. */

.pie {
  padding: clamp(2.5rem, 5vw, 3.5rem) var(--margen) clamp(2rem, 4vw, 3rem);
  /* Mismo papel que el resto de la pagina. El original de Circulo Cultural lo
     pone gris para separarlo del cuerpo; aqui la separacion ya la hace el
     filete de la seccion de cierre, y una franja gris al final rompia el
     blanco continuo que sostiene toda la galeria. */
  background: var(--papel);
  text-align: center;
}
.pie > .contenedor { padding-inline: 0; }

/* Filete con la marca partiendo la linea. */
.pie__filete {
  display: flex;
  align-items: center;
  gap: var(--e3);
  margin-bottom: var(--e4);
}
.pie__filete::before,
.pie__filete::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--linea);
}
.pie__filete img { height: 26px; width: auto; }

/* Menu del pie: enlaces separados por un filete vertical. */
.pie__menu {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--e2) 0;
  margin-bottom: var(--e4);
}
.pie__menu a {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;              /* objetivo tactil */
  padding: 0 clamp(9px, 1.4vw, 17px);
  font-size: .87rem;
  color: var(--tinta-suave);
  text-decoration: none;
  transition: color .2s;
}
.pie__menu a + a::before {
  content: "";
  position: absolute;
  left: 0; top: 50%;
  width: 1px; height: 11px;
  margin-top: -5px;
  background: var(--linea);
}
.pie__menu a:hover { color: var(--tinta); background: var(--amarillo); }

/* En movil el menu cae en dos filas, y el filete de `a + a` deja una rayita
   suelta al empezar la segunda: el selector no sabe donde envuelve el flex.
   Abajo de 700 px se quitan los filetes y separa el espacio. */
@media (max-width: 699px) {
  .pie__menu { gap: 0 var(--e1); }
  .pie__menu a::before { display: none; }
}

.pie__legal { margin: 0; font-size: .8rem; color: var(--tinta-suave); }
.pie__nota { margin: 6px 0 0; font-size: .78rem; color: var(--tinta-suave); opacity: .85; }

/* --- Visor (lightbox) ---------------------------------------------------
   <dialog> nativo: trae el foco atrapado, el Esc y el fondo inerte sin una
   linea de JS. Lo unico que agrega el script es la navegacion con flechas.
   El fondo va oscuro aunque la pagina sea blanca: es la unica manera de que
   una pieza con fondo blanco se lea como pieza y no como parte de la pagina. */

.visor {
  width: 100vw; max-width: 100vw;
  height: 100dvh; max-height: 100dvh;
  padding: 0; border: 0;
  background: transparent;
  overflow: hidden;
}
.visor::backdrop { background: rgb(17 17 17 / .95); }
/* `minmax(0, 1fr)` y no `1fr`: son cosas distintas. `1fr` equivale a
   `minmax(auto, 1fr)`, y ese minimo `auto` es el min-content de lo que hay
   dentro — o sea el alto INTRINSECO de la imagen. Con una pieza vertical la
   fila crecia hasta el tamano real del archivo, la imagen se salia por abajo
   del dialogo y tapaba la barra de navegacion. Medido en Eterna: en un visor
   de 257px de alto, una pieza de 600x1600 se pintaba a 981px.
   El `0` de minimo deja que la fila se encoja y la imagen se ajuste. */
.visor[open] { display: grid; grid-template-rows: minmax(0, 1fr) auto; }

/* Flex y no grid: con `place-items: center` la imagen quedaba de item de
   rejilla y su `max-height: 100%` se resolvia contra una altura que la propia
   imagen estaba estirando. En flex el marco manda y la imagen se ajusta.
   `overflow: hidden` es el cinturon de seguridad por si algo se escapa. */
.visor__marco {
  display: flex; align-items: center; justify-content: center;
  min-height: 0; min-width: 0;
  overflow: hidden;
  padding: clamp(var(--e3), 5vw, var(--e5));
}
.visor__marco img {
  max-width: 100%; max-height: 100%;
  width: auto; height: auto;
  object-fit: contain;
  background: #fff;
}
.visor__barra {
  display: flex; align-items: center; gap: var(--e3);
  padding: var(--e2) clamp(var(--e2), 4vw, var(--e4)) var(--e4);
  color: #f2f2f2;
}
.visor__cuenta {
  flex: 1;
  font-family: var(--dato); font-size: .78rem;
  color: #9a9a9a; white-space: nowrap;
}
.visor__nav { display: flex; gap: .5rem; }

.visor button {
  display: grid; place-items: center;
  width: 2.6rem; height: 2.6rem;
  color: #fff; background: rgb(255 255 255 / .1);
  border: 0; cursor: pointer;
  font-size: 1.1rem; line-height: 1;
  transition: background .2s var(--salida);
}
.visor button:hover:not(:disabled) { background: rgb(255 255 255 / .24); }
.visor button:disabled { opacity: .3; cursor: default; }
.visor__cerrar {
  position: absolute; top: var(--e2); right: clamp(var(--e2), 4vw, var(--e4));
}

/* ==========================================================================
   MOVIMIENTO
   --------------------------------------------------------------------------
   Hay tres capas y cada una responde a una pregunta distinta. Ninguna esta por
   verse bonita: si no se puede decir en una frase que comunica, sobra.

     1. Entrada al hacer scroll     Â¿esto es nuevo? Â¿de donde venia?
     2. Profundidad en la galeria   las piezas llegan desde atras y se posan
     3. Secuencia de apertura       jerarquia: marca, titular, contexto

   El motor preferido es `animation-timeline: view()`, o sea animacion ligada
   al scroll HECHA POR EL NAVEGADOR. No hay un solo listener de scroll ni un
   requestAnimationFrame: el compositor la corre fuera del hilo principal y no
   se cae aunque la pagina tenga 31 imagenes. Donde no exista, el observador de
   `cinco.js` hace la version simple y nadie se entera.
   ========================================================================== */

/* --- Capa 1: entrada, version de respaldo -------------------------------
   Se oculta SOLO si el JS ya corrio (clase .js en el <html>): sin script no se
   esconde nada, porque una animacion no puede ser el motivo por el que alguien
   vea una pagina en blanco. */

.js [data-entra] {
  opacity: 0;
  transform: translateY(20px) scale(.985);
}
.js [data-entra].visible {
  opacity: 1;
  transform: none;
  transition:
    opacity .75s var(--salida) var(--retraso, 0ms),
    transform .75s var(--salida) var(--retraso, 0ms);
}

/* --- Capa 2: profundidad ligada al scroll -------------------------------
   Las piezas no aparecen: se acercan. Entran inclinadas y desde el fondo, y
   terminan de posarse cuando estan bien dentro de la pantalla, asi que el
   efecto se siente al scrollear y no como un parpadeo al cruzar un umbral.

   Se queda corto a proposito. La referencia de galeria 3D gira las imagenes
   durante todo el recorrido; aqui la pieza se endereza y para. Con 31 imagenes
   mantenerlas girando convierte la galeria en un carrusel y deja de poderse
   mirar el trabajo, que es para lo que existe la pagina. */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {

    .galeria, .carrusel, .pares { perspective: 1600px; }
    .galeria > li, .carrusel > li, .pares > .par { transform-style: preserve-3d; }

    /* La animacion manda sobre el estado de la capa 1: una animacion en curso
       gana sobre el valor declarado y sobre la transicion.
       Solo las IMAGENES llegan con profundidad. El texto sube y ya: una linea
       de texto girando en perspectiva se lee peor y no comunica nada. */
    .js:not(.sin-timeline) .galeria > li,
    .js:not(.sin-timeline) .carrusel > li,
    .js:not(.sin-timeline) .par {
      opacity: 1;
      transform: none;
      animation: llega linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 24%;
    }

    .js:not(.sin-timeline) .bloque__titulo[data-entra],
    .js:not(.sin-timeline) .bloque__texto[data-entra] {
      opacity: 1;
      transform: none;
      animation: asoma linear both;
      animation-timeline: view();
      animation-range: entry 8% cover 26%;
    }

    /* Las dos mitades del par llegan desde profundidades distintas y se posan
       en el mismo plano. Es literal: son dos versiones de la misma pieza. */
    .js:not(.sin-timeline) .par__lado--story {
      animation: llega-story linear both;
      animation-timeline: view(); animation-range: entry 0% cover 28%;
    }

    /* Las laminas hacen zoom de salida dentro de su marco durante todo el
       recorrido. Da profundidad sin mover nada de sitio, que es lo unico que
       se puede permitir un elemento que ocupa el ancho completo. La figura
       solo aparece: dos movimientos encima de la misma imagen se pelean. */
    .js:not(.sin-timeline) .lamina {
      opacity: 1; transform: none;
      animation: asoma linear both;
      animation-timeline: view(); animation-range: entry 4% cover 22%;
    }

    .js:not(.sin-timeline) .lamina img {
      animation: acerca linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
      will-change: transform;
    }
  }
}


/* --- Encargo con lateral (tercera imagen movida de a sangre a lado del texto) --- */
.bloque--encargo .encargo__grid {
  display: grid;
  gap: var(--e4) var(--e5);
  grid-template-columns: 1fr;
}
@media (min-width: 900px) {
  .bloque--encargo .encargo__grid {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1.15fr);
    align-items: start;
  }
}
.encargo__visual .pieza {
  background: var(--papel);
  display: block;
  width: 100%;
}
.encargo__visual img {
  width: 100%;
  height: auto;
  display: block;
}
.bloque--encargo .encargo__texto .bloque__texto {
  font-size: clamp(1rem, .97rem + .18vw, 1.06rem);
  line-height: 1.65;
}
.encargo__caption {
  margin: .7rem 0 0;
  font-family: var(--dato); font-size: .72rem; letter-spacing: .02em;
  color: var(--tinta-suave); text-align: center;
}

/* Encargo unificado con degradado: una sola seccion sin hueco bajo imagen */
.bloque--encargo-degradado {
  background: linear-gradient(90deg, #0A0A0A 0%, #0A0A0A 52%, #1f1a00 72%, #FFB800 100%);
  margin-block: 0;
  padding-block: clamp(2.5rem, 5vw, 4rem);
}
.bloque--encargo-degradado .bloque__titulo {
  color: #fff;
}
.bloque--encargo-degradado .bloque__titulo::after {
  background: var(--amarillo);
}
.bloque--encargo-degradado .encargo__texto .bloque__texto {
  color: rgba(255,255,255,.86);
}
.bloque--encargo-degradado .encargo__grid {
  align-items: center;
}
@media (max-width: 899px) {
  .bloque--encargo-degradado {
    background: linear-gradient(180deg, #0A0A0A 0% 65%, #3a2e00 85%, #FFB800 100%);
  }
}


/* Franja pequeña pegada arriba, negro con degradado a amarillo mostaza */
.franja-negra {
  height: 22px;
  background: linear-gradient(90deg, #0A0A0A 0%, #0A0A0A 55%, #FFB800 100%);
  margin: 0;
}
@media (min-width: 900px) {
  .franja-negra { height: 28px; }
}
/* --- Feed tight: sin aire, como Instagram --- */
.galeria--feed {
  gap: 4px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (max-width: 699px) {
  .galeria--feed {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.galeria--feed > li {
  grid-column: auto !important;
  grid-row: auto !important;
}
@media (max-width: 899px) {
  .galeria--feed { gap: 3px; }
}


/* Stories & Reels split: 4 arriba, 5 abajo */
.galeria--reels {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(10px, 1.4vw, 18px);
}
.galeria--stories {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(10px, 1.4vw, 18px);
}
@media (max-width: 1099px) {
  .galeria--reels { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .galeria--stories { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 699px) {
  .galeria--reels,
  .galeria--stories {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Bento para Stories & Reels - 2 lineas como en referencia */
.bento-line {
  display: grid;
  gap: 4px;
  /* Reels arriba y stories abajo son la misma parrilla partida en dos filas, no
     dos bloques distintos: se separan lo mismo que las piezas entre si. */
  margin-bottom: 4px;
}
.bento-line:last-child { margin-bottom: 0; }
@media (max-width: 899px) {
  .bento-line { gap: 3px; margin-bottom: 3px; }
}
.bento-line--reels {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-template-rows: auto;
}
.bento-line--reels .bento-large,
.bento-line--reels .bento-small {
  grid-column: auto !important;
  grid-row: auto !important;
}
.bento-line--reels .bento-large {
  aspect-ratio: 9/16;
}

.bento-line--stories {
  grid-template-columns: repeat(5, minmax(0, 1fr));
  grid-template-rows: auto;
}
.bento-line--stories .bento-large,
.bento-line--stories .bento-small {
  grid-column: auto !important;
  grid-row: auto !important;
}
.bento-line--stories .bento-large {
  aspect-ratio: 9/16;
}
.bento-large .pieza,
.bento-large .pieza--video {
  height: 100%;
}
.bento-large .pieza img,
.bento-large .pieza--video video {
  height: 100%;
  object-fit: cover;
}
.bento-small .pieza img,
.bento-small .pieza--video video {
  aspect-ratio: 9/16;
  object-fit: cover;
  width: 100%;
  height: 100%;
}

@media (max-width: 699px) {
  .bento-line--reels,
  .bento-line--stories {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: auto;
  }
  .bento-line--reels .bento-large,
  .bento-line--stories .bento-large {
    grid-column: 1 / span 2;
    grid-row: auto;
    aspect-ratio: 9/16;
  }
  .bento-line--reels .bento-small,
  .bento-line--stories .bento-small {
    grid-column: auto !important;
    grid-row: auto !important;
  }
  .bento-line--reels .bento-small:nth-child(4) .pieza,
  .bento-line--stories .bento-small:nth-child(5) .pieza {
    max-width: none;
    margin: 0;
  }
}
/* --- Video reels en stories --- */
.pieza--video {
  position: relative;
  background: #000;
  overflow: hidden;
}
.pieza--video video {
  width: 100%; height: auto; display: block;
}
.video__badge {
  position: absolute; top: 8px; right: 8px;
  background: var(--amarillo); color: #0A0A0A;
  font-family: var(--dato); font-size: .62rem; font-weight: 700;
  letter-spacing: .08em; padding: 3px 6px;
}
@keyframes llega {
  from { opacity: 0; transform: translate3d(0, 44px, -150px) rotateX(11deg); }
  to   { opacity: 1; transform: none; }
}
@keyframes llega-story {
  from { opacity: 0; transform: translate3d(0, 44px, -260px) rotateX(11deg); }
  to   { opacity: 1; transform: none; }
}
@keyframes asoma {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: none; }
}
@keyframes acerca {
  from { transform: scale(1.07); }
  to   { transform: scale(1); }
}

/* --- Capa 3: secuencia de apertura --------------------------------------
   Las tiras del fondo del hero. Cada una recorre la mitad de su propia altura
   y vuelve a empezar; como el contenido esta duplicado, el salto es invisible.
   Velocidades distintas por tira: es lo que vende la profundidad. Las pares
   van al reves para que el conjunto no parezca una sola cortina bajando.

   Se anima `transform`, nunca `top`: solo asi el trabajo se queda en el
   compositor y no obliga a recalcular la maqueta en cada fotograma. */

.js .tira { animation: desfilar var(--vel, 70s) linear infinite; }
.js .tira:nth-child(even) { animation-direction: reverse; }
.js .tira:nth-child(1) { --vel: 68s; }
.js .tira:nth-child(2) { --vel: 84s; }
.js .tira:nth-child(3) { --vel: 74s; }
.js .tira:nth-child(4) { --vel: 92s; }

@keyframes desfilar {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(0, -50%, 0); }
}

/* El texto del hero entra escalonado al cargar: la marca, el rotulo, el
   titular y la bajada. Es la jerarquia de quien mira: de quien es la pagina,
   que trabajo es y de quien es el cliente. */
.js .marca           { animation: sube .7s var(--salida) both; animation-delay: .05s; }
.js .portada__rotulo { animation: sube .8s var(--salida) both; animation-delay: .10s; }
.js .portada__titulo { animation: sube .9s var(--salida) both; animation-delay: .22s; }
.js .portada__bajada { animation: sube .9s var(--salida) both; animation-delay: .38s; }

@keyframes sube {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* --- El interruptor -----------------------------------------------------
   Una sola regla apaga las tres capas. Va al final para que gane siempre. */

@media (prefers-reduced-motion: reduce) {
  .js [data-entra] { opacity: 1; transform: none; transition: none; }
  .js .tira { animation: none; }
  .js .marca, .js .portada__rotulo, .js .portada__titulo,
  .js .portada__bajada,
  .js .galeria > li, .js .carrusel > li, .js .par,
  .js .par__lado--story, .js .lamina, .js .lamina img {
    animation: none;
    opacity: 1;
    transform: none;
    clip-path: none;
  }
  .pieza img, .boton { transition: none; }
  .pieza:hover img, .pieza:focus-visible img { transform: none; }
}

/* --- Impresion ----------------------------------------------------------
   Un caso de portafolio se imprime a PDF mas seguido de lo que parece. */
@media print {
  .visor, .remate .boton { display: none; }
  .js [data-entra] { opacity: 1; transform: none; }
  .galeria { grid-template-columns: repeat(3, 1fr); }
}











/* --- Video cuadrado dentro del feed ---------------------------------------
   El gif del feed dejo de ser una imagen fija: ahora es un mp4 y tiene que
   ocupar exactamente la misma celda que las otras cinco piezas. */
.pieza--cuadrado video {
  aspect-ratio: 1 / 1;
  object-fit: cover;
  width: 100%;
  height: auto;
}
.galeria--feed .pieza--video {
  display: block;
  width: 100%;
}
/* El poster tapa el hueco mientras el mp4 baja; el fondo negro solo se ve en
   los verticales, que no llenan la celda al vuelo. */
.pieza--video video { background: #000; }
