/* ==========================================================================
   Portafolio, hoja de estilos
   --------------------------------------------------------------------------
   Mobile-first: la base es pantalla chica y las media queries solo agregan.

   Criterio de composición: el orden lo dan las líneas finas, la escala
   tipográfica y el aire. Casi nada vive dentro de una caja con borde, porque
   una página hecha de rectángulos redondeados se lee como una plantilla y no
   como un portafolio.
   ========================================================================== */

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

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

body, h1, h2, h3, h4, p, ul, ol, li, figure, blockquote, dl, dd, dt {
  margin: 0;
  padding: 0;
}

ul, ol { list-style: none; }

img, svg { display: block; max-width: 100%; height: auto; }

button { font: inherit; color: inherit; }

/* --- Base --------------------------------------------------------------- */
html {
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;
}

body {
  background: var(--paper);
  color: var(--ink-2);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;

  /* `clip` y no `hidden`. `overflow-x: hidden` obliga al eje vertical a
     `auto`, convierte al body en contenedor de desplazamiento y, con una
     galería horizontal dentro, un gesto diagonal en móvil arrastra la página
     entera de costado. `clip` recorta sin crear ese contenedor. */
  overflow-x: clip;
}

h1, h2, h3, h4 {
  color: var(--ink);
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}

p { text-wrap: pretty; }

a { color: var(--accent); text-underline-offset: 0.18em; }

:where(a, button, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* --- Utilidades --------------------------------------------------------- */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: var(--space-4);
  top: var(--space-4);
  z-index: 100;
  transform: translateY(-200%);
  background: var(--accent);
  color: var(--accent-ink);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius);
  font-weight: var(--weight-medium);
  text-decoration: none;
}

.skip-link:focus { transform: translateY(0); }

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.icon {
  width: 1.5rem;
  height: 1.5rem;
  flex: none;
}

.icon--inline {
  width: 1em;
  height: 1em;
  display: inline-block;
  vertical-align: -0.12em;
}

/* Marcador de contenido pendiente. Mientras se vea, no se publica. */
.todo {
  display: inline-block;
  background: var(--todo-bg);
  color: var(--todo-ink);
  border: 1px dashed var(--todo-rule);
  border-radius: var(--radius-sm);
  padding: 0.1em 0.45em;
  font-family: var(--font-mono);
  font-size: 0.9em;
  line-height: 1.45;
}

/* --- Aparición al desplazar ---------------------------------------------
   Solo se oculta si hay JS: sin script, `.js` nunca se aplica y el contenido
   se ve de entrada. Nunca se esconde algo que no se pueda volver a mostrar. */
.js .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
  transition-delay: calc(var(--i, 0) * 70ms);
}

.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* --- Cabecera ----------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  background: color-mix(in srgb, var(--paper) 86%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--rule);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 3.5rem;
}

.site-header__name {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--ink);
  text-decoration: none;
  letter-spacing: var(--tracking-tight);
  margin-inline-end: auto;
}

/* Botón de menú: solo existe con JS y solo en pantalla chica. Se muestra
   dentro de la media query de móvil, nunca por defecto. */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  margin-inline-end: calc(var(--space-2) * -1);
  background: none;
  border: 0;
  border-radius: var(--radius);
  color: var(--ink);
  cursor: pointer;
}

.nav-toggle__icon {
  position: relative;
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
}

.nav-toggle__icon .icon {
  grid-area: 1 / 1;
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}

.nav-toggle__close { opacity: 0; transform: rotate(-90deg) scale(0.7); }

.nav-open .nav-toggle__open { opacity: 0; transform: rotate(90deg) scale(0.7); }
.nav-open .nav-toggle__close { opacity: 1; transform: none; }

/* Sin JS la navegación es una fila desplazable, siempre visible. */
.site-nav { overflow-x: auto; scrollbar-width: none; }
.site-nav::-webkit-scrollbar { display: none; }

.site-nav ul {
  display: flex;
  gap: var(--space-4);
  white-space: nowrap;
}

.site-nav a {
  position: relative;
  display: inline-block;
  padding-block: var(--space-2);
  font-size: var(--text-sm);
  color: var(--ink-3);
  text-decoration: none;
  transition: color var(--dur) var(--ease-out);
}

/* Subrayado que crece desde la izquierda, en vez de aparecer de golpe. */
.site-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0.25rem;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease-out);
}

