/* ==========================================================================
   MOTION

   Un solo momento autorado —la apertura de la portada— y, para el resto
   del documento, tres revelados que no son variantes decorativas sino
   tres gestos distintos tomados del lenguaje del plano:

     · los bloques SUBEN     → material que se coloca
     · los titulares SE DESCUBREN → una plantilla que se retira
     · los trazos SE DIBUJAN → la cota que se traza de izquierda a derecha

   Nada entra desde la nada: todo parte de un estado ya compuesto y se
   resuelve con un ease-out exponencial.
   ========================================================================== */

/* El porcentaje de la máscara necesita estar registrado para poder
   transicionarse; sin esto el navegador salta al valor final. */
@property --descubrir {
  syntax: '<percentage>';
  inherits: false;
  initial-value: -30%;
}

/* ------------------------------------------------- 1. BLOQUES QUE SUBEN */

.revelar {
  --revelar-retraso: 0ms;
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition:
    opacity 520ms var(--ease-out) var(--revelar-retraso),
    transform 740ms var(--ease-out) var(--revelar-retraso);
  will-change: transform, opacity;
}

.revelar[data-visible='true'] {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  will-change: auto;
}

/* --------------------------------------- 2. TITULARES QUE SE DESCUBREN
   Una máscara con borde difuso recorre el titular de arriba abajo. El
   borde suave es lo que lo separa de un simple recorte: la letra aparece
   como si se levantara una plantilla, no como si se abriera una persiana. */

