/* ============================================
   CSS compartido — páginas de PRODUCTO
   (Trinity, Omni, Infinity, Light Mirage)
   Se suma a css/styles.css (tokens, nav, footer, etc.), que se
   carga primero. Acá solo van los componentes propios de estas
   páginas, para no inflar el styles.css del Home con cosas que
   el Home no usa.
   ============================================ */

/* ---------- Hero de producto ----------
   La foto ya trae el nombre del producto escrito (ej: "Trinity"), así
   que no hay h1 aparte. Va de borde a borde igual que el hero del
   Home (misma clase .hero, mismos breakpoints de aspect-ratio:
   16:9 desktop, 1:1 tablet, 9:16 celular), pero como imagen fija, sin
   slideshow. El texto de descripción va superpuesto sobre la foto,
   abajo, con un degradé oscuro detrás para que se lea. */
.product-hero{
  background: #000000;
}
.product-hero .hero > img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* El degradé (el "fondo" de esta zona) vive en su propio elemento fijo,
   nunca en el mismo que anima opacity — si no, el degradé se
   desvanecería junto con el texto en vez de quedar siempre visible. */
.product-hero__scrim{
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 60px var(--margin-x) 40px;
  background: linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0) 100%);
  text-align: center;
}
.product-hero__caption{
  max-width: 640px;
  margin: 0 auto;
  font-size: 20px;
  line-height: 1.6;
  color: var(--fg);
  font-weight: 300;
}
/* Desktop: texto +30% y más ancho, para que entre en 2 líneas en vez
   de 3 (solo acá — en tablet/celular queda como está arriba).
   El corte es el mismo Punto Quiebre Hamburguesa (1138px) que usa el
   resto del sitio: antes de eso, con menos ancho real disponible,
   900px de max-width no entraba y el texto tocaba los bordes. */
@media (min-width: 1139px){
  .product-hero__caption{
    max-width: min(900px, 90%); /* nunca más ancho que el 90% del espacio real */
    font-size: 26px; /* 20px + 30% */
  }
}

/* ---------- Omni: bajada del hero más grande (pedido explícito, solo
   esta ventana — Trinity/Infinity siguen con el tamaño de arriba) ----------
   +20% en mobile, +30% en tablet y desktop, cada uno sobre su propio
   valor actual (no todos desde el mismo base): 20px -> 24px en
   mobile; 20px -> 26px en tablet/desktop angosto (641-1138px, el
   mismo tramo que hoy comparte tamaño con mobile); 26px -> 33.8px en
   desktop real (≥1139px, que ya tenía su propio +30% aplicado antes
   de este pedido). */
@media (max-width: 640px){
  .product-hero__caption.product-hero__caption--omni{
    font-size: 24px; /* 20px + 20% */
  }
}
@media (min-width: 641px) and (max-width: 1138px){
  .product-hero__caption.product-hero__caption--omni{
    font-size: 26px; /* 20px + 30% */
  }
}
@media (min-width: 1139px){
  .product-hero__caption.product-hero__caption--omni{
    font-size: 33.8px; /* 26px + 30% */
  }
}

/* ---------- Omni: bajada del hero, corte de renglón fijo solo en
   tablet (641-819px, breakpoint general del sitio) — "Transforma el
   espacio" / "creando una experiencia cautivante." en 2 renglones
   pedidos a mano, no por wrap natural. En mobile y desktop sigue
   fluyendo como texto corrido normal. */
.product-hero__caption--omni .omni-hero-break{
  display: none;
}
@media (min-width: 641px) and (max-width: 819px){
  .product-hero__caption--omni .omni-hero-break{
    display: inline;
  }
}

/* ---------- Desarrollos a Medida (solo inglés): "Digital Art
   Installation Design" y "Space Identity Definition" en 1 renglón en
   desktop ---------- */
@media (min-width: 820px){
  #creacion-instalaciones h2 .dev-oneline-break,
  #definicion-identidad h2 .dev-oneline-break{
    display: none;
  }
}

/* ---------- Trinity — Opciones/Dimensiones (solo celular): "1 m,
   1,60 m y 2,20 m de ancho" entero en el segundo renglón, pedido
   puntual del cliente. En tablet/desktop sigue en el mismo renglón
   que "Disponible en 3 tamaños:", sin salto forzado. ---------- */
.trinity-dim-mobile-break{
  display: none;
}
@media (max-width: 640px){
  .trinity-dim-mobile-break{
    display: inline;
  }
}

/* ---------- Infinity — Opciones/Dimensiones (solo celular): "desde
   60 x 40 cm hasta 2 x 1,4 m" entero en el segundo renglón, mismo
   criterio que Trinity arriba. ---------- */
.infinity-dim-mobile-break{
  display: none;
}
@media (max-width: 640px){
  .infinity-dim-mobile-break{
    display: inline;
  }
}

/* ---------- Video de prueba (Trinity, debajo del hero) ----------
   A modo de prueba, para que el cliente vea cómo queda un video de
   YouTube embebido en la página — no es un componente definitivo
   todavía. Mismo criterio que el resto del sitio: fondo negro propio
   del bloque (nunca heredado), separado del contenido que hace fade
   (regla de oro #2). */
.product-video{
  background: #000000;
  padding: 80px var(--margin-x);
}
/* Tablet y celular: de borde a borde, sin margen lateral ni tope de
   ancho — pedido explícito, a diferencia del desktop, que sí lo
   conserva centrado con margen. */
@media (max-width: 819px){
  .product-video{
    padding: 80px 0;
  }
}
.product-video__frame{
  position: relative;
  max-width: 960px;
  margin: 0 auto;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}
@media (max-width: 819px){
  .product-video__frame{
    max-width: none;
  }
}
.product-video__frame iframe{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* ---------- Título de sección sin grid-section (ej: "Hard & Soft" /
   "Experiencia interactiva", que son h3 chicos dentro de columnas,
   no un h2 de sección) ---------- */
.section-subtitle{
  font-family: 'Archivo', var(--font-display);
  font-stretch: 125%;
  font-variation-settings: "wdth" 125;
  font-weight: 400;
  font-size: 28px;
  line-height: 1.15;
  letter-spacing: 0.012em;
  margin: 0 0 30px;
}
/* Mismo tamaño que section.grid-section h2 en cada formato: 28px queda
   solo para celular; en tablet y desktop iguala al h2 (36px / 46.8px). */
@media (min-width: 641px) and (max-width: 819px){
  .section-subtitle{
    font-size: 36px; /* igual a section.grid-section h2 en tablet */
  }
}
@media (min-width: 820px){
  .section-subtitle{
    /* mismo clamp() que section.grid-section h2: crece gradualmente
       hasta los 1440px en vez de saltar a 46.8px de golpe a los 820px */
    font-size: clamp(36px, 1.7391vw + 21.7565px, 46.8px);
  }
}

/* ---------- Texto de cierre debajo de una galería (centrado) ---------- */
.section-caption{
  max-width: 640px;
  margin: 23px auto 0; /* 46px - 50%: más cerca de la galería de arriba */
  padding: 0 var(--margin-x) 100px; /* mismo espacio hasta la línea divisoria que usa .item .cap en el Home */
  text-align: center;
}
.section-caption p{
  font-size: 20px;
  line-height: 1.6;
  color: var(--fg); /* blanco, antes fg-dim */
  font-weight: 300;
  margin: 0 0 20px;
}
.section-caption p:last-child{ margin-bottom: 0; }

/* Opciones (Trinity / Infinity / Omni): separación del título a la
   línea divisoria de arriba, mismo criterio de espaciado estándar
   (100px) que se usa en el resto de las secciones sin foto/galería
   propia arriba. */
#opciones{
  padding-top: 100px;
  padding-bottom: 100px; /* misma separación que arriba, hasta la línea divisoria de abajo */
}
/* Celular: las líneas divisorias (arriba y abajo de la sección) quedan
   un 50% más cerca del texto de Opciones (100px -> 50px). El espacio
   de las líneas hacia afuera (a las fotos de arriba / al video o al
   logo de abajo) no es este padding — es el de la sección vecina — así
   que queda sin tocar. */
@media (max-width: 640px){
  #opciones{
    padding-top: 50px;
    padding-bottom: 50px;
  }
}
/* ---------- 3 columnas de datos (Dimensiones / Adquisición /
   Contenido) ----------
   Desktop: lado a lado. Los títulos van más chicos que el h2
   estándar del sitio (36px-46.8px) — pedido explícito, si no, las 3
   columnas no entran juntas en el ancho de pantalla.
   Tablet y celular: apiladas, cada título con su propio texto debajo
   (no hay problema de ancho acá, así que no hace falta achicarlos). */
.spec-columns{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--photo-gap);
  text-align: center;
}
.spec-columns__col .section-subtitle{
  margin-bottom: 20px;
}
/* Desktop angosto (820px-1440px): los 3 títulos quedaban muy pegados
   entre sí con el tamaño estándar del h2 (que recién llega a su
   mínimo, 36px, a partir de acá). Este clamp() propio arranca más
   chico (32px) a los 820px y llega al mismo tamaño que el resto de
   los títulos del sitio (46.8px) recién a los 1440px de referencia
   — mismo criterio que el clamp() del h2, con piso más bajo. */
@media (min-width: 820px){
  .spec-columns__col .section-subtitle{
    font-size: clamp(32px, 2.387vw + 12.43px, 46.8px);
  }
}
.spec-columns__col p{
  font-size: 20px;
  line-height: 1.6;
  color: var(--fg);
  font-weight: 300;
  margin: 0 0 10px; /* -50% del estándar (20px): separación entre renglones de un mismo texto, no la del título al texto (esa la maneja .section-subtitle de arriba, sin tocar) */
  padding-inline: 16px;
}
.spec-columns__col p:last-child{ margin-bottom: 0; }
@media (min-width: 1139px){
  .spec-columns__col p{ font-size: 26px; } /* mismo tamaño que el resto de los textos del sitio en desktop (.section-caption p) */
}
@media (max-width: 819px){
  .spec-columns{
    display: block; /* apiladas: título + texto, una columna debajo de la otra */
  }
  .spec-columns__col{
    padding-bottom: 60px;
  }
  .spec-columns__col:last-child{
    padding-bottom: 0;
  }
}
/* Proyección mapeada (Infinity): ya no cierra con un .section-caption
   propio (se movió a #opciones), así que hay que devolverle a mano el
   espacio hasta la línea divisoria de Formato Display — acá un 50%
   más que el estándar del resto del sitio (150px en vez de 100px),
   pedido explícito del cliente para este quiebre puntual. */
#proyeccion-mapeada{
  padding-bottom: 150px;
}
/* Formato Display: mismo caso, tampoco cierra con .section-caption
   propio — se le devuelve el espacio estándar (100px, el mismo que
   usa el resto de las secciones) hasta la línea divisoria de
   Opciones, que ahora la sigue. */
#formato-display{
  padding-bottom: 100px;
}
/* Omni: mismo caso que Proyección mapeada/Formato Display en
   Infinity — las 2 fotos finales tampoco cierran con
   .section-caption propio, se le agrega el espacio estándar hasta
   la línea divisoria de Opciones. */
#omni-final-fotos{
  padding-bottom: 100px;
}
/* Infinity: línea divisoria entre Opciones y el logo de cierre
   (.product-outro no trae una por defecto). + (no ~) porque en esta
   página son hermanos directos, uno al lado del otro. */
#opciones + .product-outro{
  border-top: 1px solid transparent;
  border-image: linear-gradient(to right, #000000 0%, rgba(255,255,255,0.7) 50%, #000000 100%) 1;
}
/* Desktop: mismo tamaño que el texto del hero (.product-hero__caption,
   ver más arriba), mismo breakpoint (1139px, Punto Quiebre Hamburguesa). */