.site-nav a:hover { color: var(--ink); }
.site-nav a:hover::after { transform: scaleX(1); }

/* Panel de móvil: sale de abajo de la cabecera, no tapa la marca. */
@media (max-width: 47.999rem) {
  .js .nav-toggle { display: inline-flex; }

  .js .site-nav {
    position: fixed;
    inset: 3.5rem 0 auto 0;
    z-index: 25;
    background: var(--surface);
    border-bottom: 1px solid var(--rule);
    box-shadow: var(--shadow);
    overflow: hidden;
    opacity: 0;
    transform: translateY(-0.75rem);
    visibility: hidden;
    transition:
      opacity var(--dur) var(--ease-out),
      transform var(--dur) var(--ease-out),
      visibility 0s linear var(--dur);
  }

  .js.nav-open .site-nav {
    opacity: 1;
    transform: none;
    visibility: visible;
    transition-delay: 0s;
  }

  .js .site-nav ul {
    flex-direction: column;
    gap: 0;
    padding: var(--space-2) var(--gutter) var(--space-4);
  }

  .js .site-nav li + li { border-top: 1px solid var(--rule); }

  .js .site-nav a {
    display: block;
    padding-block: var(--space-4);
    font-size: var(--text-lg);
    color: var(--ink);
  }

  .js .site-nav a::after { display: none; }

  .nav-scrim {
    position: fixed;
    inset: 0;
    z-index: 20;
    background: rgb(0 0 0 / 0.45);
    animation: fade-in var(--dur) var(--ease-out);
  }

  .nav-scrim[hidden] { display: none; }
}

@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

/* --- Estructura de secciones -------------------------------------------- */
main > section {
  position: relative;
  padding-block: var(--section-gap);
  --section-bg: var(--paper);
}

/* Banda tenue en lugar de una línea divisoria más: cambia el ritmo sin sumar
   otro borde a la página. */
.section--tinted {
  background: var(--surface-alt);
  --section-bg: var(--surface-alt);
  /* Contiene el motivo decorativo sin volverse contenedor de desplazamiento. */
  overflow: clip;
}

main > section + section:not(.section--tinted) { border-top: 1px solid var(--rule); }
.section--tinted + section:not(.section--tinted) { border-top: 0; }

/* Motivo de chevrones tomado del fondo del retrato. Decorativo y muy tenue:
   está para dar textura, no para competir con el texto. */
.motif {
  position: absolute;
  top: -3rem;
  right: -5rem;
  width: 22rem;
  height: 22rem;
  color: var(--ink);
  opacity: 0.05;
  pointer-events: none;
  animation: motif-drift 22s var(--ease-in-out) infinite alternate;
}

@keyframes motif-drift {
  from { transform: translate3d(0, 0, 0) rotate(0deg); }
  to   { transform: translate3d(-1.25rem, 1.5rem, 0) rotate(-3deg); }
}

.section-head { margin-bottom: var(--space-7); }

.section-label {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--ink-3);
}

.section-label__num { color: var(--accent); font-variant-numeric: tabular-nums; }

/* Filete que remata la etiqueta y sostiene la retícula. */
.section-label::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--rule);
}

.section-title { font-size: var(--text-2xl); }

.section-intro {
  margin-top: var(--space-4);
  font-size: var(--text-lg);
  color: var(--ink-2);
  max-width: var(--measure);
}

.minor-title {
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: var(--space-3);
}

/* --- Hero ----------------------------------------------------------------
   Móvil: la foto es banda superior y el texto va debajo, sobre fondo plano.
   Desde 48rem la foto pasa a fondo y el texto se apoya en el aire que la
   propia composición deja a la izquierda. */

.hero {
  padding-top: 0;
  padding-bottom: var(--section-gap);
}

.hero__media { display: block; margin-bottom: var(--space-6); }

.hero__media img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  /* La toma vertical deja mucho aire arriba: el recorte baja para encuadrar
     rostro y torso en vez de fondo. */
  object-position: 50% 46%;
  animation: hero-in 1s var(--ease-out) both;
}

@keyframes hero-in {
  from { opacity: 0; transform: scale(1.04); }
  to   { opacity: 1; transform: none; }
}

.hero__name {
  font-size: var(--text-3xl);
  margin-bottom: var(--space-3);
}

.hero__headline {
  font-size: var(--text-xl);
  color: var(--ink-2);
  font-weight: var(--weight-medium);
  line-height: var(--leading-snug);
  max-width: var(--measure);
  margin-bottom: var(--space-5);
}