.revelar-titulo {
  --revelar-retraso: 0ms;
  --descubrir: -30%;
  -webkit-mask-image: linear-gradient(to bottom, #000 var(--descubrir), transparent calc(var(--descubrir) + 26%));
  mask-image: linear-gradient(to bottom, #000 var(--descubrir), transparent calc(var(--descubrir) + 26%));
  opacity: 0.001;
  transform: translate3d(0, 10px, 0);
  transition:
    --descubrir 880ms var(--ease-cortina) var(--revelar-retraso),
    opacity 240ms linear var(--revelar-retraso),
    transform 880ms var(--ease-out) var(--revelar-retraso);
  will-change: mask-image, transform;
}

.revelar-titulo[data-visible='true'] {
  --descubrir: 130%;
  opacity: 1;
  transform: translate3d(0, 0, 0);
  will-change: auto;
}

/* Si el navegador no registra la propiedad, la máscara no anima: el
   titular queda sólo con la subida y el fundido, que sí funcionan. */
@supports not (background: paint(algo)) {
  .revelar-titulo { -webkit-mask-image: none; mask-image: none; opacity: 0; }
  .revelar-titulo[data-visible='true'] { opacity: 1; }
}

/* ------------------------------------------- 3. TRAZOS QUE SE DIBUJAN

   El recorte va en los hijos, nunca en el elemento observado. Un
   `clip-path` que deja la caja en ancho cero hace que el
   IntersectionObserver mida una intersección nula: el elemento no se
   marca como visible, no se desrecorta, y la cota no se dibuja jamás.
   Observando el contenedor —que conserva su caja— y recortando los
   tramos de dentro, el gesto funciona y además se puede escalonar.

   La secuencia imita cómo se acota un plano: se tira el trazo, aparece
   la medida, se tira el siguiente trazo. */

.revelar-trazo .cota-linea__trazo {
  clip-path: inset(0 100% 0 0);
  transition: clip-path 720ms var(--ease-cortina) var(--trazo-retraso, 0ms);
}
.revelar-trazo[data-visible='true'] .cota-linea__trazo { clip-path: inset(0 0 0 0); }

.revelar-trazo .cota {
  opacity: 0;
  transition: opacity 300ms var(--ease-out) var(--trazo-retraso, 0ms);
}
.revelar-trazo[data-visible='true'] .cota { opacity: 1; }

.revelar-trazo > :nth-child(1) { --trazo-retraso: 0ms; }
.revelar-trazo > :nth-child(2) { --trazo-retraso: 170ms; }
.revelar-trazo > :nth-child(3) { --trazo-retraso: 270ms; }
.revelar-trazo > :nth-child(4) { --trazo-retraso: 430ms; }
.revelar-trazo > :nth-child(5) { --trazo-retraso: 530ms; }
.revelar-trazo > :nth-child(6) { --trazo-retraso: 690ms; }
.revelar-trazo > :nth-child(7) { --trazo-retraso: 790ms; }

/* Escalonado dentro de un grupo. 45 ms: por debajo no se percibe como
   secuencia y por encima el último elemento llega tarde. */
.escalonar > *:nth-child(1) { --revelar-retraso: 0ms; }
.escalonar > *:nth-child(2) { --revelar-retraso: 45ms; }
.escalonar > *:nth-child(3) { --revelar-retraso: 90ms; }
.escalonar > *:nth-child(4) { --revelar-retraso: 135ms; }
.escalonar > *:nth-child(5) { --revelar-retraso: 180ms; }
.escalonar > *:nth-child(6) { --revelar-retraso: 225ms; }

/* ====================================================== LA PORTADA
   El único momento compuesto del sitio, y sucede una sola vez.

   La fotografía asienta desde 1.055 y, a la vez, pasa de un desenfoque
   de 12 px a nítida. El desenfoque hace dos trabajos: da la sensación de
   un plano que entra en foco, y cubre el primer instante —el más
   visible— del reescalado de una imagen de origen limitado.
   ================================================================== */

.portada__medio img {
  transform: scale(1.055);
  filter: blur(12px) saturate(1.2);
  transition:
    transform 2200ms var(--ease-out),
    filter 1500ms var(--ease-out);
}

[data-portada-lista='true'] .portada__medio img {
  transform: scale(1);
  filter: blur(0) saturate(1);
}

/* El titular se descubre línea a línea. Cada línea sube desde debajo de
   su propia caja, así que ninguna aparece de la nada. */
.linea-cortina {
  display: block;
  overflow: hidden;
  /* Sitio para las tildes y los descendentes: sin esto el recorte come
     la Ó de OPERACIÓN. */
  padding-block: 0.06em;
  margin-block: -0.06em;
}

.linea-cortina > span {
  display: block;
  transform: translate3d(0, 106%, 0);
  transition: transform 1050ms var(--ease-cortina) var(--cortina-retraso, 0ms);
}

[data-portada-lista='true'] .linea-cortina > span { transform: translate3d(0, 0, 0); }

.portada__entrada {
  opacity: 0;
  transform: translate3d(0, 14px, 0) scale(0.985);
  transform-origin: left center;
  transition:
    opacity 620ms var(--ease-out) var(--cortina-retraso, 0ms),
    transform 760ms var(--ease-out) var(--cortina-retraso, 0ms);
}
[data-portada-lista='true'] .portada__entrada {
  opacity: 1;
  transform: translate3d(0, 0, 0) scale(1);
}

/* La cota se traza de izquierda a derecha, como se acota un plano. */
.portada__cota {
  clip-path: inset(0 100% 0 0);
  transition: clip-path 1300ms var(--ease-cortina) 700ms;
}
[data-portada-lista='true'] .portada__cota { clip-path: inset(0 0 0 0); }

/* ============================================== CRUCE AL FILTRAR OBRAS
   Al cambiar de filtro la rejilla se reorganiza de golpe. Un fundido
   corto con un desenfoque mínimo convierte los dos estados en una sola
   transformación en lugar de dos conjuntos que se sustituyen. */

.galeria__rejilla {
  transition: opacity 190ms var(--ease-out), filter 190ms var(--ease-out);
}
.galeria__rejilla[data-cambiando='true'] {
  opacity: 0.25;
  filter: blur(3px);
}

/* ====================================================== AVISO DEL FORMULARIO */

.aviso[data-visible='true'] {
  animation: aviso-entra 320ms var(--ease-out) both;
}
@keyframes aviso-entra {
  from { opacity: 0; transform: translate3d(0, 8px, 0); }
  to   { opacity: 1; transform: none; }
}

/* ====================================================== MOVIMIENTO REDUCIDO
   No es «cero animación». Se conservan el color y la opacidad, que
   ayudan a entender qué cambió, y se retira todo desplazamiento,
   desenfoque y recorte. */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .revelar,
  .revelar[data-visible='true'],
  .revelar-titulo,
  .revelar-titulo[data-visible='true'],
  .revelar-trazo .cota-linea__trazo,
  .revelar-trazo .cota {
    opacity: 1;
    transform: none;
    clip-path: none;
    -webkit-mask-image: none;
    mask-image: none;
    transition: none;
  }

  .linea-cortina > span,
  .portada__entrada,
  .portada__cota {
    transform: none;
    opacity: 1;
    clip-path: none;
    transition: none;
  }

  .portada__medio img { transform: none; filter: none; transition: none; }

  .galeria__rejilla[data-cambiando='true'] { opacity: 1; filter: none; }

  .panel-movil { transition: visibility 0s; }
  .panel-movil__enlace { opacity: 1; transform: none; transition: color 0.01ms; }

  .aviso[data-visible='true'] { animation: none; }

  /* La respuesta al presionar y los cambios de color se quedan: informan
     de que el sistema recibió la acción. */
  .boton { transition: background-color 120ms linear, color 120ms linear; }
  .boton:active { transform: none; background-color: var(--naranja-600); }
  .filtro__boton:active { transform: none; }
}
