/* ============================================================
   GINO GIGLIO — PORTFOLIO

   Estructura calcada de laboile.com. Medidas del original a 1280 px:
     columna de la marca ...... 800 / 1280 = 62,5 % centrada
     portada .................. 1254 × 463, contenido 803 × 400
                                → margen 2,5 % / 18 %, proporción 2:1
     galería .................. filas de 214,5 px, gutter de 8
     pie ...................... padding 60 / 0, centrado

   Dos cosas que NO son del original, pedidas por Gino:
     · el título de la serie va en el primer tercio, no en la mitad derecha
     · al aparecer el título, la foto se va de foco

   La tipografía de la marca y de los títulos va en SVG (carpeta svg/),
   ya convertida a curvas. Acá sólo se le da tamaño y color.
   ============================================================ */

@font-face {
  font-family: 'Avant Garde';
  src: local('ITCAvantGardeStd-Bk'), local('ITC Avant Garde Gothic Std Book'),
       url('../tipografia/ITCAvantGardeStd-Bk.ttf') format('truetype');
  font-weight: 400; font-style: normal; font-display: swap;
}

:root {
  --tinta: #111111;
  --papel: #ffffff;
  --cyan: #00ffff;
  --marcador: #f2f2f2;             /* fondo de las fotos mientras cargan */

  --logo: 56px;                    /* tamaño de la marca */
  --sangria: 60px;                 /* sangría del título sobre la foto */

  /* HOME. El panel de la izquierda no se mueve y las portadas pasan
     al costado. El 30 está confirmado con Gino y no se toca.
     Entre los dos no hay línea: lo único que los separa es el aire. */
  --panel: 30%;
  --aire: 56px;                    /* respiro del panel y de las fotos */
  --aire-entre-fotos: 40px;
  --bajada-abajo: .5;              /* aire entre ARTISTA VISUAL y BIO */

  /* Los títulos de sección SIEMPRE por debajo del nombre del artista.
     Salen de --logo, así que la jerarquía no se puede romper aunque
     cambie el tamaño de la marca. El 1.0452 compensa que Avenir tiene
     la mayúscula más baja que Avant Garde (.708 contra .740 em);
     el último factor es la altura respecto a GINO GIGLIO. */
  --compensa-avenir: 1.0452;
  --cuerpo-titulo-cover: calc(var(--logo) * var(--compensa-avenir) * .80);
  --cuerpo-titulo-serie: calc(var(--logo) * var(--compensa-avenir) * .75);
  --cuerpo-siguiente:    calc(var(--logo) * var(--compensa-avenir) * .50);

  --gutter: 8px;                   /* separación entre fotos */
  --marca-em: 3.444;               /* ancho de svg/marca.svg por cada px de cuerpo */
  --bajada-em: 3.21775;            /* ancho de svg/bajada.svg por cada px de cuerpo */

  --fuente: 'Avant Garde', 'ITC Avant Garde Gothic Std', 'Century Gothic',
            'URW Gothic', 'Futura', sans-serif;
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--papel);
  color: var(--tinta);
  font-family: var(--fuente);
  font-size: 16px;
  line-height: 1.4;
  text-transform: uppercase;
  /* Avant Garde trae los encastres en 'liga', que el navegador activa
     solo. Sin esto aparecen letras montadas en MONOCROMO, PRODUCTO… */
  font-variant-ligatures: none;
  font-feature-settings: 'liga' 0, 'clig' 0, 'dlig' 0, 'hlig' 0, 'calt' 0,
                         'ss01' 0, 'ss02' 0, 'ss03' 0, 'ss04' 0, 'ss05' 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; margin: 0; padding: 0; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }

::selection { background: var(--cyan); color: var(--tinta); }
:focus-visible { outline: 2px solid var(--tinta); outline-offset: 3px; }

/* ---------- LA MARCA ---------- */

.marca { width: calc(var(--logo) * var(--marca-em)); height: auto; flex: none; }
.marca__bajada { width: calc(var(--logo) * var(--bajada-em)); height: auto; flex: none; }