.hero__intro {
  font-size: var(--text-lg);
  max-width: var(--measure);
  margin-bottom: var(--space-6);
}

/* Dato y etiqueta, sin pastillas. */
.hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5);
  margin-bottom: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--rule);
}

.hero__meta dt {
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: var(--space-1);
}

.hero__meta dd { color: var(--ink); font-weight: var(--weight-medium); }

.hero__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
}

.hero__links a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--weight-medium);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: 2px;
}

.hero__links a .icon--inline {
  transition: transform var(--dur) var(--ease-out);
}

.hero__links a:hover .icon--inline { transform: translateX(3px); }

/* --- Trabajo seleccionado ------------------------------------------------
   Sin tarjetas: cada caso es un bloque separado por una línea fina, con la
   identificación a un lado y el desarrollo al otro. */

.cases { display: grid; }

.case {
  display: grid;
  gap: var(--space-5);
  padding-block: var(--space-7);
  border-top: 1px solid var(--rule);
}

.case:last-child { border-bottom: 1px solid var(--rule); }

.case__aside { display: grid; gap: var(--space-2); align-content: start; }

.case__index {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.case__icon { color: var(--accent); }

.case__client { font-size: var(--text-xl); }

.case__sector, .case__role {
  font-size: var(--text-sm);
  color: var(--ink-3);
  line-height: var(--leading-snug);
}

/* `min-width: 0` no es opcional acá. Una pista de grilla se dimensiona por
   defecto al contenido mínimo de sus hijos, así que un contenedor con
   desplazamiento horizontal adentro ensancha la columna hasta caber entero y
   empuja la página. Es lo que hacía que en móvil un gesto en diagonal sacara
   todo de margen. */
.case, .case__body, .case__block { min-width: 0; }

.case__body { display: grid; gap: var(--space-5); }

.case__block h4 {
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: var(--space-2);
}

.case__block p { max-width: var(--measure); }

.case__work { display: grid; gap: var(--space-2); max-width: var(--measure); }

.case__work li { position: relative; padding-left: var(--space-5); }

.case__work li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.72em;
  width: 0.5rem;
  height: 1px;
  background: var(--rule-2);
}

/* --- Galería de piezas ---------------------------------------------------
   Tira horizontal en vez de cuadrícula: entra cualquier cantidad de piezas sin
   estirar la página, y en móvil se pasa con el dedo. Sangra hasta el borde de
   la pantalla para que se note que hay más a la derecha. */

.pieces {
  min-width: 0;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(14rem, 17rem);
  gap: var(--space-4);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scroll-padding-inline: var(--gutter);
  padding-bottom: var(--space-3);
  margin-inline: calc(var(--gutter) * -1);
  padding-inline: var(--gutter);
  overscroll-behavior-x: contain;
}

.pieces:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; }

.piece { scroll-snap-align: start; }

/* El enlace envuelve la imagen: sin JavaScript abre el archivo a tamaño
   completo, y con JavaScript se intercepta para mostrarlo en el visor. */
.piece__zoom {
  position: relative;
  display: block;
  overflow: clip;
  border-radius: var(--radius);
}

.piece img {
  width: 100%;
  height: auto;
  background: var(--surface-alt);
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}

.piece__zoom:hover img { transform: scale(1.02); }

/* Señal de que se puede ampliar. En táctil no hay hover, así que se mantiene
   siempre visible en vez de aparecer al pasar el puntero. */
.piece__hint {
  position: absolute;
  right: var(--space-2);
  bottom: var(--space-2);
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-sm);
  background: rgb(9 11 14 / 0.62);
  color: #fff;
  backdrop-filter: blur(4px);
  transition: background var(--dur) var(--ease-out);
}

.piece__hint .icon { width: 1.1rem; height: 1.1rem; }

.piece__zoom:hover .piece__hint { background: rgb(9 11 14 / 0.85); }

.piece--square img { aspect-ratio: 1 / 1; }
.piece--wide img { aspect-ratio: 16 / 9; }
.piece--tall img { aspect-ratio: 3 / 4; object-position: top; }

.piece figcaption {
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  color: var(--ink-3);
  line-height: var(--leading-snug);
}

/* Las capturas de sitio necesitan más ancho para que se lean. */
.piece--wide { grid-column: span 1; }

.case__links { display: grid; gap: var(--space-3); }