@media (min-width: 1139px){
  .section-caption{ max-width: 900px; } /* más ancho: menos renglones, texto menos comprimido */
  .section-caption p{ font-size: 26px; }
}

/* ---------- Galería de 3 fotos (Escultura / Arte Digital) ----------
   Desktop y tablet: de borde a borde, ocupan todo el ancho de la
   pantalla, pegadas entre sí con el --photo-gap estándar. Las
   columnas están en proporción exacta al ancho real de cada foto a
   una altura compartida (angosta - ancha - angosta), y el contenedor
   fija su aspect-ratio a esa misma suma — así ninguna foto se
   recorta, solo se escala el conjunto entero según el ancho de
   pantalla disponible.
   Ratios reales: izquierda 788x1388 (0.568), centro 1690x1330 (1.271),
   derecha 786x1388 (0.566) — mismas proporciones en Escultura y Arte
   Digital (comparten dimensiones).
   Celular: carrusel con scroll horizontal — una foto grande a la vez,
   se desliza para ver las siguientes (angosta -> ancha -> angosta),
   con scroll-snap para que cada una quede centrada y completa. */

/* Barra de scroll nativa oculta en cualquier galería con swipe: la
   señal de "esto se desliza" la dan los puntitos (.gallery-dots),
   no una scrollbar del navegador. */
.trio-gallery,
.duo-gallery,
.lightbox__track,
.natural-gallery{
  scrollbar-width: none;      /* Firefox */
  -ms-overflow-style: none;   /* versiones viejas de Edge */
}
.trio-gallery::-webkit-scrollbar,
.duo-gallery::-webkit-scrollbar,
.lightbox__track::-webkit-scrollbar,
.natural-gallery::-webkit-scrollbar{
  display: none;              /* Chrome, Safari */
}

.trio-gallery{
  display: grid;
  grid-template-columns: 0.568fr 1.271fr 0.566fr;
  gap: var(--photo-gap);
  width: 100%;
  aspect-ratio: 2.405 / 1;
}
.trio-gallery img{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Foto extra que solo existe para el formato celular (Trinity —
   Escultura y Arte Digital): en desktop/tablet no se toca la grilla
   de 3 fotos angosta-ancha-angosta de siempre, esta se queda afuera.
   Selector con "img" repetido (no solo la clase) para igualar la
   especificidad de ".trio-gallery img" de arriba y poder ganarle. */
.trio-gallery img.trio-gallery__mobile-photo{
  display: none;
}

@media (max-width: 640px){
  .trio-gallery{
    display: flex;
    width: auto;
    aspect-ratio: auto;
    overflow-x: auto;
    overflow-y: hidden; /* explícito, no implícito: -webkit-overflow-scrolling:touch no distingue eje, y con overflow-y en "auto" (el valor por default) iOS trata este cuadro como si también tuviera scroll vertical propio — ahí "rebotaba" el dedo en vez de pasarle el gesto a la página */
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    /* Sin touch-action: el bloqueo a horizontal-solo lo hace el propio
       Safari/iOS de forma nativa (si el gesto arranca claramente
       vertical u horizontal, lo bloquea a ese eje solo) — no hace
       falta (ni conviene) reimplementarlo a mano por JS. */
    overscroll-behavior-x: contain; /* al llegar al final del swipe no "pasa" el resto del arrastre horizontal a la página (scroll chaining) */
    overscroll-behavior-y: auto; /* el vertical sí tiene que pasar normal a la página: "contain" en los dos ejes (shorthand) atrapaba el rebote vertical adentro del recuadro de la foto en vez de dejar scrollear */
  }
  .trio-gallery img{
    flex: 0 0 auto;
    width: auto;
    height: 78vw; /* foto grande a propósito: no entran las 3 juntas, hay que deslizar */
    scroll-snap-align: center;
  }
  /* La centro (la ancha/rectangular) es la que se ve primero al entrar
     a la sección; deslizando se llega a las angostas de los costados.
     Solo reordena visualmente (order, dentro del flex de celular): el
     grid de desktop/tablet, que depende del orden real en el HTML
     para que cada foto caiga en su columna angosta/ancha/angosta, no
     se toca. */
  .trio-gallery img:nth-child(2){ order: -1; }
  /* En celular, izquierda y derecha se reemplazan por una sola foto
     pensada para ese formato (.trio-gallery__mobile-photo, ya última
     en el HTML): centro sigue siendo la primera foto y, al deslizar
     hacia la derecha, se llega directo a esta — no a las angostas de
     los costados, que en este formato no se usan. */
  .trio-gallery img:nth-child(1),
  .trio-gallery img:nth-child(3){
    display: none;
  }
  .trio-gallery img.trio-gallery__mobile-photo{
    display: block;
    /* La centro llega de lateral a lateral por sí sola (su ancho:auto
       calculado desde su propia proporción a height:78vw da ~99vw, así
       de casualidad) pero la proporción de esta foto da un poco menos
       — se fuerza el ancho al 100% y se recorta con object-fit:cover
       (heredado de .trio-gallery img de más arriba) para que también
       ocupe la pantalla entera. */
    width: 100%;
  }
}

/* ---------- Galería de 2 fotos cuadradas (Proyección) ----------
   Desktop y tablet: 2 columnas, ambas fotos completas.
   Celular: una foto a pantalla completa (de lado a lado) a la vez;
   se desliza para ver la otra, con scroll-snap. */
.duo-gallery{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--photo-gap);
}
.duo-gallery .thumb{
  aspect-ratio: 1 / 1;
  overflow: hidden;
}
.duo-gallery img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

@media (max-width: 640px){
  .duo-gallery{
    display: flex;
    align-items: flex-start; /* cada diapositiva con su propia altura, no estiradas a la más alta (rompía el cuadrado de .thumb--with-caption) */
    overflow-x: auto;
    overflow-y: hidden; /* explícito, ver comentario igual en .trio-gallery */
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    /* Sin touch-action (ver comentario en .trio-gallery). */
    overscroll-behavior-x: contain; /* al llegar al final del swipe no "pasa" el resto del arrastre horizontal a la página (scroll chaining) */
    overscroll-behavior-y: auto; /* el vertical sí tiene que pasar normal a la página, ver comentario igual en .trio-gallery */
  }
  .duo-gallery .thumb{
    flex: 0 0 100%;
    width: 100%;
    scroll-snap-align: center;
  }
}

/* ---------- Galería con la proporción real de la foto, sin recortar
   a cuadrado (excepción: "Formato Display" de Infinity — fotos
   verticales de una pantalla, recortarlas a 1:1 se veía mal).
   Desktop: cada foto tiene un ancho tope (420px) para no estirarse
   de más en pantallas anchas, dejando espacio negro a los lados y
   entre ellas, como en el mockup. Tablet: al haber menos ancho
   disponible que ese tope, quedan solas pegadas entre sí con el
   mismo --photo-gap mínimo que el resto de las galerías, sin hacer
   falta ningún cambio explícito. Celular: carrusel con swipe, cada
   foto entera sin recortar (mismo loop/puntitos que el resto). ---------- */
.natural-gallery{
  display: grid; /* grid en desktop/tablet, flex solo en celular — así
    el loop de carrusel (que se fija si display es flex) no se activa
    fuera de celular, que es el único formato donde esto es swipe */
  /* ancho tope en vw (no en px fijo): ocupan mucho más pantalla en
     desktop ancho y se van achicando solas a medida que se angosta,
     hasta llegar a tablet, donde ya no entran así de grandes y quedan
     pegadas con el --photo-gap mínimo (ver abajo). min(...,700px)
     nada más para no quedar absurdamente grandes en un monitor
     ultra ancho. */
  grid-template-columns: repeat(2, minmax(0, min(46vw, 860px)));
  justify-content: center;
  gap: var(--margin-x);
}
.natural-gallery__item{
  min-width: 0;
}
.natural-gallery__item img{
  display: block;
  width: 100%;
  height: auto;
}
@media (max-width: 819px){
  .natural-gallery{ gap: var(--photo-gap); }
}
@media (max-width: 640px){
  .natural-gallery{
    display: flex;
    overflow-x: auto;
    overflow-y: hidden; /* explícito, ver comentario igual en .trio-gallery */
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    /* Sin touch-action (ver comentario en .trio-gallery). */
    overscroll-behavior-x: contain; /* al llegar al final del swipe no "pasa" el resto del arrastre horizontal a la página (scroll chaining) */
    overscroll-behavior-y: auto; /* el vertical sí tiene que pasar normal a la página, ver comentario igual en .trio-gallery */
    gap: 0;
    justify-content: flex-start;
  }
  .natural-gallery__item{
    flex: 0 0 100%;
    scroll-snap-align: center;
  }
}

/* ---------- Puntitos indicadores de swipe (mobile) ----------
   Se agregan debajo de cualquier galería con scroll horizontal
   (trio-gallery, duo-gallery) para avisar que hay más fotos
   deslizando. Solo visibles en celular, que es donde esas galerías
   scrollean; en desktop/tablet se ven todas las fotos juntas, sin
   swipe, así que los puntos no hacen falta y quedan ocultos. El JS
   (gallery-dots en main.js) crea los puntos y marca cuál está
   activo según la posición del scroll. */
.gallery-dots{
  display: none;
  justify-content: center;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
}
.gallery-dots span{
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255,255,255,0.35);
  transition: background 0.3s ease;
  flex: 0 0 auto;
}
.gallery-dots span.active{ background: rgba(255,255,255,0.95); }

@media (max-width: 640px){
  .gallery-dots{ display: flex; }
}

/* ---------- Dos columnas con título propio (Hard & Soft /
   Experiencia interactiva).
   Desktop y tablet: 2 columnas lado a lado.
   Celular: apiladas (una debajo de la otra, se ve al scrollear); la
   foto de cada una va de borde a borde, el texto conserva su margen. */
.duo-columns{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--photo-gap);
  /* sin padding lateral: las fotos van de borde a borde, igual que el
     resto de las galerías de la página */
}
.duo-columns__col{
  text-align: center;
  padding-bottom: 150px; /* 100px + 50%: separación hasta las fotos finales, en tablet/desktop */
}
/* En desktop/tablet los dos títulos van lado a lado en columnas
   angostas: si uno entra en 1 renglón ("Hard & Soft") y el otro pide 2
   ("Experiencia interactiva"), la foto de la segunda columna arranca
   más abajo que la primera. Reservando siempre el alto de 2 renglones
   —en em, así escala solo con el tamaño real del título en cada
   ancho— las dos fotos quedan a la misma altura tenga 1 o 2 renglones
   el título de al lado. En celular no hace falta: quedan apiladas, no
   una al lado de la otra. */
@media (min-width: 641px){
  .duo-columns__col .section-subtitle{
    display: flex;
    align-items: flex-end;
    justify-content: center;
    min-height: 2.3em;
  }
}
.duo-columns__col .thumb{
  aspect-ratio: 1 / 1;
  overflow: hidden;
  margin-bottom: 15px; /* 30px - 50%: el texto más cerca de la foto */
}
.duo-columns__col img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.duo-columns__col p{
  max-width: 320px;
  margin: 0 auto 16px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--fg); /* blanco, antes fg-dim */
  font-weight: 300;
}
.duo-columns__col p:last-child{ margin-bottom: 0; }
/* El contenedor ya no tiene padding lateral (las fotos van de borde a
   borde), así que el título y el texto se lo ponen ellos mismos para
   no tocar los bordes de la pantalla. */