.titulo { height: auto; }

/* ---------- PANEL FIJO ----------

   Lo usan las seis páginas. La cabecera de arriba y el pie del fondo
   que había antes ya no existen: todo eso vive acá.

   El panel toma el alto de la ventana y reparte con space-between:
   la marca se apoya arriba y ARTISTA VISUAL con los enlaces abajo.
   Ningún border acá, la separación con las fotos es el aire. */

.panel {
  position: fixed;
  top: 0; left: 0;
  width: var(--panel);
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: var(--aire);
}

.panel__marca { display: block; width: fit-content; transition: opacity .2s; }
.panel__marca:hover { opacity: .6; }

/* ARTISTA VISUAL conserva el ancho que tenía debajo de la marca, que
   es casi el de GIGLIO. Así las dos puntas del panel arman columna. */
.panel__pie .marca__bajada {
  width: calc(var(--logo) * var(--bajada-em));
  margin-bottom: calc(var(--logo) * var(--bajada-abajo));
}

.panel__enlaces { display: flex; flex-direction: column; gap: 14px; }
.panel__enlaces a {
  font-size: 12px;
  letter-spacing: .14em;
  opacity: .45;
  width: fit-content;
  transition: opacity .2s;
}
.panel__enlaces a:hover { opacity: 1; }

/* BIO es navegación y lo de abajo es contacto: un respiro los separa. */
.panel__bio { margin-bottom: 12px; }

/* Las redes van con el logo, no con la palabra. INSTAGRAM y BEHANCE
   siguen escritos en el HTML, apagados a la vista, porque un <img> sin
   texto no le dice nada a un lector de pantalla.

   Cada logo lleva su propia medida: el aire alrededor del dibujo es
   distinto en cada archivo. El de Instagram ocupa casi todo el cuadro
   y el Bē de Behance es apaisado y deja borde arriba y abajo. Con el
   mismo alto uno se vería el doble que el otro. */
.redes {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-top: 4px;
}
.icono { display: block; width: auto; }
.icono--ig { height: 22px; }
.icono--be { height: 27px; }

.rotulo {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.redes a { opacity: .55; transition: opacity .2s; }
.redes a:hover, .redes a:active { opacity: 1; }

/* El botón de las rayas sólo existe en pantalla chica. */
.menu { display: none; }

/* ---------- HOME · PORTADAS ---------- */

/* La columna de las fotos scrollea con la página. El margen la corre
   fuera del panel y el padding es el aire que hace de separación. */
.lienzo {
  margin-left: var(--panel);
  padding: var(--aire) var(--aire) var(--aire) 0;
  display: flex;
  flex-direction: column;
  gap: var(--aire-entre-fotos);
}

.portada { display: block; position: relative; width: 100%; }

.portada__foto {
  position: relative;
  aspect-ratio: 2 / 1;
  overflow: hidden;
  background: var(--marcador);         /* marcador mientras no hay foto */
}

.portada__foto img,
.portada__foto video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: filter .45s ease, transform .45s ease;
}

/* Al aparecer el título, la foto se va de foco.
   El scale tapa el borde difuminado que deja el blur.

   El hover queda encerrado en (hover: hover) para que no corra en
   pantallas táctiles: ahí el navegador lo dispara pegado al tap y
   el título aparece y desaparece de golpe. En táctil manda la clase
   .portada--activa, que pone js/portadas.js en el primer toque. */
@media (hover: hover) {
  .portada:hover .portada__foto img,
  .portada:hover .portada__foto video {
    filter: blur(14px);
    transform: scale(1.06);
  }
}

.portada--activa .portada__foto img,
.portada--activa .portada__foto video {
  filter: blur(14px);
  transform: scale(1.06);
}

.portada__velo {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  padding-left: var(--sangria);
  opacity: 0;
  transition: opacity .3s ease;
}
@media (hover: hover) {
  .portada:hover .portada__velo { opacity: 1; }
}
.portada--activa .portada__velo,
.portada:focus-visible .portada__velo { opacity: 1; }