.case__link {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2);
  font-weight: var(--weight-medium);
  text-decoration: none;
  overflow-wrap: anywhere;
}

.case__link span { border-bottom: 1px solid color-mix(in srgb, currentColor 40%, transparent); }
.case__link:hover span { border-bottom-color: currentColor; }

.case__link-note {
  display: block;
  margin-top: var(--space-1);
  font-size: var(--text-sm);
  color: var(--ink-3);
  max-width: var(--measure);
}

/* --- Flujo de producción de IA ------------------------------------------
   Cuatro etapas unidas por una línea. En móvil se apila y la línea es
   vertical; en escritorio se despliega y la línea es horizontal. Un SVG único
   con las cuatro etapas quedaría ilegible a 375px. */

.flow {
  position: relative;
  display: grid;
  gap: var(--space-6);
  margin-bottom: var(--space-8);
}

.flow::before {
  content: "";
  position: absolute;
  left: 1.375rem;
  top: 0.5rem;
  bottom: 0.5rem;
  width: 1px;
  background: var(--rule-2);
}

.flow__step { position: relative; padding-left: 4rem; }

.flow__mark {
  position: absolute;
  left: 0;
  top: 0;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  color: var(--accent);
  background: var(--section-bg);
  box-shadow: inset 0 0 0 1px var(--rule-2);
}

.flow__title { font-size: var(--text-lg); margin-bottom: var(--space-2); }

/* Sin tope de ancho: apilado, el propio contenedor ya lo limita, y un tope
   extra dejaría líneas cortadas a media frase. En escritorio lo limita la
   columna de la retícula. */
.flow__body { color: var(--ink-2); }

/* Cita destacada en lugar de un recuadro de aviso. */
.guardrails {
  margin-bottom: var(--space-8);
  padding-left: var(--space-5);
  border-left: 2px solid var(--accent);
  max-width: var(--measure);
}

.guardrails p {
  font-size: var(--text-xl);
  line-height: var(--leading-snug);
  color: var(--ink);
  letter-spacing: var(--tracking-tight);
}

.guardrails cite {
  display: block;
  margin-top: var(--space-3);
  font-style: normal;
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--ink-3);
}

.artifacts ul { display: grid; gap: var(--space-3); }

.artifacts a {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2);
  text-decoration: none;
  max-width: var(--measure);
}

.artifacts a span { border-bottom: 1px solid color-mix(in srgb, currentColor 40%, transparent); }
.artifacts a:hover span { border-bottom-color: currentColor; }

/* --- Desplegables --------------------------------------------------------
   <details> nativo: teclado y lector de pantalla incluidos, sin JavaScript. */

.disclosure { border-top: 1px solid var(--rule); }
.disclosure:last-of-type { border-bottom: 1px solid var(--rule); }

.disclosure summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-5);
  cursor: pointer;
  list-style: none;
}

.disclosure summary::-webkit-details-marker { display: none; }

.disclosure__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--ink);
  letter-spacing: var(--tracking-tight);
  transition: color var(--dur) var(--ease-out);
}

.disclosure summary:hover .disclosure__title { color: var(--accent); }

/* Signo dibujado con dos trazos: el vertical desaparece al abrir. */
.disclosure__sign {
  position: relative;
  flex: none;
  width: 1rem;
  height: 1rem;
  color: var(--ink-3);
}

.disclosure__sign::before,
.disclosure__sign::after {
  content: "";
  position: absolute;
  inset: 50% 0 auto 0;
  height: 1.5px;
  background: currentColor;
  border-radius: 2px;
  transition: transform var(--dur) var(--ease-out);
}

.disclosure__sign::after { transform: rotate(90deg); }
.disclosure[open] .disclosure__sign::after { transform: rotate(0deg); }

.disclosure__body { padding-bottom: var(--space-6); }

.disclosure[open] .disclosure__body {
  animation: disclosure-in var(--dur-slow) var(--ease-out);
}

@keyframes disclosure-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

/* --- Listados de capacidades y stack ------------------------------------ */
.groups { display: grid; gap: var(--space-6); }

.group h3 {
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: var(--space-3);
}

.group ul { display: grid; gap: var(--space-2); }
.group li, .plain li { color: var(--ink-2); }

.plain { display: grid; gap: var(--space-3); }
.plain strong { color: var(--ink); }

/* --- Trayectoria -------------------------------------------------------- */
.timeline { display: grid; }

