/* ═══════════ Paleta: beige + verde laurel (sin blanco puro) ═══════════ */
:root {
  --crema: #f2ead7;
  --beige: #e6d9bd;
  --beige-osc: #d3c2a0;
  --laurel: #6b7f5e;
  --laurel-osc: #48573f;
  --laurel-claro: #a8b59a;
  --tinta: #3d4237;
  --tinta-suave: #6d7264;
  /* usadas por el hilo dorado, la enredadera y el rosario; los temas las pisan */
  --oliva: #8a9a70;
  --oliva-osc: #6b7f5e;
  --oro: #d9b544;
  --oro-claro: #f0d99a;
  --cordon: #a8896a;
  --cuenta: #8fa9bd;
  --serif: 'Cormorant Garamond', serif;
  --script: 'Great Vibes', cursive;
  --sans: 'Jost', sans-serif;
  /* textura de papel vintage arrugado, generada con filtro SVG (no pesa nada) */
  --textura: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='420' height='420'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.013' numOctaves='5'/%3E%3CfeDiffuseLighting lighting-color='white' surfaceScale='1.7'%3E%3CfeDistantLight azimuth='45' elevation='62'/%3E%3C/feDiffuseLighting%3E%3C/filter%3E%3Crect width='420' height='420' filter='url(%23p)'/%3E%3C/svg%3E");
  /* Relieve del sobre: papel con grabado floral. La imagen se pasó a gris centrado
     en el tono medio, para que al mezclarla con `soft-light` ilumine las crestas y
     oscurezca los surcos; por eso el motivo se ve prensado en el papel y no pegado
     encima. Se puede cambiar por tema. */
  --textura-sobre: url('../assets/textura-sobre.jpg');
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  font-family: var(--sans);
  background-color: var(--crema);
  background-image: var(--textura);
  background-blend-mode: multiply;
  color: var(--tinta);
  overflow-x: hidden;
  position: relative;
}

/* ═══════════ Hilo dorado que se dibuja al scrollear ═══════════ */
.hilo {
  position: absolute;
  top: 0;
  left: 4px;
  z-index: 60;
  pointer-events: none;
  /* el trazo se redibuja en cada cuadro al scrollear: aislado en su capa,
     el repintado se queda en su franja de 70px y no toca el resto */
  will-change: transform;
}
.hilo path {
  fill: none;
  stroke-width: 2.2;
  stroke-linecap: round;
  opacity: .65;
}
.hilo circle {
  transition: opacity .6s ease;
  filter: drop-shadow(0 0 4px rgba(217, 181, 68, .8));
}

/* ═══════════ Portada (sobre) ═══════════ */
.portada {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2.2rem;
  padding: 1.5rem;
  background:
    var(--textura),
    radial-gradient(circle at 20% 15%, rgba(168, 181, 154, .35), transparent 45%),
    radial-gradient(circle at 85% 80%, rgba(221, 207, 180, .5), transparent 50%),
    var(--beige);
  background-blend-mode: multiply, normal, normal, normal;
  transition: opacity 1s ease, visibility 1s;
  perspective: 1200px;
}
.portada--abierta { opacity: 0; visibility: hidden; }

/* ── El sobre ── */
.sobre {
  position: relative;
  width: min(88vw, 400px);
  aspect-ratio: 10 / 7;
  cursor: pointer;
  animation: aparecer 1.2s ease both;
  filter: drop-shadow(0 18px 30px rgba(61, 66, 55, .3));
}

/* parte trasera (fondo del sobre) */
/* El relieve va sin repetir, para que no se vean costuras, y cada pieza toma un
   recorte distinto del patrón: la solapa y el bolsillo son hojas separadas y el
   grabado no debe continuar a través del doblez. */
.sobre__atras {
  position: absolute;
  inset: 0;
  background-color: var(--laurel-osc);
  background-image: var(--textura-sobre);
  background-size: 100% auto;
  background-position: 30% 40%;
  background-repeat: no-repeat;
  background-blend-mode: soft-light;
  border-radius: 10px;
}

/* carta que sale al abrir */
.sobre__carta {
  position: absolute;
  left: 12px;
  right: 12px;
  top: 12px;
  bottom: 12px;
  z-index: 1;
  background-color: var(--crema);
  background-image: var(--textura);
  background-blend-mode: multiply;
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 1rem;
  transition: transform .9s cubic-bezier(.2, .7, .3, 1) .55s;
}
.sobre--abierto .sobre__carta { transform: translateY(-82%) scale(1.04); }

/* frente del sobre (bolsillo en V) */
/* La textura de papel va encima del degradado con `multiply`: la trama oscurece
   de forma irregular y el sobre deja de verse como un plano de color liso.
   El barrido diagonal claro simula la luz cayendo sobre una hoja doblada. */
.sobre__bolsillo {
  position: absolute;
  inset: 0;
  z-index: 2;
  background-image:
    var(--textura-sobre),
    linear-gradient(170deg, var(--laurel), var(--laurel-osc));
  background-size: 150% auto, auto;
  background-position: 18% 62%, 0 0;
  background-repeat: no-repeat, repeat;
  background-blend-mode: soft-light, normal;
  clip-path: polygon(0 0, 50% 52%, 100% 0, 100% 100%, 0 100%);
  border-radius: 10px;
  /* El recorte en V es un corte seco: sin esto el filo del bolsillo no tiene
     grosor. `drop-shadow` sigue la forma recortada, así que una línea clara
     justo encima del filo lo convierte en un canto de papel iluminado. */
  filter: drop-shadow(0 -1px 0 rgba(255, 255, 255, .22));
}
/* canto inferior y laterales: el papel es más grueso en los dobleces */
.sobre__bolsillo::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 10px;
  box-shadow:
    inset 0 -2px 5px rgba(30, 38, 26, .3),
    inset 2px 0 4px rgba(30, 38, 26, .16),
    inset -2px 0 4px rgba(30, 38, 26, .16),
    inset 0 1px 0 rgba(255, 255, 255, .12);
  pointer-events: none;
}

/* destinatario escrito al frente */
.sobre__para {
  position: absolute;
  bottom: 13%;
  left: 0;
  width: 100%;
  z-index: 3;
  text-align: center;
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.15rem;
  color: var(--crema);
  pointer-events: none;
}