.duo-columns__col .section-subtitle,
.duo-columns__col p{
  padding-inline: var(--margin-x);
}
/* Tablet: quedaba con el tamaño de celular (16px) pero el título de al
   lado (.section-subtitle) ya salta a 36px acá — mismo criterio que
   el resto: sube a 20px y gana ancho (menos padding lateral) para no
   quedar tan apretado al centro. */
@media (min-width: 641px) and (max-width: 819px){
  .duo-columns__col p{
    max-width: 500px;
    font-size: 20px;
    padding-inline: 24px;
  }
}
/* Desktop: mismo quiebre que .section-subtitle (820px, no el Punto
   Quiebre Hamburguesa de 1139) — así el texto crece junto con el
   título en vez de quedarse chico hasta último momento. */
@media (min-width: 820px){
  .duo-columns__col p{
    /* crecen gradualmente hasta los 1440px (igual que el título), no
       de golpe a los 820px — si no, quedan gigantes en un desktop
       angosto que todavía no llegó al ancho de referencia */
    max-width: clamp(500px, 32.2061vw + 236.2319px, 700px);
    font-size: clamp(20px, 0.9662vw + 12.087px, 26px);
    padding-inline: 16px; /* menos que var(--margin-x): con el texto más
      grande, hace falta recuperar ancho para no ganar renglones de más */
  }
}

@media (max-width: 640px){
  .duo-columns{
    grid-template-columns: 1fr; /* apiladas */
    gap: 0;
    padding: 0; /* la foto va de borde a borde; el texto se acolchona aparte, ver abajo */
  }
  .duo-columns__col{ padding-bottom: 100px; } /* antes 60px: quedaba más chico que el resto del sitio antes de la línea */
  /* Línea divisoria entre "Hard & Soft" y "Experiencia interactiva"
     al quedar apiladas: mismo estilo y espaciado (90px) que separa
     cualquier otra sección del sitio. */
  .duo-columns__col:nth-child(2){
    border-top: 1px solid transparent;
    border-image: linear-gradient(to right, #000000 0%, rgba(255,255,255,0.7) 50%, #000000 100%) 1;
    padding-top: 90px;
    padding-bottom: 195px; /* 130px + 50%, extra espacio antes de la galería final */
  }
  /* Título persistente: igual que el resto de los títulos del sitio
     (section.grid-section h2), queda pegado debajo de la nav mientras
     se scrollea su sección. */
  .duo-columns__col .section-subtitle{
    position: sticky;
    top: var(--nav-h);
    z-index: 10;
    background: #000000;
    padding: 14px 0;
  }
  .duo-columns__col .section-subtitle,
  .duo-columns__col p{
    padding-inline: var(--margin-x-mob);
  }
  .duo-columns__col p{
    max-width: none; /* antes 320px: quedaba angosto y centrado */
    font-size: 20px; /* igual al resto de los textos de la página en mobile (antes 16px) */
  }
}

/* ---------- Sección sin título (ej: las 4 fotos con leyenda de Omni
   justo después del hero) ----------
   Mismo espacio que separa el final de cualquier sección de su línea
   divisoria (100px), acá arriba, para que no quede pegada a lo que
   viene justo antes (el hero). */
.untitled-section{
  background: #000000;
  padding-top: 100px;
}

/* ---------- Grilla de fotos con leyenda propia, sin título (ej: los
   4 bloques de Omni después del hero, o "App integrada..."). Misma
   geometría que .duo-columns (2 columnas de lado a lado en
   desktop/tablet, apiladas en celular, fotos de borde a borde) pero
   sin h3 y sin línea divisoria al apilarse: cada foto+texto es un
   bloque más, seguido del próximo. ---------- */
.photo-caption-grid{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--photo-gap);
}
.photo-caption-grid__item{
  text-align: center;
  padding-bottom: 100px; /* mismo espacio hasta la línea divisoria que el resto del sitio */
}
/* "App integrada..." es la que queda justo antes de las fotos finales
   (a diferencia de los 4 bloques de después del hero, que siguen con
   Aplicaciones): un 50% más de separación ahí, en tablet/desktop —
   en celular es un carrusel (.swipe-grid) y esa separación la dan los
   puntitos, ver más abajo. */
@media (min-width: 641px){
  #app-integrada .photo-caption-grid__item{
    padding-bottom: 150px; /* 100px + 50% */
  }
}
.photo-caption-grid__item .thumb{
  aspect-ratio: 1 / 1;
  overflow: hidden;
  margin-bottom: 15px; /* 30px - 50%: el texto más cerca de la foto */
}
.photo-caption-grid__item img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.photo-caption-grid__item p{
  max-width: 320px;
  margin: 0 auto;
  font-size: 16px;
  line-height: 1.6;
  color: var(--fg);
  font-weight: 300;
  padding-inline: var(--margin-x);
}
/* Mismos quiebres que .duo-columns__col p: tablet real (641-819) y
   desktop desde 820px (igual que section.grid-section h2), no desde
   el Punto Quiebre Hamburguesa de 1139 — así el texto no se queda
   chico mientras el título de al lado ya creció. */
@media (min-width: 641px) and (max-width: 819px){
  .photo-caption-grid__item p{
    max-width: 500px;
    font-size: 20px;
    padding-inline: 24px;
  }
}
@media (min-width: 820px){
  .photo-caption-grid__item p{
    /* mismo clamp() que .duo-columns__col p: crece gradualmente hasta
       los 1440px en vez de saltar de golpe a los 820px */
    max-width: clamp(500px, 32.2061vw + 236.2319px, 700px);
    font-size: clamp(20px, 0.9662vw + 12.087px, 26px);
    padding-inline: 16px;
  }
}
@media (max-width: 640px){
  .photo-caption-grid{
    grid-template-columns: 1fr;
    gap: 0;
  }
  .photo-caption-grid__item p{
    max-width: none;
    font-size: 20px;
    padding-inline: var(--margin-x-mob);
  }
}
/* Si esta grilla queda dentro de una section.grid-section (título
   persistente/sticky, ver styles.css), el último ítem necesita más
   espacio de sobra antes de que empiece lo que sigue — si no, el
   título todavía no terminó de despegarse cuando ya aparece contenido
   nuevo debajo (mismo caso ya resuelto en Hard & Soft de Trinity). */
@media (max-width: 640px){
  section.grid-section .photo-caption-grid__item:last-child{
    padding-bottom: 130px; /* 100px + 30%, igual que en Trinity */
  }
}

/* ---------- Cierre de página de producto (logo) ----------
   Mismo componente para Trinity/Omni/Infinity/Light Mirage, antes del
   footer: el logo de cada producto (ícono + nombre en un solo archivo,
   PNG con fondo transparente). */
.product-outro{
  background: #000000;
  text-align: center;
  padding: 120px var(--margin-x);
}
/* Omni: 50% más de separación entre la foto de arriba y el logo de
   cierre, pero solo en mobile/tablet (120px -> 180px; desktop no
   cambia). */
@media (max-width: 819px){
  .product-outro--omni{
    padding-top: 180px;
  }
}
.product-outro__mark{
  width: 110px;
  height: auto;
  margin: 0 auto;
  display: block;
}
/* Light Mirage: a diferencia de Trinity/Omni (donde el ícono ocupa
   borde a borde el ancho del PNG), el archivo de este logo es más
   ancho que el ícono porque abajo lleva el nombre del producto en un
   renglón más ancho que el círculo — con los mismos 110px de
   .product-outro__mark de arriba, el ícono en sí renderizaba más
   chico que en las otras ventanas. Se compensa agrandando el ancho
   del contenedor (110px / 0.5942, la proporción real ícono/lienzo
   del archivo) para que el círculo quede al mismo tamaño real que en
   Trinity/Omni. */
.product-outro--light-mirage .product-outro__mark{
  width: 185px;
}
/* Infinity: acá el ícono (el doble loop) sí ocupa el ancho del PNG
   borde a borde como en Trinity/Omni, pero es una forma más ancha
   que alta (proporción real ancho:alto del ícono, sin contar el
   nombre de abajo, 1.53:1 — Trinity/Omni son ~1:1, un cubo y un
   círculo). Con el mismo width:110px de arriba, height:auto lo
   dejaba mucho más bajo que el resto (medido: ~71px de alto real
   contra ~108px en Trinity/Omni) — se veía chico en proporción, no
   por el ancho sino por el alto. Se agranda el contenedor (110px x
   1.53 ≈ 168px) para que el alto real del ícono quede igual al de
   Trinity/Omni. */
.product-outro--infinity .product-outro__mark{
  width: 168px;
}

/* Aplicaciones (Omni y futuras páginas de producto): mismas tarjetas
   que las grillas del Home, pero acá no son link a ningún lado, y en
   celular su título no va en negrita (a diferencia del resto de las
   grillas de tarjetas). */
#aplicaciones .item{ cursor: default; }
#aplicaciones .item .cap h3{ font-weight: 400; }
/* En tablet/desktop quedaba en 20px (tamaño base, sin el +20% que ya
   tienen Desarrollos/Trabajos del Home con esta misma tarjeta) — se
   iguala a esas, mismo tipo de grilla. En celular no cambia. */
@media (min-width: 641px){
  #aplicaciones .item .cap h3{
    font-size: 24px; /* igual a #desarrollos/#trabajos .item .cap h3 */
  }
}

/* .swipe-grid: en celular (nada más — en tablet/desktop se ven todas
   las tarjetas juntas, sin swipe), en vez de apilarse como el resto
   de las grillas del sitio, se convierte en un carrusel con swipe —
   una tarjeta (foto + leyenda) ocupa toda la pantalla, se desliza
   para ver la siguiente (con loop infinito, ver main.js). Sirve tanto
   para .item (Aplicaciones) como para .photo-caption-grid__item
   ("App integrada..."): cualquier hijo directo del carrusel. */
@media (max-width: 640px){
  .swipe-grid{
    display: flex;
    overflow-x: auto;
    overflow-y: hidden; /* explícito, ver comentario igual en .trio-gallery */
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    /* Sin touch-action (ver comentario en .trio-gallery). */
    overscroll-behavior-x: contain; /* al llegar al final del swipe no "pasa" el resto del arrastre horizontal a la página (scroll chaining) */
    overscroll-behavior-y: auto; /* el vertical sí tiene que pasar normal a la página, ver comentario igual en .trio-gallery */
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .swipe-grid::-webkit-scrollbar{ display: none; }
  .swipe-grid > *{
    flex: 0 0 100%;
    width: 100%;
    scroll-snap-align: center;
  }
  /* Los 100px de espacio antes de la línea divisoria (.item .cap o
     .photo-caption-grid__item) tienen sentido cuando las tarjetas
     están todas apiladas a la vista (desktop/tablet); acá, en
     carrusel, solo se ve una tarjeta a la vez y ese espacio quedaría
     antes de los puntitos, no antes de lo que sigue de verdad. El
     espacio hasta los puntitos pasa a ser el mismo que en cualquier
     otro carrusel (los 16px de margin-top de .gallery-dots); el
     espacio hasta la próxima sección se agrega después de los
     puntitos, ver más abajo. */
  .swipe-grid .item .cap,
  .swipe-grid.photo-caption-grid .photo-caption-grid__item,
  .swipe-grid.photo-caption-grid .photo-caption-grid__item:last-child{
    padding-bottom: 0;
  }
  .swipe-grid + .gallery-dots{
    margin-bottom: 84px; /* + 16px de margin-top = 100px, mismo criterio que el resto del sitio */
  }
  /* "App integrada...": mismo orden foto -> puntitos -> texto que
     Light Mirage (ver .synced-captions más abajo) — el texto de cada
     tarjeta se oculta acá (se clona en .synced-captions vía JS) y los
     puntitos dejan de ser lo último antes de la próxima sección,
     así que ya no necesitan el margen extra de abajo; ese respiro
     (150px = 100px + 50%, la misma separación que ya tenía en
     tablet/desktop por quedar justo antes de las fotos finales) pasa
     a ponerlo .synced-captions. */
  #app-integrada .thumb{
    margin-bottom: 0;
  }
  #app-integrada .photo-caption-grid__item p{
    display: none;
  }
  #app-integrada .swipe-grid + .gallery-dots{
    margin-bottom: 0;
  }
  #app-integrada .synced-captions{
    padding-bottom: 150px;
  }
}