.timeline__item {
  display: grid;
  gap: var(--space-1);
  padding-block: var(--space-5);
}

.timeline__item + .timeline__item { border-top: 1px solid var(--rule); }

.timeline__period {
  font-size: var(--text-sm);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.timeline__role { font-size: var(--text-lg); }
.timeline__org { color: var(--ink-2); font-weight: var(--weight-medium); }
.timeline__note { color: var(--ink-3); font-size: var(--text-sm); }

/* --- Contacto ----------------------------------------------------------- */
.closing {
  font-size: var(--text-lg);
  max-width: var(--measure);
  margin-bottom: var(--space-6);
}

.contact__list { display: grid; gap: var(--space-4); }

.contact__item {
  display: grid;
  gap: var(--space-1);
  padding-block: var(--space-4);
  border-top: 1px solid var(--rule);
}

.contact__label {
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--ink-3);
}

.contact__value { font-size: var(--text-lg); overflow-wrap: anywhere; }

.contact__value a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, currentColor 40%, transparent);
}

.contact__value a:hover { border-bottom-color: currentColor; }
.contact__value a .icon--inline { transition: transform var(--dur) var(--ease-out); }
.contact__value a:hover .icon--inline { transform: translateX(3px); }

/* --- Medición y reporting ----------------------------------------------- */
.reporting { margin-top: var(--space-7); }

.reporting__intro {
  max-width: var(--measure);
  margin-bottom: var(--space-5);
  color: var(--ink-2);
}

/* Marcas en fila, separadas por un punto. Sin pastillas: son enlaces de
   lectura, no etiquetas. */
.brands {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
}

.brands li { position: relative; }

.brands li + li::before {
  content: "";
  position: absolute;
  left: calc(var(--space-2) * -1);
  top: 50%;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--rule-2);
}

.brands a {
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, currentColor 40%, transparent);
}

.brands a:hover { border-bottom-color: currentColor; }

/* --- Visor ampliado ------------------------------------------------------
   <dialog> nativo: el encierro de foco, el cierre con Escape y la devolución
   del foco vienen de serie. Solo hay que darle forma. */

.lightbox {
  width: min(100vw - 2rem, 78rem);
  max-width: none;
  max-height: calc(100dvh - 2rem);
  padding: 0;
  border: 0;
  background: none;
  overflow: visible;
  color: #fff;
}

.lightbox::backdrop {
  background: rgb(6 8 10 / 0.88);
  backdrop-filter: blur(3px);
}

.lightbox[open] { animation: lightbox-in var(--dur-slow) var(--ease-out); }

@keyframes lightbox-in {
  from { opacity: 0; transform: scale(0.98); }
  to   { opacity: 1; transform: none; }
}

.lightbox__stage { border-radius: var(--radius); }

.lightbox__img {
  width: 100%;
  max-height: calc(100dvh - 8rem);
  object-fit: contain;
  border-radius: var(--radius);
  background: #000;
}

/* En pantalla chica, ajustar un tablero apaisado al ancho lo deja ilegible,
   que es justo lo que el visor tiene que resolver. Debajo de 48rem la imagen
   se muestra a una altura cómoda y el escenario se desplaza en horizontal, así
   que las cifras se leen recorriendo en vez de haciendo zoom con dos dedos. */
@media (max-width: 47.999rem) {
  .lightbox__stage {
    overflow: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    background: #000;
  }

  .lightbox__stage:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

  .lightbox__img {
    width: auto;
    max-width: none;
    height: min(calc(100dvh - 9rem), 34rem);
    max-height: none;
    border-radius: 0;
  }
}

.lightbox__caption {
  margin-top: var(--space-3);
  font-size: var(--text-sm);
  color: rgb(255 255 255 / 0.82);
  text-align: center;
}

/* Objetivo táctil de 44px, separado del borde para que no lo tape el pulgar. */
.lightbox__close {
  position: absolute;
  top: -0.5rem;
  right: 0;
  transform: translateY(-100%);
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border: 0;
  border-radius: 50%;
  background: rgb(255 255 255 / 0.14);
  color: #fff;
  cursor: pointer;
  transition: background var(--dur) var(--ease-out);
}