/* solapa que se abre */
.sobre__tapa {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 54%;
  z-index: 4;
  /* El color de fondo asoma como un filo de un par de píxeles alrededor del
     triángulo: ese es el canto del papel. La cara de la solapa va en ::before,
     recortada un poco más adentro. Se hace así porque `clip-path` recorta también
     las sombras del elemento, así que un `drop-shadow` en el filo se cortaría
     justo donde tiene que verse. */
  background-color: var(--laurel-claro);
  /* el canto se apaga hacia la punta: ahí la luz ya no le pega de frente */
  background-image: linear-gradient(178deg, rgba(255, 255, 255, .12), rgba(30, 38, 26, .3));
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  border-radius: 10px 10px 0 0;
  transform-origin: top center;
  transition: transform .65s ease;
}
/* la cara de la solapa: mismo relieve que el bolsillo, en otra parte del patrón */
.sobre__tapa::before {
  content: '';
  position: absolute;
  inset: 0;
  /* arriba va al ras: ese lado es el doblez del papel, no un corte, y no debe
     tener filo. El canto sólo se ve en las dos diagonales. */
  clip-path: polygon(0.9% 0, 99.1% 0, 50% 96%);
  background-image:
    var(--textura-sobre),
    linear-gradient(180deg, var(--laurel-osc), var(--laurel));
  background-size: 150% auto, auto;
  background-position: 74% 12%, 0 0;
  background-repeat: no-repeat, repeat;
  background-blend-mode: soft-light, normal;
  border-radius: 10px 10px 0 0;
}
/* sombra suave donde la solapa cae sobre el bolsillo: le da grosor al papel */
.sobre__tapa::after {
  content: '';
  position: absolute;
  inset: 0;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  background: linear-gradient(180deg, rgba(30, 38, 26, 0) 55%, rgba(30, 38, 26, .28));
  pointer-events: none;
}
.sobre--abierto .sobre__tapa { transform: rotateX(180deg); }
/* cuando la solapa terminó de girar, pasa detrás de la carta */
.sobre--tapa-atras .sobre__tapa { z-index: 0; }

/* sello de cera dorado (imagen real con fondo transparente) */
.sobre__sello {
  position: absolute;
  top: calc(54% - 44px);
  left: 50%;
  z-index: 5;
  transform: translateX(-50%);
  width: 88px;
  height: auto;
  filter: drop-shadow(0 5px 8px rgba(0, 0, 0, .35));
  transition: opacity .4s ease;
}
.sobre--abierto .sobre__sello { opacity: 0; }

/* textos dentro de la carta */
.portada__mini {
  text-transform: uppercase;
  letter-spacing: .45em;
  font-size: .68rem;
  color: var(--laurel-osc);
  margin-bottom: .8rem;
}
.portada__nombres {
  font-family: var(--script);
  font-weight: 400;
  font-size: clamp(2.2rem, 9vw, 3rem);
  color: var(--laurel-osc);
  line-height: 1.15;
}
.portada__nombres span { color: var(--laurel); }
.portada__fecha {
  font-family: var(--serif);
  font-size: 1.15rem;
  letter-spacing: .35em;
  margin-top: .8rem;
  color: var(--tinta-suave);
}

/* instrucción bajo el sobre */
.portada__instruccion {
  font-size: .85rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--laurel-osc);
  animation: latido 2.2s ease-in-out infinite;
}
.portada--abierta .portada__instruccion,
.sobre--abierto ~ .portada__instruccion { opacity: 0; transition: opacity .5s; }

@keyframes latido {
  0%, 100% { opacity: .55; }
  50% { opacity: 1; }
}

/* ═══════════ Botones ═══════════ */
.btn {
  display: inline-block;
  font-family: var(--sans);
  font-size: .95rem;
  letter-spacing: .12em;
  text-decoration: none;
  border: none;
  cursor: pointer;
  padding: .85rem 2.1rem;
  border-radius: 999px;
  transition: transform .25s ease, box-shadow .25s ease;
}
.btn:hover { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(72, 87, 63, .25); }
.btn--principal { background: var(--laurel-osc); color: var(--crema); }
.btn--secundario { background: transparent; color: var(--laurel-osc); border: 1px solid var(--laurel-osc); }

.botones {
  display: flex;
  gap: .9rem;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 1.5rem;
}

/* ═══════════ Estructura ═══════════ */
.contenido { opacity: 0; transition: opacity 1.2s ease .3s; }
.contenido--visible { opacity: 1; }

.seccion {
  padding: 4.5rem 1.5rem;
  text-align: center;
  max-width: 100%;
}
.seccion--beige {
  background-color: var(--beige);
  background-image: var(--textura);
  background-blend-mode: multiply;
}
.seccion--verde {
  background-image: var(--textura), linear-gradient(160deg, var(--laurel-osc), var(--laurel));
  background-blend-mode: multiply, normal;
  color: var(--crema);
}
/* Secciones con fotografía de fondo, con un velo encima para que el texto respire.
   La foto y el velo se pueden cambiar desde el tema (`temas.colores` puede traer
   `foto-lago`, `foto-bosque` y `velo`); si el tema no los trae, quedan los de aquí,
   que son los de Fer y Pedro. */