/* ---------- Galería final de cierre (2x2, sin texto) ----------
   Mismo criterio de separación que las grillas del Home: un pequeño
   espacio negro entre fotos que se tocan (--photo-gap), acá tanto
   entre columnas como entre filas porque no hay texto que separe. */
.final-gallery-section{
  background: #000000;
  /* sin línea divisoria propia arriba, a propósito */
  padding-bottom: 100px; /* espacio estándar hasta la línea divisoria de Opciones, que ahora la sigue */
}
/* Tampoco la línea que trae el footer por defecto (sí la conserva en
   el resto de las páginas). Usa ~ (no +) porque el lightbox queda
   como hermano en el medio, entre la galería y el footer. */
.final-gallery-section ~ footer.contact{
  border-top: none;
  border-image: none;
}
/* Separación pedida entre la sección Opciones y el video que la
   sigue: el doble del padding-top estándar de .product-video (80px en
   los tres formatos, ver arriba) en cualquier ancho de pantalla, más
   su propia línea divisoria (mismo estilo que .grid-section — este
   video no trae una por defecto). Selector ~ (no +) porque el
   lightbox y la sección Opciones quedan como hermanos en el medio,
   entre la galería final y el video. Afecta nada más a este video (el
   único después de la grilla final), no al de más arriba de la
   página. */
.final-gallery-section ~ .product-video{
  padding-top: 160px;
  border-top: 1px solid transparent;
  border-image: linear-gradient(to right, #000000 0%, rgba(255,255,255,0.7) 50%, #000000 100%) 1;
}
/* Tampoco la línea divisoria antes del footer cuando la página cierra
   con el aro + nombre del producto (.product-outro, ver más abajo). */
.product-outro ~ footer.contact{
  border-top: none;
  border-image: none;
}
#administracion-contenido ~ footer.contact{
  border-top: none;
  border-image: none;
}
#alberto-ferreras ~ footer.contact{
  border-top: none;
  border-image: none;
}
#tendencia-arenales ~ footer.contact{
  border-top: none;
  border-image: none;
}
.final-gallery{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--photo-gap);
}
.final-gallery .thumb{
  aspect-ratio: 1 / 1;
  overflow: hidden;
}
@media (max-width: 819px){
  .final-gallery{ gap: calc(var(--photo-gap) * 0.6); } /* tablet y celular: misma separación que la grilla de Referencias de Omni (6px -> 3.6px), pedido explícito del cliente */
}
.final-gallery img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* siempre a su brillo/opacidad original: no es un link a otra
     página (abre el lightbox en la misma), así que no lleva el efecto
     de subir opacidad/brillo al tocar — ver .item para dónde sí va. */
}
/* ---------- Lightbox genérico: cualquier galería marcada con
   [data-lightbox] se abre en grande al tocar una foto (ver js/main.js
   para qué formato responde cada valor: "always" o "tablet"). Cursor
   en forma de mano como pista, nada más donde de verdad responde al
   toque en este ancho — "always" en cualquier formato, "tablet" solo
   ahí (en celular esas galerías ya son swipe en la propia página, en
   desktop se ven todas las fotos juntas). */
[data-lightbox="always"] img{ cursor: pointer; }
@media (min-width: 641px) and (max-width: 819px){
  [data-lightbox="tablet"] img{ cursor: pointer; }
}

/* ---------- Lightbox: foto en grande, con swipe entre las demás de
   la misma galería ----------
   Se abre al tocar/cliquear cualquier foto de una galería marcada con
   [data-lightbox]. Adentro, la foto tocada queda centrada y se puede
   deslizar (swipe) para ver las demás de esa galería, con los mismos
   puntitos que el resto del sitio (ver .gallery-dots) — acá siempre
   visibles, sea cual sea el tamaño de
   pantalla, a diferencia de las otras galerías que solo los muestran
   en celular. */
.lightbox{
  position: fixed;
  inset: 0;
  background: #000000;
  z-index: 200;
  display: flex;
  flex-direction: column;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}
.lightbox.open{
  opacity: 1;
  pointer-events: auto;
}
.lightbox__close{
  position: absolute;
  top: 20px;
  right: 20px;
  width: 40px;
  height: 40px;
  background: none;
  border: none;
  color: var(--fg);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  z-index: 3; /* por encima de .lightbox__zones (z-index:2): con el mismo valor, la zona derecha (que viene después en el HTML) le tapaba el toque a la cruz en esa esquina */
}
.lightbox__stage{
  position: relative;
}
.lightbox__track{
  display: flex;
  align-items: center;
  width: 100%;
  height: 80vh;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-x; /* restringe el movimiento a horizontal, ninguna galería con swipe se mueve en vertical */
  overscroll-behavior: contain; /* al llegar al final del swipe no "pasa" el resto del arrastre a la página (scroll chaining), que se sentía como movimiento vertical residual */
}
/* Navegación por clic (desktop, sin touch): dos zonas invisibles,
   mitad izquierda/derecha, mismo criterio que .hero-zones del Home. En
   celular y tablet no estorban: el swipe con el dedo sigue andando
   igual, un tap ahí solo avanza/retrocede una foto además. */
.lightbox__zones{
  position: absolute;
  inset: 0;
  display: flex;
  z-index: 2;
}
.lightbox__zone{
  flex: 1;
  background: transparent;
  border: none;
  cursor: pointer;
}
/* En celular y tablet (pantallas táctiles), este contenedor queda
   tapando el track por encima (para que los botones puedan recibir
   el toque) pero al ser hermano del track (no hijo), un arrastre que
   arranca sobre él nunca llega a considerarse swipe del track de
   abajo — solo el tap (que sí burbujea como click) funcionaba, no el
   deslizamiento clásico. Con pointer-events:none acá (en el
   contenedor: un botón hijo con pointer-events:none no alcanza, el
   div que lo envuelve sigue interceptando igual), el toque pasa
   directo al track: el arrastre nativo empieza a funcionar, y el
   avance por toque lo toma setupTapToAdvance() puesto directo sobre
   el track (ver JS) en su lugar. Hasta 819px (celular + tablet):
   pedido explícito de que todo el swipe de tablet también se pueda
   hacer con el dedo, no solo con el toque tipo historias. En desktop
   este contenedor sigue exactamente igual (ahí no hay dedo que
   tapar). */
@media (max-width: 819px){
  .lightbox__zones{
    pointer-events: none;
  }
}
.lightbox__item{
  flex: 0 0 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  scroll-snap-align: center;
  touch-action: pan-x; /* también en la foto (el toque empieza ahí, no en el contenedor) */
  /* sin padding lateral: la foto va de lado a lado de la pantalla */
}
.lightbox__item img{
  display: block;
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain; /* la foto entera, sin recortar */
}
.lightbox .gallery-dots{
  display: flex; /* siempre visibles acá (a diferencia del resto, que solo se ven en celular) */
  margin: 20px 0 0;
}

/* ---------- Lightbox más grande (desktop) ----------
   Pedido explícito para la galería final de Trinity (la única con
   data-lightbox="always" hoy — main.js le suma esta clase al abrir):
   en desktop, la foto ocupa más pantalla que el resto de las galerías
   (.lightbox__track en 80vh) pero sigue viéndose ENTERA, sin
   recortar — el alto pasa a 100vh, object-fit se mantiene en contain
   (heredado del estilo base). No es "pantalla completa" literal: si
   la proporción de la foto no es exactamente la de la pantalla,
   sigue quedando algo de espacio vacío a los costados o arriba/abajo,
   pero mucho menos que antes de este cambio. Los puntitos, que ya no
   entran como contenido aparte debajo de la foto, quedan flotando
   encima, cerca del borde inferior. Solo desktop: en el resto de los
   formatos esta galería sigue igual que siempre (80vh). */
@media (min-width: 820px){
  .lightbox--fill .lightbox__track{
    height: 100vh;
  }
  .lightbox--fill .gallery-dots{
    position: absolute;
    left: 0;
    right: 0;
    bottom: 32px;
    margin: 0;
    z-index: 2;
  }
}

/* ============================================
   Desarrollos a Medida
   ============================================ */

/* ---------- Hero (mismo bloque de foto que .product-hero, pero el
   título va arriba en vez de una bajada abajo — esta página no es un
   producto con nombre propio en la foto, así que hace falta un h1
   real). El degradé vive en su propio elemento (nunca junto al fade),
   arriba en vez de abajo, para que el título blanco se lea sobre
   cualquier zona clara de la foto. ---------- */
.dev-hero{
  background: #000000;
}
.dev-hero .hero > img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.dev-hero__scrim{
  position: absolute;
  left: 0; right: 0; top: 0;
  padding: 40px var(--margin-x) 60px;
  background: linear-gradient(to bottom, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0) 100%);
  text-align: center;
}
.dev-hero__title{
  margin: 0;
  color: var(--fg);
  font-family: 'Archivo', var(--font-display);
  font-stretch: 125%;
  font-variation-settings: "wdth" 125;
  font-weight: 400;
  font-size: 50px; /* antes 58px (29px x2) */
  letter-spacing: 0.012em;
}
/* Desarrollos a Medida (solo versión en inglés): "Custom Projects" es
   más corto que "Desarrollos a Medida", así que a diferencia del
   español (donde ese título no entra en 1 renglón ni achicando
   bastante la letra, y el corte a 2 renglones en tablet de acá abajo
   es el diseño buscado, no un bug) acá alcanza con ajustar tamaño y
   ancho para que entre siempre en 1 renglón.
   OJO al medir esto: la fuente real (Archivo, font-stretch:125%) no
   carga en este entorno de pruebas (Google Fonts bloqueado), así que
   medir con la fuente de reemplazo del navegador da anchos muy por
   debajo de los reales — la primera vez que se ajustó este bloque
   quedó mal calculado por eso (41px, insuficiente). Vuelto a medir
   bajando el archivo real de Archivo aparte para probarlo. */