/* los títulos son SVG negros: acá se invierten a blanco */
.portada__velo .titulo { filter: invert(1); }

/* ---------- PÁGINA DE SERIE ----------

   Mismo panel y mismo lienzo que el home. Lo único distinto es lo que
   entra en el lienzo: título de la serie, grilla y enlace a la que
   sigue, en lugar de las cinco portadas. */

.lienzo--serie { gap: 0; }

/* El título de la serie ya no se ve. La página abre con la foto, y el
   borde de arriba de la primera foto queda a la misma altura que el de
   GINO GIGLIO, igual que en la home: los dos a 56 px, que es --aire.
   El h1 sigue existiendo para el lector de pantalla y para el buscador,
   que si no la página se queda sin encabezado. */
.seccion__titulo {
  position: absolute;
  width: 1px; height: 1px;
  margin: 0; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- BIO ----------

   La bio abre igual que la home: la foto a todo el ancho del lienzo,
   recortada a 2:1 como las cinco portadas. Abajo, el texto corre en
   dos columnas parejas que juntas ocupan el mismo ancho que la foto,
   con 40 de aire en el medio, el mismo que separa la foto del texto.

   El texto va en caja normal (párrafos corridos en mayúsculas no se
   leen), en Helvetica Neue y con interlineado de 24, o sea 3 veces
   la unidad de 8: las líneas de las dos columnas comparten baseline.
   El navegador balancea las columnas para que cierren en la misma
   horizontal, y ningún párrafo se parte entre columnas. */

.grilla--bio { gap: 40px var(--gutter); }

.grilla--bio .foto--bio {
  grid-column: 1 / -1;
  aspect-ratio: 2 / 1;
  overflow: hidden;
}
.grilla--bio .foto--bio .foto__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.grilla--bio .bio {
  grid-column: 1 / -1;
  text-transform: none;
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  font-size: 15px;
  line-height: 24px;
}

/* SOY ARTISTA VISUAL abre sola, a modo de título, fuera de las
   columnas. El reparto es el de la maqueta de Gabi: Nací y Mi vínculo
   a la izquierda; a la derecha Con el tiempo y Desde entonces van
   pegados en un solo bloque, y después Trabajo y Me conmueven.

   Las columnas cierran en la misma línea sin estirar ningún aire:
   izquierda 8+5 líneas y un aire, derecha 6+3+3 y dos aires, catorce
   unidades de 24 por lado. Ese equilibrio vale con la izquierda entre
   434 y 454 px de ancho: por eso el bloque va a ancho fijo (la foto
   acompaña, están en la misma grilla) y las columnas en 444/468.
   Tocar el texto de la bio puede romper la cuenta: medir de nuevo. */
.grilla--bio { max-width: 952px; }
.grilla--bio .bio__columnas {
  display: grid;
  grid-template-columns: 444fr 468fr;
  column-gap: 40px;
}
.grilla--bio .bio p {
  margin: 0 0 24px;
  break-inside: avoid;
}
.grilla--bio .bio p:last-child { margin-bottom: 0; }
.bio p { margin: 0 0 1.5em; }
.bio p:last-child { margin-bottom: 0; }

/* En el panel, BIO se queda prendido cuando es la página actual. */
.panel__enlaces a[aria-current="page"] { opacity: 1; }

/* ---------- GRILLA RECTANGULAR ----------

   Seis columnas sobre el ancho útil del lienzo. A 1440 eso da 952 px:
   columna de 152, gutter de 8, y cuatro anchos de bloque nada más.

     2 col  312    vertical
     3 col  472    apaisada
     4 col  632    apaisada que comparte fila con una vertical
     6 col  952    panorámica, o la apaisada más ancha de la serie

   El ancho lo decide la proporción de la foto. Con tres columnas
   parejas una apaisada 3:2 quedaba de 312 x 208 contra 312 x 468 de
   una vertical, el 44 % del área. Con seis, las dos ocupan casi lo
   mismo: 148.680 y 146.016 px². Misma presencia, distinta forma.

   Ninguna fila mezcla familias que no se emparejen en alto, así el
   hueco que queda abajo de la foto más baja nunca pasa de unos 80 px.
   Esos huecos son parte del sistema: la trama necesita módulos vacíos.

   Nadie se recorta y nadie se estira: cada foto entra con su
   proporción real. El reparto en filas lo calcula
   herramientas/grilla.py y viene escrito en el HTML, así que esto
   funciona sin una línea de JavaScript. */

.grilla {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--gutter);
  align-items: start;
  margin: 0;
}