.seccion--foto-lago,
.seccion--foto-bosque {
  color: var(--crema);
  background:
    linear-gradient(var(--velo, rgba(61, 73, 52, .82)), var(--velo, rgba(61, 73, 52, .82))),
    var(--foto) center / cover no-repeat;
}
.seccion--foto-lago { --foto: var(--foto-lago, url('https://images.unsplash.com/photo-1439066615861-d1af74d74000?w=1600&q=70')); }
.seccion--foto-bosque { --foto: var(--foto-bosque, url('https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=1600&q=70')); }
.seccion--verde .titulo,
.seccion--foto-lago .titulo,
.seccion--foto-bosque .titulo { color: var(--crema); }
.seccion--verde .titulo::after,
.seccion--foto-lago .titulo::after,
.seccion--foto-bosque .titulo::after { background: var(--beige-osc); }
.seccion--verde .texto,
.seccion--foto-lago .texto,
.seccion--foto-bosque .texto { color: #e9e4d5; }

/* "El gran día" con las fotos de la sesión pasando de fondo (iniciarGranDia).
   La capa vive debajo del contenido y no recibe toques; el velo es el mismo
   lenguaje de las secciones con foto, un pelo más abierto para que se vean. */
.seccion--grandia { position: relative; overflow: hidden; }
/* el fondo oscuro es lo que se ve mientras bajan las fotos: verde hondo, no gris */
.grandia-fotos {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  background: var(--laurel-osc, #3d4934);
}
/* la cinta desfila de corrido: dos copias de la secuencia y un viaje a -50%
   hacen el bucle sin costura. La mueve el compositor (transform), no cuesta.
   No se detiene con "reducir movimiento" a propósito: a este paso (una vuelta
   en 3 minutos) es una deriva, y congelada parecía descompuesta (pasó en iPhone). */
.grandia-cinta {
  display: flex;
  height: 100%;
  width: max-content;
  animation: grandia-desfile 180s linear infinite;
}
.grandia-tramo {
  position: relative;
  flex: none;
  height: 100%;
  margin: 0;
}
.grandia-tramo img {
  display: block;
  height: 100%;
  width: auto;
}
/* la unión entre fotos se funde con un degradado suave, sin máscaras CSS
   (en el Safari del iPhone las máscaras animadas fallan al dibujarse) */
.grandia-tramo::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 84px;
  z-index: 1;
  background: linear-gradient(to right, rgba(45, 55, 40, .6), transparent);
}
@keyframes grandia-desfile {
  to { transform: translateX(-50%); }
}
.grandia-fotos::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--velo-grandia, rgba(61, 73, 52, .38));
}
.seccion--grandia > :not(.grandia-fotos) { position: relative; z-index: 1; }
/* con foto detrás, el texto pasa a crema y la tarjeta se vuelve vidrio: se ve
   la foto a través de ella sin sacrificar la lectura */