@media (max-width: 640px){
  .dev-hero__title--oneline{
    /* Lo más grande posible en cada ancho, siempre en 1 renglón —
       fluido en vez de un tamaño fijo (pedido explícito): crece con
       el ancho real de pantalla, tope en 54px (mismo tamaño con el
       que arranca el h1 en tablet, así no da un salto raro al cruzar
       los 640px). Por debajo de los ~337px de ancho real ya no entra
       en 1 renglón ni al piso de 30px — caso límite, celulares muy
       angostos que casi no existen hoy. */
    font-size: clamp(30px, 10.2vw - 5px, 54px);
    /* +20px de separación con el header, pedido explícito — solo
       acá (mobile, inglés): el padding-top del contenedor
       (.dev-hero__scrim) es compartido con tablet/desktop y con la
       versión en español, así que se baja con margin-top en el
       título en vez de tocar ese padding. */
    margin-top: 20px;
  }
}
@media (min-width: 641px) and (max-width: 819px){
  /* 50% más grande que el h2 de sección en tablet (36px x1.5 = 54px).
     A ese tamaño el texto entra en un renglón si se lo deja libre, así
     que se limita el ancho a propósito para que se parta en 2 — es la
     forma de lograr el tamaño pedido sin ensanchar de más el bloque. */
  .dev-hero__title{
    font-size: 54px;
    max-width: 460px;
    margin: 0 auto;
  }
  /* "Custom Projects" a 54px (con la fuente real) mide ~520px, más
     ancho que los 460px de arriba (pensados para forzar el corte a 2
     renglones en español) pero bien por debajo del ancho real
     disponible en cualquier ancho de tablet (561px como mínimo, a
     los 641px) — con quitarle el max-width alcanza, sin tocar el
     tamaño de letra. */
  .dev-hero__title--oneline{
    max-width: none;
  }
}
@media (min-width: 820px){
  .dev-hero__title{
    /* Arranca en 54px a los 820px (mismo tamaño que en tablet, para
       que no haya un salto brusco al cruzar el breakpoint) y sube
       rápido con el ancho real de pantalla hasta el doble (93.6px) a
       los 1440px — siempre por encima del h2 de sección en cualquier
       ancho intermedio. */
    font-size: clamp(54px, 6.3871vw + 1.626px, 93.6px);
  }
}

/* ---------- Línea de tags cortos debajo del h2 (ej: "LED · Mapping ·
   Display · Ingeniería óptica · Montaje") ---------- */
.section-tags{
  max-width: 1200px; /* bien ancho: en un renglón siempre que el formato lo permita */
  margin: -26.08px auto 20px; /* separación al h2 -20% extra en mobile (22.4px -> 17.9px); separación a la foto -50% (antes 40px) */
  padding: 0 var(--margin-x);
  text-align: center;
  font-size: 20px; /* mismo tamaño que .section-caption p (resto de las ventanas) */
  line-height: 1.6;
  color: var(--fg);
  font-weight: 300;
}
@media (min-width: 641px){
  .section-tags{ margin-top: -30.4px; } /* separación al h2 -30% extra sobre el -20% anterior (48px -> 33.6px en tablet/desktop) */
}
@media (min-width: 1139px){
  .section-tags{ font-size: 26px; } /* mismo quiebre y tamaño que .section-caption p */
}

/* ---------- Frase corta debajo del h2, antes de la grilla de fotos
   (ej: "Desarrollo de visuales creadas específicamente para cada
   instalación.") ---------- */
.section-intro{
  max-width: 1200px; /* bien ancho: en un renglón siempre que el formato lo permita */
  margin: -26.08px auto 20px; /* mismo criterio que .section-tags, ver arriba */
  padding: 0 var(--margin-x);
  text-align: center;
  font-size: 20px; /* mismo tamaño que .section-caption p (resto de las ventanas) */
  line-height: 1.6;
  color: var(--fg);
  font-weight: 300;
}
@media (min-width: 641px){
  .section-intro{ margin-top: -30.4px; } /* mismo criterio que .section-tags, ver arriba */
}
@media (min-width: 1139px){
  .section-intro{ font-size: 26px; } /* mismo quiebre y tamaño que .section-caption p */
}

/* ---------- Trabajos: "Gewin / Edificio ICONNECT" — el texto debajo
   del título en un solo renglón mientras el ancho de pantalla lo
   permita, centrado respecto a la grilla de fotos (pedido explícito,
   solo para este texto puntual, no para el resto de .section-intro
   del sitio). Medido en vivo: el texto sin cortar (26px) necesita
   1179.2px de ancho propio; sumado al padding de 64px de cada lado
   (var(--margin-x) en desktop), hace falta un ancho real de pantalla
   de ~1307px para que entre; 1320px deja un margen chico de sobra
   (re-medido tras un cambio de texto — si se vuelve a editar este
   texto, volver a medir el ancho real antes de tocar el breakpoint).
   Por debajo de eso, sigue en 2 renglones como el resto de las
   leyendas .section-intro. width:fit-content además de quitar el
   max-width: así la caja mide justo el ancho del texto y el
   margin:auto de arriba la centra respecto a la grilla, en vez de
   ocupar todo el ancho disponible. */
@media (min-width: 1320px){
  #gewin-iconnect .section-intro{
    white-space: nowrap;
    max-width: none;
    width: fit-content;
  }
}

/* ---------- Bloque de texto + fotos (Administración Remota /
   Administración Local): título, texto y galería, todo centrado, uno
   debajo del otro (no en columnas lado a lado). ---------- */
.admin-block{
  text-align: center;
}
/* Separación entre el final de las fotos de Remota (con su "Imágenes
   de referencia") y el título de Local: 190px -> 133px (-30%). El
   .grid-note de arriba ya trae 100px propios hasta acá, así que el
   resto lo pone este padding-top (33px = 133 - 100). */
.admin-block + .admin-block{
  padding-top: 13.5px; /* separación total (fotos -> siguiente título) -30%: 255px -> 178.5px */
}
/* Subtítulos (Administración Remota/Local): tamaños fijos pedidos por
   el cliente (22px en mobile, 24px en tablet, 30px en desktop). */
.admin-block .section-subtitle{
  margin: 0 0 20px;
  font-size: 20px;
}
@media (min-width: 641px) and (max-width: 819px){
  .admin-block .section-subtitle{ font-size: 24px; }
}
@media (min-width: 820px){
  .admin-block .section-subtitle{ font-size: 30px; }
}
/* Separación entre el h2 de sección y "Administración Remota" (el
   primer subtítulo): +20%. Va en padding-top del bloque (no en
   margin-top del h3) porque un margin-top ahí colapsaría con el
   margin-bottom del h2 (se queda con el mayor de los dos, no los
   suma) — el padding no colapsa, así que sí se nota. El segundo
   subtítulo ("Administración Local") no se toca acá — su separación
   con lo de arriba ya se ajustó aparte (ver .admin-block + .admin-block). */
.admin-block:first-of-type{
  padding-top: 8.8px; /* mobile: 44px + 8.8px = 52.8px (+20%) */
}
@media (min-width: 641px){
  .admin-block:first-of-type{
    padding-top: 12.8px; /* tablet/desktop: 64px + 12.8px = 76.8px (+20%) */
  }
}
.admin-block__text{
  max-width: 1480px; /* bien ancho: en un renglón siempre que el formato lo permita */
  margin: 0 auto 20px; /* misma separación hasta la foto que en las demás secciones (.section-intro) */
  padding: 0 var(--margin-x);
  font-size: 20px; /* mismo tamaño que el resto de los textos (.section-caption p) */
  line-height: 1.6;
  color: var(--fg);
  font-weight: 300;
}
@media (min-width: 1139px){
  .admin-block__text{ font-size: 26px; }
}

/* ---------- Leyenda chica debajo de cada grilla de 4 fotos: a la
   izquierda el pie de foto del proyecto (opcional), a la derecha
   siempre "- Imágenes de referencia -". Mismo espacio hasta la línea
   divisoria (100px) que el resto de las leyendas de la página. ---------- */
/* Grid de 2 columnas — mismas columnas que .duo-gallery de arriba —
   para que el pie de foto quede confinado al ancho real de la foto
   izquierda en vez de estirarse como texto libre y invadir el espacio
   de la foto derecha. */
/* Sin padding lateral propio en el contenedor: va de borde a borde
   igual que la galería de arriba. El inset lateral lo pone cada
   párrafo — .grid-note__caption con el mismo var(--margin-x) que el
   resto de los textos de la sección (.section-intro, .admin-block__text);
   .grid-note__ref con un inset fijo propio, más chico, ver abajo. */
.grid-note{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--photo-gap);
  align-items: flex-start; /* "- Imágenes de referencia -" pegado arriba, cerca de la foto, no al piso de la fila — importa nada más cuando comparte fila con un pie de foto más alto (grid-note__caption, ver Creación de Instalaciones); en el resto de las secciones (un solo renglón) no cambia nada */
  margin-top: 11.5px; /* 23px - 50%: la fecha/texto de referencia va más cerca de la foto que el resto de los textos debajo de imagen (Trinity/Omni) */
  padding: 0 0 100px;
}
.grid-note p{
  margin: 0;
  line-height: 1.6;
  color: var(--fg); /* blanco, antes gris tenue */
  font-weight: 300;
}
.grid-note p.grid-note__ref{
  color: rgba(255,255,255,0.7); /* gris 70%, en todos los formatos */
}
.grid-note__caption{
  grid-column: 1;
  text-align: left;
  padding: 0 var(--margin-x); /* mismo espaciado izquierda/derecha que el resto de los textos de la sección (.section-intro, .admin-block__text) */
  font-size: 20px; /* mismo tamaño que el resto de los textos (.section-caption p) */
}
.grid-note__ref{
  grid-column: 2;
  justify-self: end;
  text-align: right;
  padding-right: 22px; /* mismo inset que .item .cap, del lado derecho */
  font-style: italic;
  white-space: nowrap;
  font-size: 15px; /* mitad del tamaño del resto de los textos, +50% (10px -> 15px) */
}
@media (min-width: 1139px){
  .grid-note__caption{ font-size: 26px; }
  .grid-note__ref{ font-size: 19.5px; } /* 13px + 50% */
}
/* Desktop: espaciado izquierdo más chico (pedido explícito, valor
   exacto dado por el cliente: 34px en vez de los 64px de
   var(--margin-x) que usa el resto de los textos de la sección). El
   padding derecho no se toca. */
@media (min-width: 820px){
  .grid-note__caption{ padding-left: 34px; }
}
@media (max-width: 640px){
  .grid-note{
    grid-template-columns: 1fr;
    align-items: flex-start;
    gap: 8px;
    padding: 0 0 100px; /* acá sí es lo último antes de la línea divisoria: los puntitos van arriba, igual que en Trinity/Infinity */
  }
  .grid-note__ref{
    grid-column: 1;
    grid-row: 1; /* misma fila que grid-note__caption cuando existe (ver abajo): se superponen en vez de apilarse, así "- Imágenes de referencia -" queda pegado arriba (cerca de la foto) y no empujado por el pie de foto más alto — en las secciones sin caption no cambia nada, es la única fila igual */
    justify-self: end;
    text-align: right;
    padding-left: 0;
    padding-right: 22px;
  }
  /* Fecha (Trabajos/Exhibiciones): alineada con el centro de los
     puntitos del swipe, no contra el borde derecho. */
  .work-item .grid-note__ref{
    justify-self: center;
    text-align: center;
    padding-right: 0;
  }
  /* Mientras se desliza entre las 4 fotos, el pie de foto del proyecto
     propio (Mirabilia) solo tiene sentido cuando esa foto puntual está
     en pantalla — el resto del tiempo (fotos de referencia) no debe
     verse, y en su lugar corresponde "- Imágenes de referencia -" de
     acá abajo. Oculto por defecto (visibility, no display) para que el
     alto del bloque no cambie y la línea divisoria de abajo no salte
     de lugar al pasar de una foto a otra. JS (main.js) le suma esta
     clase según el índice activo — mismo mecanismo que
     .grid-note__ref.is-own-photo, pero invertido. Comparte fila con
     .grid-note__ref (grid-row:1 en ambos) en vez de ir debajo: así
     "- Imágenes de referencia -" no queda empujado hacia abajo por el
     alto reservado del pie de foto (3 renglones) mientras está oculto. */
  .grid-note__caption{
    grid-column: 1;
    grid-row: 1;
    /* padding: heredado de la regla de arriba (0 var(--margin-x)),
       mismo espaciado izquierda/derecha que el resto de los textos. */
    visibility: hidden;
  }
  .grid-note__caption.is-own-photo{ visibility: visible; }
  .grid-note__ref.is-own-photo{ visibility: hidden; }
}