.grilla .foto--v  { grid-column: span 2; }
.grilla .foto--h  { grid-column: span 3; }
.grilla .foto--hh { grid-column: span 4; }
.grilla .foto--p  { grid-column: 1 / -1; }

/* El quiebre. Una sola foto por página se come el aire de la derecha y
   llega al borde de la ventana. Va tarde en el scroll a propósito: se
   lee como decisión recién cuando la trama ya está establecida. */
.foto--sangre { width: calc(100% + var(--aire)); max-width: none; }

/* ---------- GALERÍA MASONRY ----------

   Ya no la usa ninguna página: las cinco series pasaron a la grilla de
   arriba. Queda por si hace falta volver atrás, junto con js/galeria.js,
   que tampoco carga en ningún lado.

   Era masonry de columnas de ancho fijo. El JavaScript ponía la clase
   galeria--masonry y recién ahí arrancaban las columnas, sin mover un
   solo nodo. Sin JavaScript quedaba una sola columna, las fotos
   apiladas a todo el ancho, y no se rompía nada. */
.galeria { margin: 0; }

.foto {
  position: relative;
  margin: 0 0 var(--gutter);
  cursor: pointer;
}

/* En la grilla el aire lo pone el gap, no el margen de cada foto. */
.grilla .foto { margin: 0; }

/* Con JavaScript. El ancho y la posición de cada foto los escribe
   galeria.js, y el alto de la galería también, porque con las fotos
   absolutas se queda sin alto propio. */
.galeria--masonry { position: relative; }
.galeria--masonry .foto {
  position: absolute;
  top: 0;
  left: 0;
  margin: 0;
}

/* Al 100% del ancho de su columna y el alto que le da su proporción.
   Nada de object-fit: acá no se recorta ninguna foto. */
.foto__img,
.foto__vacia {
  display: block;
  width: 100%;
  height: auto;
  background: var(--marcador);         /* marcador mientras no cargó */
  transition: opacity .2s;
}
.foto__vacia { background: var(--cyan); }   /* foto faltante: el cyan avisa */
.foto:hover .foto__img { opacity: .78; }

/* ---------- SIGUIENTE SERIE ---------- */

.siguiente {
  display: flex;
  align-items: center;
  gap: 20px;
  margin: clamp(40px, 6vw, 84px) 0 0;
  padding: clamp(18px, 2.4vw, 28px) 0 0;
  border-top: 1px solid rgba(17, 17, 17, .14);
}
.siguiente__rotulo { font-size: 13px; opacity: .45; }
.siguiente .titulo { transition: opacity .2s; }
.siguiente:hover .titulo { opacity: .5; }

/* ---------- VISOR ---------- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(255, 255, 255, .98);
  display: grid;
  place-items: center;
  padding: 70px 90px;
}
.lightbox[hidden] { display: none; }

.lightbox__stage { display: grid; place-items: center; max-width: 100%; max-height: 100%; }
.lightbox__stage img,
.lightbox__stage video { max-width: min(1400px, 88vw); max-height: 82vh; width: auto; height: auto; object-fit: contain; }
.lightbox__placeholder { background: var(--marcador); width: min(900px, 80vw); }

.lightbox__caption {
  position: absolute;
  bottom: 26px; left: 0; right: 0;
  text-align: center;
  font-size: 12px;
  letter-spacing: .14em;
  opacity: .45;
}

.lightbox__close {
  position: absolute; top: 22px; right: 26px;
  font-size: 18px; opacity: .55; transition: opacity .2s;
}
.lightbox__close:hover { opacity: 1; }

.lightbox__arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 60px; height: 60px; font-size: 22px; opacity: .45; transition: opacity .2s;
}
.lightbox__arrow:hover { opacity: 1; }
.lightbox__arrow--prev { left: 14px; }
.lightbox__arrow--next { right: 14px; }

body.lightbox-abierto { overflow: hidden; }

/* ---------- RESPONSIVE ---------- */