.seccion--grandia:has(.grandia-fotos) .titulo,
.seccion--grandia:has(.grandia-fotos) .evento h3,
.seccion--grandia:has(.grandia-fotos) .evento__hora,
.seccion--grandia:has(.grandia-fotos) .evento__icono { color: var(--crema); }
.seccion--grandia:has(.grandia-fotos) .titulo::after { background: var(--beige-osc); }
.seccion--grandia:has(.grandia-fotos) .texto { color: #ede8d9; }
.seccion--grandia:has(.grandia-fotos) .texto--suave { color: #dcd6c3; }
/* la tarjeta lleva la cajita de resaltado del contador: vidrio claro con
   borde, para que el texto no se pierda sobre las fotos */
.seccion--grandia:has(.grandia-fotos) .evento {
  background: rgba(250, 246, 238, .16);
  border: 1px solid rgba(233, 228, 213, .4);
  box-shadow: none;
}
.seccion--grandia:has(.grandia-fotos) .titulo,
.seccion--grandia:has(.grandia-fotos) .evento h3,
.seccion--grandia:has(.grandia-fotos) .evento__hora,
.seccion--grandia:has(.grandia-fotos) .texto,
.seccion--grandia:has(.grandia-fotos) .texto--suave {
  text-shadow: 0 1px 4px rgba(24, 28, 18, .9), 0 0 14px rgba(24, 28, 18, .55);
}
@media (prefers-reduced-motion: reduce) {
  .grandia-fotos img { transition: none; }
}

.titulo {
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(1.7rem, 6vw, 2.3rem);
  color: var(--laurel-osc);
  margin-bottom: 1.6rem;
}
.titulo::after {
  content: '';
  display: block;
  width: 70px;
  height: 1px;
  background: var(--laurel);
  margin: .8rem auto 0;
}

.texto {
  font-weight: 300;
  font-size: 1.05rem;
  line-height: 1.8;
  max-width: 520px;
  margin: 0 auto;
  color: var(--tinta-suave);
}
.texto--suave { font-size: .9rem; opacity: .8; margin-top: .8rem; }
.texto em { font-size: .85rem; }

/* ═══════════ Hero ═══════════ */
.hero { padding-top: 6rem; padding-bottom: 5.5rem; }
/* Sin fecha ni lugar (viven en la cuenta regresiva y en "¿Cómo llegar?"),
   lo que queda respira y crece. */
.hero__mini {
  text-transform: uppercase;
  letter-spacing: .5em;
  font-size: .95rem;
  color: var(--laurel);
  margin-bottom: 1.4rem;
}
.hero__nombres {
  font-family: var(--script);
  font-weight: 400;
  font-size: clamp(3.8rem, 16vw, 6.5rem);
  color: var(--laurel-osc);
  line-height: 1.1;
}
.hero__nombres .amp { color: var(--laurel-claro); }
.hero__linea {
  width: 110px;
  height: 1px;
  background: var(--laurel);
  margin: 2rem auto;
}
.hero__invitado {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.5rem;
  color: var(--laurel);
  margin-top: 1.8rem;
}
/* la fecha, ahora al pie del contador */
.countdown__fecha {
  font-family: var(--serif);
  font-size: 1.35rem;
  letter-spacing: .1em;
  color: var(--crema);
  margin-top: 1.4rem;
}
.hero__personas {
  display: inline-block;
  margin-top: .35rem;
  color: var(--tinta-suave);
  letter-spacing: .04em;
}

/* ═══════════ Cuenta regresiva ═══════════ */
.countdown {
  display: flex;
  justify-content: center;
  gap: .8rem;
  flex-wrap: wrap;
  margin-bottom: 1.4rem;
}
.countdown__caja {
  background: rgba(250, 246, 238, .12);
  border: 1px solid rgba(233, 228, 213, .4);
  border-radius: 12px;
  padding: 1rem .5rem;
  min-width: 74px;
}
.countdown__caja span {
  display: block;
  font-family: var(--serif);
  font-size: 2.1rem;
  font-weight: 600;
}
.countdown__caja small {
  text-transform: uppercase;
  letter-spacing: .2em;
  font-size: .65rem;
  opacity: .85;
}

/* ═══════════ Historia ═══════════ */
.historia { max-width: 560px; margin: 0 auto; }
/* la foto se ve COMPLETA: sin recorte, solo esquinas suavizadas */
.historia__foto {
  width: 100%;
  max-width: 620px;
  height: auto;
  border-radius: 18px;
  border: 6px solid var(--beige);
  box-shadow: 0 12px 30px rgba(61, 66, 55, .18);
  margin-bottom: 1.8rem;
}
/* El video va sin filtros ni velo encima: se ve tal cual. Se topa en 360 px porque
   el archivo mide 352 px de ancho — a ese tamaño se ve nítido, y estirarlo más sólo
   lo emborronaría. Mismo marco que la foto para que combine con el resto. */
.historia__video {
  display: block;
  width: 100%;
  max-width: 360px;
  /* La proporción va escrita a mano (el archivo mide 704×1280, que es la misma
     proporción 11:20). Sin esto, en Safari de iPhone el hueco se queda sin altura
     hasta que el video termina de cargar, y el invitado no ve nada. Con la
     proporción fija, el espacio existe desde el primer momento y el poster se
     pinta ahí. Si algún día cambia el video, revisa que la proporción coincida. */
  aspect-ratio: 352 / 640;
  height: auto;
  object-fit: cover;
  /* No es interactivo: no se toca, no se pausa, no saca controles. Es parte del
     decorado de la sección, como una foto que se mueve. */
  pointer-events: none;
  margin: 0 auto 1.8rem;
  border-radius: 18px;
  border: 6px solid var(--beige);
  box-shadow: 0 12px 30px rgba(61, 66, 55, .18);
  background: var(--beige);
}

/* ═══════════ Ubicación: foto del lugar con la tarjeta encima ═══════════ */
.lugar {
  max-width: 560px;
  margin: 0 auto;
}
.lugar__foto {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 18px;
  border: 6px solid var(--beige);
  box-shadow: 0 14px 34px rgba(30, 38, 26, .35);
}
/* la tarjeta monta sobre la foto, como una nota puesta encima */
.lugar__tarjeta {
  position: relative;
  z-index: 2;
  width: min(100%, 26rem);
  margin: -3.2rem auto 0;
  padding: 1.6rem 1.4rem 1.5rem;
  background-color: var(--crema);
  background-image: var(--textura);
  background-blend-mode: multiply;
  border-radius: 14px;
  box-shadow: 0 12px 28px rgba(30, 38, 26, .32);
}
.lugar__rotulo {
  font-family: var(--script);
  font-size: 1.7rem;
  line-height: 1;
  color: var(--laurel);
  margin-bottom: .5rem;
}
.lugar__nombre {
  font-family: var(--serif);
  font-size: 1.35rem;
  font-weight: 500;
  color: var(--laurel-osc);
  margin-bottom: .5rem;
}
.lugar__direccion {
  font-size: .85rem;
  line-height: 1.7;
  color: var(--tinta-suave);
  margin-bottom: 1.2rem;
}
.lugar__botones {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  justify-content: center;
}
.lugar__botones .btn {
  flex: 1 1 9rem;
  padding: .72rem 1rem;
  font-size: .88rem;
}

@media (max-width: 430px) {
  .lugar__tarjeta { margin-top: -2.4rem; padding: 1.3rem 1.1rem 1.3rem; }
  .lugar__botones .btn { flex: 1 1 100%; }
}

/* ═══════════ Padres ═══════════ */
.padres__rol {
  text-transform: uppercase;
  letter-spacing: .3em;
  font-size: .75rem;
  color: var(--laurel);
  margin-bottom: 1rem;
}
.padres__nombre {
  font-family: var(--serif);
  font-size: 1.45rem;
  color: var(--tinta);
  line-height: 1.7;
}
.padres__nota {
  font-family: var(--serif);
  font-style: italic;
  font-size: .95rem;
  color: var(--tinta-suave);
  margin-bottom: .6rem;
}
.padres + .padres { margin-top: 2.2rem; }

/* Familias: textos a la izquierda, foto de niños a la derecha */
.padres-layout {
  display: grid;
  gap: 1.5rem;
  align-items: center;
  max-width: 900px;
  margin: 0 auto;
}
@media (min-width: 760px) {
  .padres-layout { grid-template-columns: 1.1fr .9fr; gap: 2.5rem; }
  .padres-layout__texto { text-align: right; }
}
/* La foto viene recortada, sin fondo, así que va completa y sin máscara: no hay
   rectángulo que disimular. La proporción va escrita para que reserve su espacio
   antes de cargar (si no, en Safari el hueco se queda sin altura). La sombra sigue
   la silueta —no la caja— y hace que se vean apoyados sobre el papel. */
.padres-layout__foto {
  width: 100%;
  max-width: 340px;
  justify-self: center;
  aspect-ratio: 700 / 874;
  height: auto;
  object-fit: contain;
  filter: drop-shadow(0 12px 14px rgba(61, 66, 55, .28));
}
.cruz { color: var(--laurel); font-size: 1.1rem; }

/* ═══════════ Evento ═══════════ */
.evento {
  max-width: 480px;
  margin: 0 auto;
  background: var(--beige);
  border-radius: 18px;
  padding: 2.4rem 1.8rem;
  box-shadow: 0 10px 26px rgba(61, 66, 55, .1);
}
.evento__icono { font-size: 2.2rem; margin-bottom: .8rem; }
/* segundo acto del día (ceremonia tras la recepción): un respiro entre ambos */
.evento__acto { margin-top: 1.2rem; }
.evento h3 {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 1.5rem;
  color: var(--laurel-osc);
}
.evento__hora {
  font-family: var(--serif);
  font-size: 2rem;
  color: var(--laurel);
  margin: .5rem 0 .9rem;
}

/* ═══════════ Dress code ═══════════ */
.dresscode__sub {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.2rem;
  color: var(--laurel);
  margin: -0.8rem 0 1.2rem;
}
.paleta {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1.2rem 1.4rem;
  margin-top: 1.6rem;
  max-width: 560px;
  margin-left: auto;
  margin-right: auto;
}
.paleta__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .45rem;
  width: 105px;
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--tinta-suave);
  text-align: center;
}
.paleta__item i {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--c);
  border: 2px solid var(--beige-osc);
  box-shadow: inset 0 -6px 12px rgba(0, 0, 0, .08);
}
.dresscode__detalles {
  max-width: 480px;
  margin: 1.8rem auto 0;
  background: var(--beige);
  border-radius: 16px;
  padding: 1.4rem 1.6rem;
  text-align: left;
}
.dresscode__detalles p {
  font-weight: 300;
  font-size: .95rem;
  line-height: 1.6;
  color: var(--tinta);
  margin: .4rem 0;
}
.dresscode__img {
  width: 100%;
  max-width: 460px;
  margin-top: 1.8rem;
  border-radius: 16px;
  box-shadow: 0 12px 30px rgba(61, 66, 55, .18);
}