/* ---------- Foto con pie propio dentro de una .duo-gallery (ej: la
   3ra foto de "Creación de Instalaciones", la única con proyecto
   identificado). El pie queda oculto por el propio overflow:hidden
   del cuadrado en todos los formatos — la versión visible es siempre
   la de .grid-note__caption más abajo, fija debajo de los puntitos.
   En celular esa versión solo se muestra mientras esta foto puntual
   está en pantalla durante el swipe (ver .grid-note__caption.is-own-photo
   más arriba); en desktop/tablet, sin swipe, queda siempre visible. ---------- */
.thumb--with-caption .thumb__photo{
  width: 100%;
  height: 100%;
}
.thumb__caption{
  margin: 0;
  padding: 0;
  font-size: 20px;
  line-height: 1.6;
  color: var(--fg);
  font-weight: 300;
}
@media (min-width: 1139px){
  .thumb__caption{ font-size: 26px; }
}
@media (max-width: 640px){
  /* El pie de foto ya no va adentro de la foto en celular — vuelve a
     mostrarse en .grid-note__caption, fijo debajo de los puntitos,
     igual que el resto de los textos del sitio (así el alto de la
     sección no cambia según qué foto esté activa, y la línea
     divisoria de abajo no salta de lugar al hacer swipe). */
  .thumb__caption{ display: none; }
}

/* ============================================
   Trabajos
   ============================================ */

/* ---------- Encabezado de la página: "TRABAJOS" chico, centrado, con
   una línea corta a cada lado — mismo degradé que las líneas
   divisorias del sitio, pero empezando en blanco puro pegada al texto
   y apagándose a negro hacia afuera (no simétrica como la divisoria
   de sección). No hay foto de hero acá, ni línea divisoria: es lo
   primero de la página. ---------- */
.work-header{
  background: #000000;
  padding: 50px 0 0; /* mobile/tablet: -50% (100px -> 50px) */
  text-align: center;
}
@media (min-width: 820px){
  .work-header{
    padding-top: 40px; /* desktop: -50% extra sobre el 80px de arriba (80px -> 40px) */
  }
}
@media (max-width: 819px){
  .work-header{
    padding-top: 12.5px; /* mobile y tablet: -50% extra sobre el 25px de arriba (25px -> 12.5px) */
  }
}
.work-header__eyebrow{
  /* display:flex (no inline-flex) + width:100%: con inline-flex, si
     el conjunto línea+texto+línea llegaba a medir más que el ancho
     real de pantalla (pasó al agrandar las líneas un 50%, sobre todo
     con textos más largos como "EXHIBITIONS"), text-align:center del
     padre (heredado, ver .work-header) no lo podía centrar — el
     navegador lo dejaba pegado contra el borde izquierdo en vez de
     centrarlo aunque se pasara de ancho. Con flex + width:100% el
     centrado (justify-content:center) es real independientemente de
     si el contenido entra o no en el ancho disponible. */
  display: flex;
  width: 100%;
  box-sizing: border-box;
  align-items: baseline; /* las líneas arrancan desde la base del texto, no desde el centro */
  justify-content: center;
  gap: 16px;
  padding: 0 var(--margin-x);
}
.work-header__eyebrow::before,
.work-header__eyebrow::after{
  content: '';
  /* Mobile/tablet: tope en 360px (240px + 50%, pedido explícito),
     ya escala con el viewport para no desbordar. */
  width: min(360px, 27vw);
  height: 1.5px; /* 1px + 50% */
}
@media (min-width: 820px){
  .work-header__eyebrow::before,
  .work-header__eyebrow::after{
    width: min(720px, 43.5vw); /* 360px x2 (mismo x2 de siempre), solo en desktop */
  }
}
.work-header__eyebrow::before{
  background: linear-gradient(to left, rgba(255,255,255,0.7) 0%, #000000 100%);
}
.work-header__eyebrow::after{
  background: linear-gradient(to right, rgba(255,255,255,0.7) 0%, #000000 100%);
}
.work-header__eyebrow span{
  /* Mismas proporciones que section.grid-section h2 (36/46.8 entre
     tablet y desktop, 29/36 entre mobile y tablet), reescaladas para
     que el valor de desktop bien ancho (1440px) dé 30px — así se
     achica al angostar la pantalla igual que el resto de los
     títulos, en vez de quedar fijo en un solo tamaño. */
  font-size: 18.6px;
  letter-spacing: 0.3em;
  color: var(--fg); /* blanco */
  font-weight: 300;
  white-space: nowrap;
}
@media (min-width: 641px) and (max-width: 819px){
  .work-header__eyebrow span{ font-size: 23.08px; }
}
@media (min-width: 820px){
  .work-header__eyebrow span{
    font-size: clamp(23.08px, 1.1161vw + 13.928px, 30px);
  }
}
/* Sin línea divisoria entre el encabezado y el primer trabajo. */
.work-header + .work-item{
  border-top: none;
  border-image: none;
}
@media (max-width: 819px){
  .work-header + .work-item{
    padding-top: 45px; /* mobile y tablet: -50% sobre el padding-top de sección (90px -> 45px) */
  }
}
@media (max-width: 640px){
  .work-header + .work-item{
    padding-top: 26.7px; /* mobile: -30% extra sobre el 45px de arriba (gap visual 61px -> 42.7px) */
  }
}

/* ---------- Cada trabajo: título (mismo h2 que el resto del sitio,
   con su línea divisoria de sección) + descripción + galería + fecha.
   La descripción reutiliza .section-intro (mismo tamaño/separación
   que las demás ventanas) y la fecha reutiliza .grid-note (misma
   posición/estilo que "- Imágenes de referencia -"). La cantidad de
   fotos varía según el trabajo (.duo-gallery ya arma 2x2 sola si son
   4, o 2 columnas si son 2). ---------- */

/* ============================================
   Bio
   ============================================ */

/* ---------- Primera sección de la página (Biografía): no hay hero
   antes, la nav queda justo arriba — sin línea divisoria, para no
   pintar un renglón pegado al borde de la barra. Selector con el
   mismo "section.grid-section" del que hereda, si no la especificidad
   empata con la regla base y esta nunca gana (bug real: quedaba
   visible igual). También acerca el título a la nav, con el mismo
   criterio de separación que usa .work-header (Trabajos, la otra
   página sin hero) en vez del padding-top de sección estándar (90px,
   pensado para cuando arriba hay una línea divisoria de verdad). ---------- */
section.grid-section--no-divider{
  border-top: none;
  border-image: none;
  padding-top: 12.5px;
}
@media (min-width: 820px){
  section.grid-section--no-divider{ padding-top: 40px; }
}

/* ---------- Bloque de dos mitades: una mitad el texto, la otra la
   foto a borde de pantalla (sin recorte de página) — ambas alineadas
   arriba. Por defecto el texto va a la izquierda y la foto a la
   derecha (Biografía, Prensa); .split-section--reverse invierte el
   orden (Statement). El texto usa el mismo tamaño/quiebre que el
   resto de las ventanas (.section-intro, .admin-block__text): 20px
   hasta 1138px, 26px desde 1139px, justificado — y el mismo margen
   lateral (var(--margin-x)) del lado de afuera; del lado de la foto
   no lleva padding propio, el --photo-gap del grid ya separa lo
   justo. Debajo de los 820px (tablet y celular, mismo ancho real para
   bordear texto y foto) se apilan, una arriba de la otra: por defecto
   el texto primero (Statement, Prensa); .split-section--mobile-photo-first
   arranca con la foto (Biografía). Obra Trinity no usa este
   componente — ver .trinity-text más abajo, que bordea la foto con
   texto en flujo (float) en vez de columnas fijas. */
.split-section{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-template-areas: "text photo";
  align-items: start;
  gap: var(--photo-gap);
  padding-bottom: 100px; /* mismo espacio hasta la línea divisoria que el resto del sitio */
}
.split-section--reverse{
  grid-template-areas: "photo text";
}
.split-section__text{
  grid-area: text;
  padding-left: var(--margin-x);
}
.split-section--reverse .split-section__text{
  /* Mismo margen de los dos lados: separación del borde de pantalla
     (derecha) y separación de la foto (izquierda), ambas var(--margin-x). */
  padding-left: var(--margin-x);
  padding-right: var(--margin-x);
}
.split-section__text p,
.trinity-text p{
  margin: 0 0 20px;
  font-size: 20px;
  line-height: 1.6;
  color: var(--fg);
  font-weight: 300;
  text-align: justify;
}
.split-section__text p:last-child,
.trinity-text p:last-child{ margin-bottom: 0; }
@media (min-width: 1139px){
  .split-section__text p,
  .trinity-text p{ font-size: 26px; }
}
.split-section__photo{
  grid-area: photo;
  aspect-ratio: 1 / 1;
  overflow: hidden;
}
.split-section__photo img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
@media (max-width: 819px){
  .split-section{
    grid-template-columns: 1fr;
    grid-template-areas: "text" "photo";
    gap: 40px;
  }
  .split-section--mobile-photo-first{
    grid-template-areas: "photo" "text";
  }
  /* En celular y tablet ya no comparte renglón con la foto: el margen
     lateral va completo a los dos lados (antes solo del lado de
     afuera). */
  .split-section__text,
  .split-section--reverse .split-section__text{
    padding-left: var(--margin-x);
    padding-right: var(--margin-x);
  }
}

/* ---------- Biografía: etiqueta corta (el título de cada hito) más
   pegada al párrafo con la fecha que le sigue, que a la etiqueta
   anterior — mismo tamaño que el resto del texto, solo con más peso. ---------- */
.split-section__text p.bio-entry__label{
  font-weight: 500;
  margin-bottom: 4px;
}

/* ---------- Statement: cita completa en itálica. ---------- */
.split-section__text--quote p{
  font-style: italic;
}

/* ---------- Obra Trinity: todo el cuerpo de texto es un único flujo
   (no una porción fija al lado de la foto + el resto abajo): en
   desktop la foto flota a la derecha (float, a borde de pantalla) y
   el texto la bordea por la izquierda mientras dura su alto; en
   cuanto el texto pasa el final de la foto, sigue solo, ya expandido
   de lado a lado de la pantalla — es el comportamiento nativo de un
   float, no hace falta partir el texto "a mano" en dos bloques. Cada
   párrafo lleva su propio margen lateral (mismo var(--margin-x) que
   el resto de los textos); el contenedor no tiene padding propio para
   que la foto llegue al borde real. ---------- */
.trinity-text{
  padding-bottom: 100px; /* mismo espacio hasta la línea divisoria que el resto del sitio */
}
.trinity-text p{
  padding: 0 var(--margin-x);
}
.trinity-text .signature{
  margin-top: 20px;
  padding-top: 20px;
  color: rgba(255,255,255,0.7); /* mismo gris atenuado que .grid-note__ref */
  text-align: left; /* nombre/rol/fecha en 3 renglones cortos (<br>): justificarlos los estiraría de forma rara */
}
/* Desktop/tablet ancho (>819px): foto flotante a la derecha, a borde
   de pantalla — el texto (todos los párrafos, en su orden real del
   HTML) la bordea por la izquierda mientras dura su alto, y sigue de
   lado a lado en cuanto la supera. */
@media (min-width: 820px){
  .trinity-text__photo{
    float: right;
    width: calc(50% - var(--photo-gap) / 2);
    aspect-ratio: 1 / 1;
    overflow: hidden;
    margin-bottom: 20px;
  }
  .trinity-text__photo img{
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }
}
/* Tablet angosta y celular (≤819px): no hay ancho real para bordear
   una foto con texto, así que se apila — orden fijo pedido por el
   cliente: los primeros 2 párrafos, la foto entera de borde a borde,
   y recién ahí el resto del texto. Se logra con flex + order (en vez
   de mover el HTML) para no duplicar el mismo comportamiento con
   dos órdenes de DOM distintos según el ancho. */
@media (max-width: 819px){
  .trinity-text{
    display: flex;
    flex-direction: column;
  }
  .trinity-text p:nth-of-type(1){ order: -2; }
  .trinity-text p:nth-of-type(2){ order: -1; }
  .trinity-text__photo{
    order: 0;
    aspect-ratio: 1 / 1;
    overflow: hidden;
    margin-bottom: 20px;
  }
  .trinity-text__photo img{
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }
}
/* Subtítulo tipo "Church y Trinity, un viaje introspectivo": mismo
   componente que Hard&Soft (.section-subtitle) pero alineado a la
   izquierda, con el margen lateral propio (en vez de centrado dentro
   de una columna angosta), y en el tamaño chico de subtítulo
   (.admin-block .section-subtitle, ej: "Administración Remota" en
   Desarrollos a Medida) en vez del tamaño grande que comparte
   proporción con el h2. */
.section-subtitle--left{
  text-align: left;
  padding: 0 var(--margin-x);
  margin: 0 0 40px;
  font-size: 20px; /* igual a .admin-block .section-subtitle en mobile */
}
@media (min-width: 641px) and (max-width: 819px){
  .section-subtitle--left{ font-size: 24px; }
}
@media (min-width: 820px){
  .section-subtitle--left{ font-size: 30px; }
}
/* Bio: "Church y Trinity, / un viaje introspectivo" (ES) / "Church
   and Trinity, / an Introspective Journey" (EN) en 2 renglones fijos
   en tablet y celular — pedido explícito. En desktop sigue corrido
   como texto normal (sin el corte). */
.trinity-subtitle-break{
  display: none;
}
@media (max-width: 819px){
  .trinity-subtitle-break{
    display: inline;
  }
}

/* ---------- Prensa: subtítulo "La Nación" (celular: mismo tamaño que
   .section-subtitle--left "Church y Trinity...", +5px; tablet/desktop:
   +6px que .admin-block .section-subtitle, +5px), "por Leila Sobol"
   en el tamaño de ese mismo subtítulo sin ningún extra, la cita en
   itálica al tamaño estándar del resto de los textos, y el link
   alineado al piso de la foto (columna estirada a su altura completa,
   ver .split-section--press). ---------- */
.press-title{
  font-family: 'Archivo', var(--font-display);
  font-stretch: 125%;
  font-variation-settings: "wdth" 125;
  font-weight: 400;
  margin: 0 0 8px;
  font-size: 25px; /* 20px (celular, igual a .section-subtitle--left) + 5px */
}
@media (min-width: 641px) and (max-width: 819px){
  .press-title{ font-size: 35px; } /* 24px + 6px + 5px */
}
@media (min-width: 820px){
  .press-title{ font-size: 41px; } /* 30px + 6px + 5px */
}
.press-byline{
  font-size: 20px; /* igual a .admin-block .section-subtitle, sin el +6px del título */
}
@media (min-width: 641px) and (max-width: 819px){
  .press-byline{ font-size: 24px; }
}
@media (min-width: 820px){
  .press-byline{ font-size: 30px; }
}
.press-quote{
  font-style: italic;
}
.press-link{
  display: inline-block;
  margin-top: auto; /* empuja el link al piso de la columna estirada */
  padding-top: 20px;
  font-size: 20px; /* mismo tamaño que el resto de los textos (.split-section__text p) */
  color: var(--fg);
  text-decoration: underline;
  text-underline-offset: 3px;
}
@media (min-width: 1139px){
  .press-link{ font-size: 26px; }
}
/* La columna de texto se estira a la altura completa de la fila (foto
   incluida) para que el link pueda ir al piso — el resto de las
   secciones (Biografía, Statement, Obra Trinity) no lo necesitan: ahí
   texto y foto se alinean arriba nada más, sin nada que anclar abajo. */
.split-section--press{
  align-items: stretch;
}
.split-section--press .split-section__text{
  display: flex;
  flex-direction: column;
  /* Mismo margen de los dos lados: separación del borde de pantalla
     (izquierda) y separación de la foto (derecha), ambas
     var(--margin-x) — mismo criterio que Statement. */
  padding-right: var(--margin-x);
}

/* ============================================
   Textos justificados (pedido explícito, por página)
   ============================================ */
/* Omni: texto de cada una de las 4 fotos debajo del hero (sin título
   de sección, ver .untitled-section en omni.html) y el de "App
   integrada para experiencia interactiva". */
.untitled-section .photo-caption-grid__item p,
#app-integrada .photo-caption-grid__item p{
  text-align: justify;
}
/* Omni, solo versión en inglés: "Omni is a high-resolution circular
   LED display" y "A luxury object with a simple, minimalist finish"
   son más cortas que su equivalente en español y entran en un solo
   renglón — un renglón único con justify no se centra (justify no
   estira la única línea de un párrafo), queda pegado al borde
   izquierdo de su caja en vez de centrado contra la foto. Se pisa a
   center solo para estas dos (clase puesta en el HTML), en cualquier
   ancho de pantalla — a diferencia de .caption-oneline (que fuerza
   un renglón desde cierto ancho), acá alcanza con centrar: el texto
   ya entra en 1 o 2 renglones según el ancho, y center se ve bien en
   cualquiera de los dos casos. */
.untitled-section .photo-caption-grid__item p.caption-centered{
  text-align: center;
}
/* Omni (solo tablet): las 4 fotos debajo del hero, sin justificar —
   alineadas a la izquierda. Desktop y celular quedan justificados. */
@media (min-width: 641px) and (max-width: 819px){
  .untitled-section .photo-caption-grid__item p{
    text-align: left;
  }
}
/* Trinity: "Hard & Soft" y "Experiencia interactiva". */
#hard-soft .duo-columns__col p{
  text-align: justify;
}
/* Infinity: texto debajo de las 2 fotos que siguen al hero (sin
   título de sección, mismo .untitled-section que Omni pero acá con
   duo-gallery + .section-caption en vez de photo-caption-grid). */