@media (max-width: 1100px) {
  :root {
     --sangria: 40px; --logo: 46px;
    --aire: 40px; --aire-entre-fotos: 28px;
  }
}

/* Abajo de 900 px el panel al 30 % deja menos de 270 px y la marca no
   entra. Ahí el panel deja de ser columna y pasa a ser cabecera:
   la marca a la izquierda, el botón de las rayas a la derecha, y todo
   lo que en escritorio va abajo cuelga del botón. */
@media (max-width: 900px) {
  .panel {
    position: relative;            /* de acá cuelga el desplegable */
    width: 100%;
    height: auto;
    display: block;
    padding: var(--aire) var(--aire) 0;
    z-index: 50;
  }

  .panel__cabeza {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 20px;
  }

  .menu {
    display: block;
    flex: none;
    width: 34px;
    height: 34px;
    margin-top: 2px;
    padding: 8px 4px;
  }
  .menu__raya {
    display: block;
    width: 26px;
    height: 1.5px;
    background: var(--tinta);
    transition: transform .25s ease;
  }
  .menu__raya + .menu__raya { margin-top: 7px; }

  /* Abierto, las dos rayas se cruzan y hacen la cruz de cerrar. */
  .panel--abierto .menu__raya:first-child { transform: translateY(4.25px) rotate(45deg); }
  .panel--abierto .menu__raya:last-child  { transform: translateY(-4.25px) rotate(-45deg); }

  /* El desplegable cae del botón y se apoya sobre la primera foto.
     Fondo papel para que se lea encima de cualquier imagen. */
  .panel__pie {
    display: none;
    position: absolute;
    top: 100%;
    right: var(--aire);
    z-index: 60;
    background: var(--papel);
    padding: 20px 22px 22px;
    text-align: right;
  }
  .panel--abierto .panel__pie { display: block; }

  .panel__pie .marca__bajada { margin-left: auto; }
  .panel__enlaces { align-items: flex-end; }

  /* Los logos son los mismos de escritorio, un toque más grandes
     porque acá se tocan con el dedo, y alineados a la derecha con el
     resto del desplegable. */
  .redes { justify-content: flex-end; margin-top: 6px; }
  .icono--ig { height: 26px; }
  .icono--be { height: 32px; }
  .redes a { opacity: .75; }

  .lienzo { margin-left: 0; padding: var(--aire); }

  /* La vertical pasa a media fila y la apaisada a fila entera. Seis
     columnas acá dejarían la vertical en 130 px. */
  .grilla .foto--v  { grid-column: span 3; }
  .grilla .foto--h,
  .grilla .foto--hh { grid-column: 1 / -1; }
  .grilla .foto--sangre { width: 100%; }
  .grilla--bio .bio { grid-column: 1 / -1; }
}

/* En pantalla angosta las dos columnas de texto quedarían en menos
   de 300 px cada una: pasa a una sola. */
@media (max-width: 700px) {
  .grilla--bio .bio__columnas { grid-template-columns: 1fr; row-gap: 24px; }
}

/* En el teléfono una sola columna: dos dejarían las fotos en 160 px y
   un portfolio de fotografía no se mira así. */
@media (max-width: 560px) {
  .grilla { grid-template-columns: 1fr; }
  .grilla .foto { grid-column: 1 / -1; }
}

@media (max-width: 768px) {
  :root {
     --sangria: 24px; --logo: 34px;
    --aire: 24px; --aire-entre-fotos: 20px;
  }
  .site-header { padding: 40px 0 34px; }
  .lightbox { padding: 60px 20px; }
  .lightbox__arrow { width: 44px; height: 44px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