/* ═══════════ Galería compartida ═══════════ */
.btn:disabled { opacity: .5; cursor: not-allowed; transform: none; box-shadow: none; }

.galeria-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(105px, 1fr));
  gap: .5rem;
  max-width: 720px;
  margin: 1.6rem auto 0;
}
/* display:grid le gana al atributo hidden del navegador; sin esto no se cierra */
.galeria-grid[hidden] { display: none; }
.galeria-grid img,
.galeria-grid video {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 10px;
  cursor: pointer;
  transition: transform .25s ease;
}
.galeria-grid img:hover { transform: scale(1.04); }
.galeria-grid video:hover { transform: scale(1.04); }
.galeria-item { position: relative; min-width: 0; }
.galeria-item > img, .galeria-item > video { display: block; }
.galeria-item > img, .galeria-item > video { touch-action: manipulation; }
.galeria-video {
  width: 100%; aspect-ratio: 1; border: 0; border-radius: 10px;
  background: linear-gradient(145deg, var(--laurel-osc), var(--laurel)); color: var(--crema);
  display: grid; place-content: center; gap: .35rem; cursor: pointer; touch-action: manipulation;
}
.galeria-video__miniatura { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 10px; cursor: pointer; display: block; }
.galeria-video__insignia { position: absolute; left: .55rem; bottom: .55rem; width: 2.25rem; height: 2.25rem; display: grid; place-content: center; padding-left: .1rem; border-radius: 50%; color: #fff; background: rgba(35,45,31,.82); border: 1px solid rgba(255,255,255,.85); pointer-events: none; box-shadow: 0 2px 8px rgba(0,0,0,.25); }
.galeria-video__play { width: 2.5rem; height: 2.5rem; border: 1px solid rgba(255,255,255,.8); border-radius: 50%; display: grid; place-content: center; padding-left: .12rem; }
.galeria-video__texto { font: 600 .7rem var(--sans); letter-spacing: .04em; }
.galeria-item--seleccionada > img, .galeria-item--seleccionada > video { outline: 4px solid var(--oro); outline-offset: 2px; }
.galeria-item__marca {
  position: absolute; top: .35rem; right: .35rem; width: 2rem; height: 2rem;
  border: 0; border-radius: 50%; background: rgba(255,255,255,.94); color: var(--laurel-osc);
  font-size: 1.35rem; line-height: 1; padding: 0; box-shadow: 0 2px 8px rgba(0,0,0,.2);
}
.galeria-pestanas { display: flex; justify-content: center; gap: .35rem; flex-wrap: nowrap; margin: .7rem 0 .35rem; }
.galeria-pestanas .btn { flex: 1 1 0; padding: .46rem .45rem; font-size: .72rem; letter-spacing: .03em; white-space: nowrap; }
.galeria-pestana--activa { background: var(--laurel-osc) !important; color: white !important; }
.galeria-acciones { flex-wrap: nowrap; gap: .35rem; margin-top: .9rem; }
.galeria-acciones .btn { flex: 1 1 0; min-width: 0; padding: .62rem .2rem; font-size: clamp(.65rem, 3vw, .78rem); letter-spacing: 0; white-space: nowrap; }
.galeria-descargar { display: block; width: min(100%, 22rem); margin: .55rem auto 0; padding: .62rem .8rem; font-size: .78rem; letter-spacing: .04em; }

/* Visor contenido: mantiene visible el contexto de la galería en teléfono. */
.visor {
  position: fixed;
  inset: 0;
  z-index: 120;
  background: rgba(30, 34, 26, .42);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
.visor__panel {
  width: min(100%, 680px);
  max-height: min(76vh, 680px);
  overflow: hidden;
  border-radius: 16px;
  background: var(--crema);
  box-shadow: 0 18px 50px rgba(24, 28, 18, .42);
}
.visor__barra, .visor__pie { display: flex; align-items: center; padding: .55rem .7rem; }
.visor__barra { justify-content: flex-start; border-bottom: 1px solid rgba(61, 66, 55, .14); }
.visor__pie { justify-content: flex-end; border-top: 1px solid rgba(61, 66, 55, .14); }
.visor__volver {
  border: 0;
  padding: .5rem .35rem;
  color: var(--laurel-osc);
  background: transparent;
  font: 700 .8rem var(--sans);
  letter-spacing: .01em;
  cursor: pointer;
}
.visor__medio { display: block; width: 100%; max-height: min(61vh, 570px); object-fit: contain; background: #20231e; }
.visor__medio:not(.visor__video) { background: var(--beige); }
.visor__video { aspect-ratio: 16 / 9; }
.visor__volver:focus-visible, .visor__descargar:focus-visible { outline: 3px solid var(--oro); outline-offset: 2px; }
.visor__descargar {
  position: static;
  border: 0; border-radius: 999px; padding: .56rem .78rem;
  background: var(--oro); color: var(--tinta); font: 700 .73rem var(--sans);
  box-shadow: 0 2px 8px rgba(0,0,0,.16); cursor: pointer;
}
.visor__flecha {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.7rem;
  line-height: 1;
  color: var(--crema);
  background: rgba(24, 28, 18, .45);
  border: none;
  border-radius: 50%;
  cursor: pointer;
}
.visor__flecha--ant { left: .8rem; }
.visor__flecha--sig { right: .8rem; }
.visor__contador {
  position: absolute;
  bottom: 1rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  margin: 0;
  color: var(--crema);
  font-size: .85rem;
  letter-spacing: .06em;
  text-shadow: 0 1px 4px rgba(24, 28, 18, .9);
}
/* en celular se pasa deslizando; las flechas sólo estorbarían sobre la foto */
@media (max-width: 759px) {
  .visor__flecha { display: none; }
}
.galeria-cerrar { margin-top: 1rem; }
/* el display de .btn también le gana al atributo hidden */
.galeria-cerrar[hidden] { display: none; }

/* mapa incrustado bajo demanda (lo despliega el botón "Ver mapa") */
.mapa-caja { max-width: 720px; margin: 1.2rem auto 0; }
.mapa-caja[hidden] { display: none; }
.mapa-caja__marco {
  display: block;
  width: 100%;
  height: 340px;
  border: 0;
  border-radius: 14px;
  box-shadow: 0 10px 26px rgba(24, 28, 18, .25);
  background: var(--beige);
}
.mapa-caja__app {
  display: inline-block;
  margin-top: .55rem;
  font-size: .85rem;
  color: #e9e4d5;
}

/* ═══════════ QR ═══════════ */
.qr {
  width: 190px;
  height: 190px;
  margin-top: 1.6rem;
  border: 10px solid var(--beige);
  border-radius: 14px;
  box-shadow: 0 10px 26px rgba(61, 66, 55, .15);
}

/* ═══════════ Palomear quién asiste ═══════════ */
.rsvp-personas {
  max-width: 440px;
  margin: 1.6rem auto 0;
}
.rsvp-personas__titulo {
  font-family: var(--serif);
  font-size: 1.15rem;
  color: #f4efdf;
  margin-bottom: .8rem;
}
.rsvp-personas__lista {
  display: flex;
  flex-direction: column;
  gap: .5rem;
}
.rsvp-persona {
  display: flex;
  align-items: center;
  gap: .7rem;
  background: rgba(242, 234, 215, .14);
  border: 1px solid rgba(242, 234, 215, .35);
  border-radius: 12px;
  padding: .7rem .9rem;
  cursor: pointer;
  transition: background .25s ease, opacity .25s ease;
}
.rsvp-persona input { width: 20px; height: 20px; accent-color: var(--laurel-claro); cursor: pointer; flex: none; }
.rsvp-persona span {
  font-family: var(--serif);
  font-size: 1.05rem;
  color: #f4efdf;
}
/* quien queda desmarcado se ve atenuado */
.rsvp-persona:has(input:not(:checked)) { opacity: .45; }
.rsvp-personas__nota {
  font-size: .78rem;
  letter-spacing: .06em;
  color: rgba(242, 234, 215, .75);
  margin-top: .6rem;
}

/* ═══════════ Mensajito para los novios ═══════════ */
.rsvp-mensaje {
  max-width: 440px;
  margin: 1.6rem auto 0;
}
.rsvp-mensaje textarea {
  width: 100%;
  border: 1px solid rgba(242, 234, 215, .45);
  border-radius: 14px;
  background: rgba(242, 234, 215, .14);
  color: #f4efdf;
  font-family: var(--serif);
  font-size: 1.05rem;
  padding: .9rem 1.1rem;
  resize: vertical;
  min-height: 90px;
  outline: none;
  transition: border-color .3s, background .3s;
}
.rsvp-mensaje textarea::placeholder { color: rgba(242, 234, 215, .65); font-style: italic; }
.rsvp-mensaje textarea:focus {
  border-color: rgba(242, 234, 215, .85);
  background: rgba(242, 234, 215, .2);
}
.rsvp-mensaje__nota {
  font-size: .78rem;
  letter-spacing: .06em;
  color: rgba(242, 234, 215, .75);
  margin-top: .5rem;
}
.mesa-asignada { max-width: 430px; margin: 1.2rem auto 0; padding: 1rem 1.15rem; border-radius: 14px; background: rgba(242,234,215,.92); color: var(--laurel-osc); text-align: center; box-shadow: 0 8px 20px rgba(24,28,18,.16); }
.mesa-asignada b { display: block; font: 600 1.55rem var(--serif); margin-top: .2rem; }

/* ═══════════ Footer ═══════════ */
.footer {
  background: var(--tinta);
  color: var(--beige);
  text-align: center;
  /* El botón de música flota fijo en la esquina inferior derecha (52px + 1.2rem
     de margen). Sin este colchón abajo se encima sobre la última línea del pie
     justo cuando la página llega al final, que es donde siempre termina. */
  padding: 3.5rem 1.5rem calc(52px + 2.6rem);
}
.footer__nombres {
  font-family: var(--script);
  font-size: 2.4rem;
}
.footer__nombres span { color: var(--laurel-claro); }
.footer__fecha { letter-spacing: .4em; margin: .6rem 0 1rem; font-size: .9rem; }
.footer__gracias { font-weight: 300; font-size: .9rem; opacity: .75; }

/* ═══════════ Música ═══════════ */
.btn-musica {
  position: fixed;
  bottom: 1.2rem;
  right: 1.2rem;
  z-index: 90;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: none;
  background: var(--laurel-osc);
  color: var(--crema);
  font-size: 1.3rem;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(61, 66, 55, .35);
}
.btn-musica--pausada { opacity: .55; }

/* ═══════════ Costuras entre secciones ═══════════ */
/* Elegido por Pedro (26 jul 2026): que ninguna sección termine en línea recta,
   porque el ojo lo lee como pantalla de cierre y la gente abandona ahí.
   La sección de ARRIBA se recorta con una máscara: su fondo real (color, foto
   o degradado) baja en ola y se mete en la siguiente. Por eso es máscara y no
   un parche de color encima: un parche no puede imitar una foto.
   El acomodo (solapar secciones y apilarlas) lo pone el JS en armarCosturas();
   si el JS no corre, no hay clase y todo se ve recto, como siempre. */
@supports (mask-repeat: no-repeat) or (-webkit-mask-repeat: no-repeat) {
  .seccion--ola {
    position: relative;
    margin-bottom: -48px;   /* la siguiente se mete bajo la ola */
    -webkit-mask-image:
      linear-gradient(#000, #000),
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 340 48' preserveAspectRatio='none'%3E%3Cpath d='M0 0H340V6C306 10 260 20 208 30 158 38 100 34 58 24 36 18 16 10 0 8Z'/%3E%3C/svg%3E");
    mask-image:
      linear-gradient(#000, #000),
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 340 48' preserveAspectRatio='none'%3E%3Cpath d='M0 0H340V6C306 10 260 20 208 30 158 38 100 34 58 24 36 18 16 10 0 8Z'/%3E%3C/svg%3E");
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: top, bottom;
    mask-position: top, bottom;
    /* 1px encimado entre las dos capas para que no quede un pelito de luz */
    -webkit-mask-size: 100% calc(100% - 47px), 100% 48px;
    mask-size: 100% calc(100% - 47px), 100% 48px;
  }
}

/* Las secciones "crema" no traen fondo propio: son transparentes y dejan ver el
   del body. Una máscara no puede recortar lo transparente, así que su ola no se
   veía. El JS les pone este fondo, idéntico al del body: nada cambia de color. */
.seccion--fondo-propio { background-color: var(--crema, #f2ead7); }

/* las hojas que cruzan la costura: quietas, sin animación, cero costo al scrollear */
.costura {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 0;
  pointer-events: none;
}
.costura__hoja { position: absolute; width: 22px; }
.costura__hoja svg { display: block; width: 100%; height: auto; overflow: visible; }
.costura__baya {
  position: absolute;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--oro, #b08d4f);
  opacity: .9;
}

/* ═══════════ Ruta de secciones ═══════════ */
/* Observado con una invitada real: se quiso salir dos veces, después de ver la
   fecha y después de ver el lugar. No era que no supiera deslizar — ya tenía lo
   que venía a buscar. Estas cuentas contestan "cuánto falta", y sobre todo
   dejan saltar a la sección que le interese en vez de cerrar la pestaña.
   Van del lado izquierdo, a la izquierda del hilo: el hilo serpentea entre x=22
   y x=48 de su propio lienzo (que empieza en left:4), así que a 10px no chocan. */
.ruta {
  position: fixed;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 84;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 11px;
  opacity: 0;
  visibility: hidden;
  transition: opacity .6s ease, visibility .6s;
}
.ruta--visible { opacity: 1; visibility: visible; }

/* La zona de toque es sólo la bolita con un colchón pequeño. El nombre vive en
   posición absoluta para que el botón no se ensanche invisible sobre el
   contenido: así un toque en una foto del borde izquierdo cae en la foto. */
.ruta__parada {
  appearance: none;
  border: none;
  background: none;
  padding: 6px;
  margin: -6px 0;
  cursor: pointer;
  position: relative;
  display: flex;
  align-items: center;
  font: inherit;
}
.ruta__parada:focus-visible { outline: 2px solid var(--oro, #d9b544); outline-offset: 3px; }

.ruta__punto {
  display: block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #fff;
  opacity: .38;
  /* el halo oscuro es lo que la hace visible sobre el crema y sobre las fotos */
  filter: drop-shadow(0 0 2px rgba(24, 28, 18, .9));
  /* crece con transform, no con ancho/alto: así no re-acomoda nada al animar */
  transition: transform .32s cubic-bezier(.2, 1.4, .4, 1), opacity .32s ease;
}
.ruta__parada--vista .ruta__punto { opacity: .62; }
.ruta__parada--actual .ruta__punto { transform: scale(1.86); opacity: 1; }

/* El nombre se asoma al cambiar de sección y se quita solo: informa sin estorbar. */
.ruta__nombre {
  position: absolute;
  left: calc(100% + .2rem);
  top: 50%;
  font-size: .68rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: #fff;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transform: translateY(-50%) translateX(-5px);
  transition: opacity .35s ease, transform .35s ease;
  text-shadow: 0 0 3px rgba(24, 28, 18, .95), 0 1px 5px rgba(24, 28, 18, .75);
}
.ruta__parada--anunciando .ruta__nombre { opacity: 1; transform: translateY(-50%) translateX(0); }

/* En computadora la barra de scroll ya dice dónde vas. */
@media (min-width: 760px) {
  .ruta { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .ruta__punto, .ruta__nombre { transition: none; }
}

/* ═══════════ Pista de scroll ═══════════ */
/* La invitación es una sola columna larga y en el celular, después de dos o tres
   deslizadas, no queda claro que hay que seguir. Esta mano aparece tras unos
   segundos sin moverse y se va en cuanto la persona vuelve a deslizar.
   Va en trazo abierto, no sobre una pastilla. El halo oscuro son dos sombras:
   una pegada, que le da borde sobre el crema claro, y otra suave, que la
   despega de las fotos. Sin la primera, el trazo blanco se pierde en el crema.
   La flecha de doble punta es la que hace entendible el gesto; la mano sola
   es ambigua. */
.pista-scroll {
  position: fixed;
  right: 1.1rem;
  top: 50%;
  z-index: 85;
  transform: translateY(-50%);
  color: #fff;
  filter: drop-shadow(0 0 2px rgba(24, 28, 18, .85))
          drop-shadow(0 2px 7px rgba(24, 28, 18, .5));
  opacity: 0;
  visibility: hidden;
  pointer-events: none;   /* nunca se interpone con lo que hay debajo */
  transition: opacity .5s ease, visibility .5s;
}
.pista-scroll--visible { opacity: .95; visibility: visible; }

.pista-scroll__mano {
  display: block;
  width: 48px;   /* la mitad de los 96 originales */
  height: auto;
}
/* la animación sólo corre mientras la pista se ve: oculta no gasta nada */
.pista-scroll--visible .pista-scroll__mano {
  animation: pista-vaiven 2.4s ease-in-out infinite;
}

/* Sube y baja, como dice la flecha de doble punta. */
@keyframes pista-vaiven {
  0%, 100% { transform: translateY(8px); }
  50%      { transform: translateY(-8px); }
}

/* En computadora la barra de scroll ya avisa que hay más abajo. */
@media (min-width: 760px) {
  .pista-scroll { display: none; }
}

/* Sin movimiento sigue sirviendo: se queda quieta en vez de desaparecer. */
@media (prefers-reduced-motion: reduce) {
  .pista-scroll__mano { animation: none; }
}

/* ═══════════ Hojas cayendo ═══════════ */
.hojas {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 80;
  overflow: hidden;
}
.hoja {
  position: absolute;
  top: -30px;
  width: 14px;
  height: 14px;
  background: var(--laurel-claro);
  border-radius: 0 60% 0 60%;
  opacity: .7;
  animation: caer linear infinite;
  /* cada hoja en su propia capa: sin esto, su vaivén repintaba la pantalla */
  will-change: transform;
}

/* en pleno scroll las animaciones de fondo se pausan (ver el vigía en main.js):
   compiten por los mismos cuadros que el deslizar y nadie las ve moverse */
body.scrolleando .hoja,
body.scrolleando .mota,
body.scrolleando .mariposa { animation-play-state: paused; }

@keyframes caer {
  0%   { transform: translateY(-5vh) translateX(0) rotate(0deg); }
  100% { transform: translateY(110vh) translateX(60px) rotate(360deg); }
}

/* ═══════════ Animaciones reveal ═══════════ */
.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity .9s ease, transform .9s ease;
}
/* las imágenes entran con un ligero zoom */
.reveal--zoom { transform: translateY(28px) scale(.92); }
.reveal--visible { opacity: 1; transform: none; }

@keyframes aparecer {
  from { opacity: 0; transform: scale(.95); }
  to   { opacity: 1; transform: scale(1); }
}

/* ═══════════ Mariposas volando (tema terracota) ═══════════ */
/* Portadas de demo-aurora/css/estilos.css. Sólo se dibujan si el evento pide
   animacion = 'mariposas'; los demás temas nunca crean estos elementos. */
.mariposas { position: fixed; inset: 0; pointer-events: none; z-index: 80; overflow: hidden; }
.mariposa {
  position: absolute;
  bottom: -55px;
  width: var(--tamano, 46px);
  height: calc(var(--tamano, 46px) * .763);
  animation: volar-mariposa var(--duracion, 15s) linear infinite;
  filter: drop-shadow(0 3px 3px rgba(51, 39, 33, .18));
  will-change: transform;
}
.mariposa__inclinacion {
  position: absolute;
  inset: 0;
  animation: inclinar-mariposa 2.8s ease-in-out infinite alternate;
  perspective: 110px;
  transform-style: preserve-3d;
}
.mariposa__imagen {
  position: absolute;
  top: 0;
  display: block;
  width: 50.2%;
  height: 100%;
  background-image: url('../assets/mariposa-natural.webp');
  background-repeat: no-repeat;
  background-size: 200% 100%;
  filter: hue-rotate(var(--tono, 0deg)) saturate(.88) brightness(.98);
  backface-visibility: visible;
}
.mariposa__imagen--izq { left: 0; background-position: left center; transform-origin: right center; animation: aletear-natural-izq var(--aleteo, .54s) ease-in-out infinite alternate; }
.mariposa__imagen--der { right: 0; background-position: right center; transform-origin: left center; animation: aletear-natural-der var(--aleteo, .54s) ease-in-out infinite alternate; }
@keyframes aletear-natural-izq { from { transform: rotateY(4deg); } to { transform: rotateY(58deg); } }
@keyframes aletear-natural-der { from { transform: rotateY(-4deg); } to { transform: rotateY(-58deg); } }
@keyframes inclinar-mariposa { from { transform: rotate(-7deg) scale(.96); } to { transform: rotate(8deg) scale(1.03); } }
@keyframes volar-mariposa {
  0% { opacity: 0; transform: translate3d(0, 0, 0) rotate(-7deg); }
  7% { opacity: .76; }
  24% { transform: translate3d(var(--x1, 24px), -29vh, 0) rotate(6deg); }
  49% { transform: translate3d(var(--x2, -18px), -59vh, 0) rotate(-5deg); }
  73% { transform: translate3d(var(--x3, 30px), -88vh, 0) rotate(7deg); }
  92% { opacity: .76; }
  100% { opacity: 0; transform: translate3d(var(--deriva, 15px), -122vh, 0) rotate(-4deg); }
}

/* ═══════════ Enredadera que se dibuja al scrollear (tema terracota) ═══════════ */
.enredadera {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 60;
  pointer-events: none;
  opacity: .62;
  overflow: visible;
  will-change: transform;   /* misma razón que .hilo */
}
.enredadera__tallo {
  fill: none;
  stroke-width: 2.2;
  stroke-linecap: round;
}
.enredadera__brote {
  opacity: 0;
  transform: scale(.15);
  transform-box: fill-box;
  transform-origin: center;
  transition: opacity .7s ease, transform .8s cubic-bezier(.2, .8, .25, 1.35);
}
.enredadera__brote--visible { opacity: 1; transform: scale(1); }
.enredadera__hoja { fill: var(--oliva-osc); }
.enredadera__flor { fill: var(--laurel-claro); }
.enredadera__flor-centro { fill: var(--oro); }
.enredadera__punta {
  fill: var(--oliva-osc);
  filter: drop-shadow(0 0 3px rgba(107, 127, 94, .45));
  transform-box: fill-box;
  transform-origin: center;
}

/* ═══════════ Invitación inexistente o todavía sin publicar ═══════════ */
body.evento-no-disponible .portada,
body.evento-no-disponible .contenido,
body.evento-no-disponible .hojas,
body.evento-no-disponible .btn-musica { display: none; }
.no-disponible {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .9rem;
  padding: 2rem;
  text-align: center;
  background-color: var(--beige);
  background-image: var(--textura);
  background-blend-mode: multiply;
}
.no-disponible__titulo {
  font-family: var(--serif);
  font-size: 1.7rem;
  color: var(--laurel-osc);
}
.no-disponible__texto {
  max-width: 34ch;
  font-size: .92rem;
  line-height: 1.7;
  color: var(--tinta-suave);
}

@media (max-width: 430px) {
  .enredadera { left: -22px; }
}

@media (prefers-reduced-motion: reduce) {
  .mariposas { display: none; }
}

/* ═══════════ Motas de luz flotando (tema de comunión) ═══════════ */
/* Portadas de demo-comunion/css/estilos.css. */
.motas { position: fixed; inset: 0; pointer-events: none; z-index: 55; overflow: hidden; }
.mota {
  position: absolute;
  bottom: -20px;
  width: var(--tam, 8px);
  height: var(--tam, 8px);
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--oro-claro), var(--oro) 60%, transparent 72%);
  opacity: 0;
  animation: subir-mota linear infinite;
}
@keyframes subir-mota {
  0%   { transform: translateY(0) translateX(0) scale(.7); opacity: 0; }
  12%  { opacity: .75; }
  70%  { opacity: .55; }
  100% { transform: translateY(-108vh) translateX(var(--deriva, 40px)) scale(1.1); opacity: 0; }
}

/* ═══════════ Rosario que se desgrana al scrollear (tema de comunión) ═══════════ */
/* A diferencia del hilo y la enredadera, este va del lado derecho. */
.rosario { position: absolute; top: 0; right: 2px; z-index: 60; pointer-events: none;
  will-change: transform;   /* misma razón que .hilo */ }
.rosario .cordon { fill: none; stroke-width: 1.6; stroke-linecap: round; opacity: .55; }
.rosario .cuenta {
  opacity: 0;
  transform-origin: center;
  transition: opacity .55s ease, transform .55s cubic-bezier(.2, 1.4, .4, 1);
}
.rosario .cuenta--visible { opacity: .95; }
.rosario .cruz-final { opacity: 0; transition: opacity .9s ease; }
.rosario .cruz-final--visible { opacity: .95; }

@media (prefers-reduced-motion: reduce) {
  .motas { display: none; }
}