.untitled-section .section-caption p{
  text-align: justify;
}
/* Trinity (solo celular): "Proyección", "Escultura" y "Arte Digital". */
@media (max-width: 640px){
  #proyeccion .section-caption p,
  #escultura .section-caption p,
  #arte-digital .section-caption p{
    text-align: justify;
  }
}

/* ---------- Omni: "Integra múltiples facetas..." en un solo renglón
   mientras el ancho de pantalla lo permita (pedido explícito) — con
   la MISMA letra que las otras 3 leyendas (a diferencia de un intento
   anterior, que la achicaba para que entrara siempre: el cliente
   prefiere que quede pareja y, si no entra, que pase a 2 renglones
   como el resto). Medido en vivo: el texto sin cortar necesita
   754.6px a la letra más grande (26px, ver clamp de
   .photo-caption-grid__item p) — la columna de esta leyenda (borde a
   borde, sin var(--margin-x)) llega a esa medida recién pasados los
   ~1500px de ancho real de pantalla; 1550px deja un margen chico de
   sobra. Por debajo de eso, sigue en 2 renglones, igual que siempre.
   width:fit-content + margin-inline:auto: en 1 renglón la caja pasa a
   medir justo el ancho del texto, así el centrado (margin:auto) queda
   centrado respecto a la foto de arriba, igual que las otras 3 leyendas
   (si no, al quitar el max-width la caja ocupa toda la columna y el
   texto, justificado, queda pegado a la izquierda en vez de centrado). */
@media (min-width: 1550px){
  .untitled-section .photo-caption-grid__item p.caption-oneline{
    white-space: nowrap;
    max-width: none;
    width: fit-content;
    margin-inline: auto;
  }
}

/* ============================================
   Light Mirage
   ============================================ */

/* ---------- Textos justificados (a pedido del cliente, solo en esta
   ventana): el texto de cierre de "Plataforma de Arte Digital" y el
   pie de cada captura de la app. El texto superpuesto sobre la foto
   de hero (.product-hero__caption) no entra acá — sigue centrado,
   como en el resto de las páginas de producto. ---------- */
#plataforma-arte-digital .section-caption p,
.lm-screens .photo-caption-grid__item p{
  text-align: justify;
}
/* "Display standard" e "Instalación Infinity": pies cortos de una
   sola línea, no un párrafo — justify no los centra (una sola línea
   queda alineada a la izquierda), se ven pegados al borde izquierdo
   de la caja en vez de centrados contra su foto. Se pisa a center
   solo para estos dos (clase puesta en el HTML), tanto en la versión
   desktop (cada uno con su propio <p>) como en el clon dentro de
   .synced-captions que usan tablet/celular (mismo <p>, clonado por
   JS con sus clases, ver setupLoopingCarousel en main.js). */
.lm-screens .photo-caption-grid__item p.caption-centered,
.synced-captions p.caption-centered{
  text-align: center;
}
/* Desktop: en 2 renglones en vez de 3 — el max-width de .section-caption
   (900px desde los 1139px) se queda corto para este texto más largo.
   1400px no es un ancho "real": es a propósito más grande que
   cualquier pantalla de verdad, para que el límite efectivo lo ponga
   siempre el viewport (y el padding lateral propio de .section-caption)
   y no este valor — así entra en 2 renglones en cualquier desktop
   real y solo pasa a 3 si la ventana se angosta lo suficiente (medido:
   necesita ~972px de texto disponible en tablet ancha/desktop chico
   con fuente 20px, ~1200px con fuente 26px desde 1139px). */
@media (min-width: 820px){
  #plataforma-arte-digital .section-caption{
    max-width: 1400px;
    padding-bottom: 130px; /* 100px + 30%: más separación hasta las capturas de la app de abajo */
  }
}

/* ---------- 4 capturas de la app con su propio pie ("Playing",
   "Browse", "Filters", "Brightness"). Reutiliza
   .photo-caption-grid.swipe-grid tal cual (grilla 2x2 en tablet, foto
   cuadrada, swipe+puntitos en celular) con las fotos del set "tablet
   y mobile" que dio el cliente. Cada foto es un <picture>: en
   desktop (≥820px) el navegador elige sola la versión "desktop" (las
   mismas capturas, recortadas más de cerca al teléfono) sin JS ni
   duplicar el HTML de las leyendas.
   En desktop, igual que en el mockup: dos fotos con su texto arriba,
   las otras dos abajo (2x2, no una sola fila) — mismo espacio entre
   las dos fotos de cada renglón que entre cada una y el lateral
   correspondiente (justify-content:space-evenly). Cada foto queda a
   la altura de las fotos cuadradas del duo-gallery de "Plataforma de
   Arte Digital" de arriba (mismo cálculo: (100vw - --photo-gap) / 2).
   Como estas fotos son rectangulares, no cuadradas, el ancho que les
   toca a esa altura sale de su proporción real (834x1800 ya
   redimensionadas, equivalente a las 4493x9697 originales = 0.4633) —
   el pie de cada una usa el mismo cálculo de ancho para quedar
   centrado y justificado contra su propia foto, no contra toda la
   tarjeta.
   display:grid en vez de flex a propósito: setupLoopingCarousel()
   (main.js) arma clones para loop infinito en cualquier galería cuyo
   display computado sea "flex" — .swipe-grid ya usa ese chequeo para
   saber si de verdad es un carrusel activo (display:flex, o sea
   celular) o no (grid, desktop/tablet). Si acá se pusiera flex,
   quedaría marcado como carrusel también en desktop y main.js le
   sumaría clones del primer/último ítem, duplicando fotos. Grid con
   justify-content:space-evenly logra la misma distribución simétrica
   sin ese efecto secundario. */