.lightbox__close:hover { background: rgb(255 255 255 / 0.26); }
.lightbox__close:focus-visible { outline-color: #fff; }

/* --- Pie ---------------------------------------------------------------- */
.site-footer {
  border-top: 1px solid var(--rule);
  padding-block: var(--space-6);
  color: var(--ink-3);
  font-size: var(--text-sm);
}

/* ==========================================================================
   A partir de tablet
   ========================================================================== */

@media (min-width: 48rem) {
  /* Hero: foto de fondo y texto sobre el aire de la izquierda. El velo no es
     decorativo, es lo que sostiene el contraste AA del texto blanco sobre un
     degradado claro. Por eso el hero se compromete a un solo aspecto oscuro
     en los dos temas. */
  .hero {
    isolation: isolate;
    display: grid;
    align-items: center;
    /* El tope de arriba tiene que ser alto. Si la altura deja de crecer con el
       ancho, la imagen se sigue ampliando pero la ventana visible no, y el
       recorte se come la cabeza. Con 44vw la proporción recortada es la misma
       a 1280 que a 2000, así que el encuadre no cambia. */
    min-height: clamp(30rem, 44vw, 60rem);
    padding-block: var(--space-8);
    overflow: clip;
  }

  .hero__media { position: absolute; inset: 0; margin: 0; z-index: -2; }

  .hero__media img {
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
    /* La cabeza arranca en el 6,4% del alto de la foto. Con el 82% visible,
       un 28% deja el recorte empezando cerca del 5%: gana torso sin tocar
       el pelo. */
    object-position: 72% 28%;
  }

  /* Por encima de unos 2200px la altura ya topó y la ventana visible se
     encoge, así que el encuadre tiene que subir para no comerse la cabeza. */
  @media (min-width: 137.5rem) {
    .hero__media img { object-position: 72% 10%; }
  }

  .hero::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(
      to right,
      rgb(9 11 14 / 0.94) 0%,
      rgb(9 11 14 / 0.91) 42%,
      rgb(9 11 14 / 0.72) 60%,
      rgb(9 11 14 / 0.22) 82%,
      rgb(9 11 14 / 0.08) 100%
    );
  }

  .hero__content > * { max-width: 32rem; }

  .hero__name, .hero__headline, .hero__intro { color: #ffffff; }

  .hero__meta { border-top-color: rgb(255 255 255 / 0.25); }
  .hero__meta dt { color: rgb(255 255 255 / 0.72); }
  .hero__meta dd { color: #ffffff; }

  .hero__links a { color: #cfe0ff; }
  .hero__links a:focus-visible { outline-color: #ffffff; }

  /* Casos en dos columnas: identificación fija a la izquierda. */
  .case {
    grid-template-columns: 15rem 1fr;
    gap: var(--space-6);
  }

  /* Dentro de la columna del caso la galería ya no necesita sangrar. */
  .pieces {
    margin-inline: 0;
    padding-inline: 0;
    scroll-padding-inline: 0;
    grid-auto-columns: minmax(15rem, 19rem);
  }

  .piece--wide { grid-column: span 2; }

  .timeline__item { grid-template-columns: 11rem 1fr; column-gap: var(--space-5); }
  .timeline__period { padding-top: 0.2em; }

  .contact__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .groups { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 64rem) {
  /* El flujo se despliega y la línea pasa a horizontal. */
  .flow { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-5); }

  .flow::before {
    left: 1.375rem;
    right: 1.375rem;
    top: 1.375rem;
    bottom: auto;
    width: auto;
    height: 1px;
  }

  .flow__step { padding-left: 0; padding-top: 3.75rem; }

  .groups { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* --- Movimiento reducido ------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .motif { animation: none; }

  .js .reveal { opacity: 1; transform: none; transition: none; }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* --- Impresión -----------------------------------------------------------
   Algunos reclutadores guardan a PDF. Que salga legible y con los desplegables
   abiertos: un acordeón cerrado en papel es contenido perdido. */
@media print {
  .site-header, .skip-link, .hero__media, .motif, .nav-scrim { display: none; }

  body { background: #fff; color: #000; font-size: 11pt; }

  .hero { min-height: 0; padding-block: 0; }
  .hero::before { display: none; }
  .hero__name, .hero__headline, .hero__intro, .hero__meta dd { color: #000; }

  .js .reveal { opacity: 1; transform: none; }

  .disclosure__body { display: block !important; }
  .disclosure__sign { display: none; }

  .case { break-inside: avoid; }
  main > section { padding-block: 1.5rem; }

  a { color: #000; text-decoration: underline; }
  .case__link::after { content: " (" attr(href) ")"; font-size: 9pt; }
}