@media (min-width: 820px){
  .lm-screens{
    display: grid;
    grid-template-columns: repeat(2, max-content);
    justify-content: space-evenly;
    align-items: flex-start;
    gap: 100px 0; /* horizontal ya la da justify-content; vertical, entre renglón 1 y 2 */
  }
  .lm-screens .photo-caption-grid__item{
    padding-bottom: 100px;
  }
  .lm-screens .thumb{
    aspect-ratio: auto;
    width: calc((100vw - var(--photo-gap)) / 2 * 0.4633);
    height: calc((100vw - var(--photo-gap)) / 2);
    /* el pie de foto (ver más abajo) es más ancho que la imagen
       (+60px), por lo que la columna de la grilla termina siendo tan
       ancha como el texto — sin este margin-inline:auto la imagen
       quedaba pegada al lateral izquierdo de esa columna en vez de
       centrada, aunque el texto sí se veía centrado (bug real: el
       texto solo parecía "expandirse" hacia la derecha). */
    margin-inline: auto;
    /* Separación entre la foto y su pie de texto: +50% sobre la
       separación general del sitio (15px, .photo-caption-grid__item
       .thumb) — pedido explícito, solo para estas 4 capturas. */
    margin-bottom: 22.5px; /* 15px + 50% */
  }
  .lm-screens .photo-caption-grid__item p{
    /* mismo ancho que la foto (ver .lm-screens .thumb) + más todavía
       de cada lado (30px -> 50px -> 75px, pedidos explícitos sucesivos
       de expandir más), centrado contra la foto */
    max-width: calc((100vw - var(--photo-gap)) / 2 * 0.4633 + 150px);
    margin-inline: auto;
    padding-inline: 0;
  }
}

/* ---------- Tablet y celular: la foto de cada captura de la app
   (set "tablet y mobile") se mostraba recortada — .photo-caption-grid__item
   .thumb fuerza aspect-ratio:1/1 para las grillas cuadradas del resto
   del sitio, pero estas capturas no son cuadradas (967x1400 ya
   redimensionadas). Se sobreescribe con su proporción real para que
   entre la captura completa, de borde a borde (mismo ancho que
   cualquier otra foto de .photo-caption-grid, edge-to-edge). */
@media (max-width: 819px){
  .lm-screens .thumb{
    aspect-ratio: 967 / 1400;
  }
}

/* ---------- Tablet: mismo swipe que celular ----------
   Pedido explícito del cliente: en tablet las 4 capturas de la app
   también se deslizan una por una (como en celular), en vez de la
   grilla 2x2 de desktop. Mismas propiedades que .swipe-grid en
   celular (ver arriba), pero acá scopeadas a .lm-screens nada más —
   los demás usos de .swipe-grid del sitio (ej. "App integrada..." de
   Omni) siguen en grilla en tablet, sin cambios. */
@media (min-width: 641px) and (max-width: 819px){
  .lm-screens{
    display: flex;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    overscroll-behavior-y: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .lm-screens::-webkit-scrollbar{ display: none; }
  .lm-screens > *{
    flex: 0 0 100%;
    width: 100%;
    scroll-snap-align: center;
  }
  .lm-screens.photo-caption-grid .photo-caption-grid__item{
    padding-bottom: 0;
  }
  .lm-screens + .gallery-dots{
    display: flex;
  }
}

/* ---------- Puntitos + pie de foto sincronizado (celular y tablet) ----------
   Pedido explícito: durante el swipe, el orden visual tiene que ser
   foto -> puntitos -> texto (mismo orden que la galería de arriba,
   "Plataforma de Arte Digital"), no foto -> texto -> puntitos como
   quedaba antes: el <p> de cada captura vivía adentro de su propia
   tarjeta, pegado a la foto, y los puntitos (únicos, uno solo para
   las 4 fotos) aparecían recién al final, después de la última.
   El texto de cada captura sigue viviendo en un solo lugar (su <p>
   adentro de .photo-caption-grid__item — es lo que se ve en el 2x2 de
   desktop): acá ese <p> se oculta y el JS (main.js) clona su
   contenido dentro de .synced-captions (vacío en el HTML, después de
   los puntitos), un clon por foto. Los 4 clones comparten la misma
   celda de grilla (superpuestos) y se muestran/ocultan con
   visibility según qué foto está activa en el swipe — así el alto del
   bloque no cambia entre una captura y otra y no salta la línea
   divisoria de más abajo. */
.synced-captions{
  display: none; /* solo existe en celular/tablet — en desktop cada captura ya muestra su propio <p>, ver .lm-screens .photo-caption-grid__item p más arriba */
}
@media (max-width: 819px){
  .lm-screens .thumb{
    margin-bottom: 0; /* ese espacio lo pone ahora .gallery-dots (margin-top propio), no la foto: acá el pie de foto ya no sigue directo a la imagen, van primero los puntitos */
  }
  .lm-screens .photo-caption-grid__item p{
    display: none; /* clonado en .synced-captions vía JS, ver comentario arriba */
  }
  .lm-screens + .gallery-dots{
    margin-bottom: 0; /* ya no son los puntitos lo último antes de la próxima sección — ahora sigue el pie de foto (.synced-captions), que aporta esos 100px, ver abajo */
  }
  .synced-captions{
    display: grid;
    max-width: 640px;
    margin: 23px auto 0; /* mismo criterio que .section-caption: puntitos -> texto, cerca */
    padding: 0 var(--margin-x) 100px; /* mismo espacio hasta la línea divisoria que el resto de los pies de foto del sitio */
    text-align: justify;
  }
  .synced-captions p{
    grid-row: 1;
    grid-column: 1;
    margin: 0;
    font-size: 20px;
    line-height: 1.6;
    font-weight: 300;
    color: var(--fg);
    visibility: hidden;
  }
  .synced-captions p.is-active{
    visibility: visible;
  }
}
/* "App integrada..." (Omni) es swipe solo en celular (a diferencia de
   Light Mirage, que también lo es en tablet, ver .lm-screens más
   arriba) — la regla genérica de arriba muestra .synced-captions
   hasta los 819px, pero en tablet esta sección vuelve a la grilla
   2 columnas normal, con cada <p> ya visible dentro de su propia
   tarjeta: sin este corte, el texto de "Integra múltiples
   funciones..." se veía duplicado (una vez en su tarjeta, otra en
   .synced-captions, que seguía de pie). */
/* El título sticky de la sección (ver section.grid-section h2 en
   styles.css) queda pegado mientras la CAJA de la sección todavía
   sigue por debajo de la barra — esa caja incluye el padding-bottom
   de .synced-captions (100px), que es espacio en blanco, no texto. El
   título mide más que esos 100px, así que quedaba pegado tapando ese
   espacio vacío bastante después de que el texto real ya había
   desaparecido de la pantalla. Se mueve ese mismo espacio a la
   sección siguiente (mismo negro de fondo, mismo total visual) para
   que el título se despegue apenas se deja de ver el texto. Solo
   celular: es el único formato donde el título es sticky. */
@media (max-width: 640px){
  #app-integrada .synced-captions{
    padding-bottom: 0;
  }
  #app-integrada + section{
    padding-top: 100px;
  }
}
@media (min-width: 641px) and (max-width: 819px){
  #app-integrada .synced-captions{
    display: none;
  }
}


/* ---------- Omni: "Referencias" (16 fotos en páginas) ----------
   El JS (main.js, .ref-grid) agrupa las 16 fotos en páginas dentro de
   .ref-track > .ref-page:
   - Desktop (>819px): 4 columnas x 2 filas = 8 fotos por página (2
     páginas). Las flechas deslizan la pista con una transición suave.
   - Tablet y celular (<=819px): 2 columnas x 2 filas = 4 fotos por
     página (4 páginas), como la grilla 2x2 de "Aplicaciones". Sin
     flechas: la pista es un scroll horizontal con enganche (swipe).
   Las 16 fotos abren en grande en el lightbox y se recorren con clic
   (data-lightbox="always", igual que la galería final de Trinity).
   Entre fotos que se tocan va --photo-gap (6px, igual que la galería
   final de Trinity); contra el borde de pantalla van al ras. */
#referencias{
  padding-bottom: 100px; /* espacio estándar hasta el logo de cierre (padding, no margin: ver regla de oro #3) */
}
#referencias .ref-intro{
  max-width: none;
  margin: 0 0 20px; /* mismo espacio texto -> fotos que el resto de los .section-intro del sitio */
  text-align: left; /* alineado a la izquierda, como en el mockup */
}
/* Sin JS (por las dudas): grilla común de 4 columnas, se ven las 16 */
.ref-grid{
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--photo-gap);
  background: #000000;
}
@media (max-width: 819px){
  .ref-grid{ grid-template-columns: repeat(2, 1fr); }
}
/* Con JS: la grilla pasa a ser una ventana (overflow oculto) que
   muestra una página de la pista a la vez */
.ref-grid.ref-ready{
  display: block;
  overflow: hidden;
}
.ref-track{
  display: flex;
  background: #000000;
  transition: transform 1s cubic-bezier(0.65, 0, 0.35, 1); /* desliza suave entre páginas (desktop): arranca y frena despacio. Antes 0.6s con curva (0.4, 0, 0.2, 1), se sentía brusco */
  will-change: transform;
}
.ref-page{
  flex: 0 0 100%;
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--photo-gap);
  background: #000000;
}
.ref-grid .thumb{
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: #000000;
}
.ref-grid img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Flechas + puntitos. Los puntitos son solo indicadores (no
   clickeables): marcan en qué página estás. Flechas: chevron fino de
   1.5px, mismo estilo que la flechita de "Productos" del menú mobile. */
.ref-pager{
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 28px;
  padding-top: 48px; /* padding (no margin): ver regla de oro #3 */
  background: #000000;
}
.ref-pager__arrow{
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px; /* zona de toque cómoda; el dibujo en sí mide 15x19px */
  height: 44px;
  padding: 0;
  background: #000000;
  border: none;
  color: var(--fg);
  opacity: 0.75;
  cursor: pointer;
  transition: opacity 0.2s ease;
}
.ref-pager__arrow:hover, .ref-pager__arrow:focus-visible{ opacity: 1; }
.ref-pager__dots{
  display: flex;
  align-items: center;
  gap: 12px;
}
.ref-pager__dots span{
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255,255,255,0.35);
  transition: background 0.3s ease;
}
.ref-pager__dots span.active{ background: rgba(255,255,255,0.95); }

/* Tablet y celular: 2x2 por página, swipe manual (sin flechas) y
   puntitos del mismo tamaño que los del resto del sitio
   (.gallery-dots: 6px, separados 8px). */
@media (max-width: 819px){
  .ref-page{
    grid-template-columns: repeat(2, 1fr);
    gap: calc(var(--photo-gap) * 0.6); /* separación entre fotos -40% solo acá (6px -> 3.6px), pedido explícito del cliente */
  }
  .ref-track{
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    -ms-overflow-style: none;
    transform: none !important; /* acá no se mueve con transform: lo mueve el scroll */
    transition: none;
    will-change: auto;
  }
  .ref-track::-webkit-scrollbar{ display: none; }
  .ref-page{ scroll-snap-align: center; }
  .ref-pager__arrow{ display: none; }
  .ref-pager{ gap: 0; }
  .ref-pager__dots{ gap: 8px; }
  .ref-pager__dots span{ width: 6px; height: 6px; }
}
