/* ============================================================
   styles.css — Invitación de Boda
   ============================================================
   Índice:
     §1  Reset & Tokens
     §2  Base
     §3  Scroll Container
     §4  Páginas / Secciones
     §5  Capa Parallax
     §6  Overlay (página 1)
     §7  Contenido central
     §8  Adornos de esquina
     §9  Tipografía — Página 1
     §10 Tipografía — Página 2
     §11 Sistema de Animación (anim-item)
     §12 Cursor typewriter
     §13 Navegación lateral (dots)
     §14 Reduced motion
     §15 Responsivo
   ============================================================ */


/* ────────────────────────────────────────────────────────────
   §1  RESET & TOKENS
──────────────────────────────────────────────────────────── */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  /* ── Paleta por página ──────────────────────────────────── */
  --p1-bg:    #0a0a0f;          /* Noche profunda            */
  --p1-text:  #f0ece4;          /* Blanco cálido             */
  --p2-bg:    #f3e2c9;          /* Crema suave               */
  --p2-text:  #2a2016;          /* Oscuro cálido             */
  --p3-bg:    #fdfbf7;
  --p3-text:  #2a2016;

  /* ── Tipografía (cambia las familias aquí) ──────────────── */
  --font-display: Georgia, "Times New Roman", serif;
  --font-body:    system-ui, -apple-system, sans-serif;

  /* ── Parallax ───────────────────────────────────────────── */
  --parallax-speed: 0.35;

  /* ── Animaciones ────────────────────────────────────────── */
  --ease-out:      cubic-bezier(0.22, 1, 0.36, 1);
  --dur-enter:     0.75s;
  --dur-exit:      0.35s;
  --stagger-step:  0.14s;   /* multiplicador de data-delay en JS */

  /* ── Dots de navegación ─────────────────────────────────── */
  --dot-size:   10px;
  --dot-gap:    14px;
}


/* ────────────────────────────────────────────────────────────
   §2  BASE
──────────────────────────────────────────────────────────── */
html {
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--font-body);
  overflow: hidden;    /* El scroll ocurre en #scroll-container */
  height: 100dvh;
  background: #000;
}


/* ────────────────────────────────────────────────────────────
   §3  SCROLL CONTAINER
──────────────────────────────────────────────────────────── */
#scroll-container {
  height: 100dvh;
  overflow-y: scroll;
  overflow-x: hidden;
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
#scroll-container::-webkit-scrollbar { display: none; }


/* ────────────────────────────────────────────────────────────
   §4  PÁGINAS / SECCIONES
──────────────────────────────────────────────────────────── */
.page {
  position: relative;
  width: 100%;
  height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

#page1 { background-color: var(--p1-bg); color: var(--p1-text); }
#page2 { background-color: var(--p2-bg); color: var(--p2-text); }
#page3 { background-color: var(--p2-bg); color: var(--p3-text); }
#page4 { background-color: var(--p2-bg); color: var(--p2-text); }
#page5 { background-color: var(--p1-bg); color: var(--p1-text); }
#page6 { background-color: var(--p1-bg); color: var(--p1-text); }


/* ────────────────────────────────────────────────────────────
   §5  CAPA PARALLAX
   La posición vertical se anima con JS (translateY).
   La capa desborda ±30% verticalmente para que el movimiento
   no deje espacios en blanco en los bordes.
──────────────────────────────────────────────────────────── */
.page__parallax-bg {
  position: absolute;
  inset: -30% 0;
  width: 100%;
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
  will-change: transform;
  transform: translateY(0px);
  z-index: 0;
}

/* Página 1: foto de fondo a plena opacidad */
#page1 .page__parallax-bg {
  background-image: url('img/rings_caja.webp'); /* ← reemplaza con tu imagen */
  opacity: 1;
}

/* Páginas 5 y 6: foto de fondo a plena opacidad (igual que p1) */
#page5 .page__parallax-bg {
  background-image: url('img/anillos_reales.webp'); /* ← reemplaza con tu imagen */
  opacity: 1;
  inset: -5% 0;
}
#page6 .page__parallax-bg {
  background-image: url('img/zapatos.webp'); /* ← reemplaza con tu imagen */
  opacity: 1;
  inset: -1% 0;
}

/* Páginas 2, 3, 4: sin imagen parallax (fondo sólido del .page) */
#page2 .page__parallax-bg,
#page3 .page__parallax-bg,
#page4 .page__parallax-bg {
  opacity: 0;
  pointer-events: none;
}

/*
  ── §5b  DYNAMIC BLUR ──────────────────────────────────────
  Activa el efecto en cualquier sección añadiéndole la clase
  .dynamic-blur. No requiere tocar nada más: el blur máximo
  es configurable por sección con la custom property
  --dynamic-blur-max (default: 10).

  Uso mínimo en HTML:
    <section class="page dynamic-blur" id="pageN" ...>

  Ajuste fino por sección en CSS:
    #page5 { --dynamic-blur-max: 6; }

  Cómo funciona:
    · JS lee --dynamic-blur-max en cada sección.
    · Calcula progress = |scrollOffset| / sectionHeight  (0→1)
    · Aplica filter: blur( maxBlur * progress + 'px' )
    · Result: 0 px cuando la sección está snapeada,
              maxBlur px cuando está completamente fuera del viewport.
  ────────────────────────────────────────────────────────── */
.dynamic-blur {
  --dynamic-blur-max: 10; /* px — sobrescribe por sección si quieres */
}

.dynamic-blur .page__parallax-bg {
  /*
    GPU hint: transform ya estaba; añadimos filter.
    Ambas viven en el compositor → sin layout, sin paint.
  */
  will-change: transform, filter;

  /*
    Valor inicial antes del primer tick de JS.
    Al arrancar, la página 1 ya está snapeada → JS la pondrá
    en blur(0) inmediatamente. Las demás están fuera del viewport
    así que el valor no importa visualmente.
  */
  filter: blur(10px);
}


/* ────────────────────────────────────────────────────────────
   §6  OVERLAY — solo página 1
   Oscurece la foto para que el texto sea legible.
──────────────────────────────────────────────────────────── */
.page__overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

#page1 .page__overlay,
#page5 .page__overlay,
#page6 .page__overlay {
  background: linear-gradient(
    160deg,
    rgba(0 0 0 / 0.20) 0%,
    rgba(0 0 0 / 0.60) 100%
  );
}


/* ────────────────────────────────────────────────────────────
   §7  CONTENIDO CENTRAL
──────────────────────────────────────────────────────────── */
.page__content {
  position: relative;
  z-index: 2;
  width: min(700px, 88%);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.2rem;
}

/* ────────────────────────────────────────────────────────────
   §9  TIPOGRAFÍA — PÁGINA 1
──────────────────────────────────────────────────────────── */
.eyebrow {
  font-family: var(--font-body);
  font-size: clamp(0.65rem, 1.4vw, 0.82rem);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  opacity: 0.65;
}

.couple-names {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2.8rem, 9vw, 6rem);
  line-height: 1.05;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15em;
}

.name__sep {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 4.5vw, 3rem);
  font-weight: 300;
  opacity: 0.5;
  line-height: 1;
}

.wedding-date {
  font-family: var(--font-body);
  font-size: clamp(0.7rem, 1.6vw, 0.9rem);
  letter-spacing: 0.22em;
  opacity: 0.6;
}


/* ────────────────────────────────────────────────────────────
   §10 TIPOGRAFÍA — PÁGINA 2
──────────────────────────────────────────────────────────── */
.invitation-block {
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
}

.invitation-label {
  font-family: var(--font-body);
  font-size: clamp(0.65rem, 1.4vw, 0.82rem);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  opacity: 0.45;
}

.invitation-text {
  font-family: var(--font-display);
  font-size: clamp(1.45rem, 4vw, 2.2rem);
  font-style: italic;
  font-weight: 400;
  line-height: 1.5;
  /* Reserva altura para que el bloque no salte al ir apareciendo el texto */
  min-height: 4.5em;
}


/* ────────────────────────────────────────────────────────────
   §10b TIPOGRAFÍA — PÁGINA 3 (countdown + headline)
──────────────────────────────────────────────────────────── */
.countdown-headline {
  font-family: var(--font-display);
  font-size: clamp(1rem, 2.8vw, 1.5rem);
  font-style: italic;
  font-weight: 400;
  line-height: 1.55;
  opacity: 0.82;
  max-width: 38ch;
}

.countdown {
  display: flex;
  align-items: flex-start;
  gap: clamp(0.6rem, 1.8vw, 1.4rem);
}

.countdown__unit {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
}

.countdown__number {
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 7vw, 4.2rem);
  font-weight: 400;
  line-height: 1;
  min-width: 2ch;
  text-align: center;
  /* Evita saltos de layout al cambiar dígitos (1ch ≈ ancho de '0') */
  font-variant-numeric: tabular-nums;
}

.countdown__label {
  font-family: var(--font-body);
  font-size: clamp(0.58rem, 1.1vw, 0.7rem);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.45;
}

.countdown__sep {
  font-family: var(--font-display);
  font-size: clamp(1.8rem, 5vw, 3rem);
  line-height: 1;
  opacity: 0.25;
  /* Alinea el ':' con los números, no con las etiquetas */
  margin-top: 0.08em;
  align-self: flex-start;
}


/* ────────────────────────────────────────────────────────────
   §10c COMPONENTE POLAROID
   ─────────────────────────────────────────────────────────
   Reutilizable en cualquier sección.
   La inclinación se controla con la custom property
   --polaroid-rotate (acepta cualquier valor de <angle>):

     <div class="polaroid-frame" style="--polaroid-rotate: -5deg">

   El rotate se combina con el translate del efecto peek,
   así que nunca pisas la rotación al animar la posición.
──────────────────────────────────────────────────────────── */
.polaroid-frame {
  --polaroid-rotate: 0deg;   /* override inline o por selector */

  /* Posicionamiento: peek-anim--bl/tr lo sobreescriben */
  position: absolute;
  z-index: 3;

  /* Marco estilo foto instantánea */
  background: #ffffff;
  padding: clamp(8px, 1.2vw, 12px)
           clamp(8px, 1.2vw, 12px)
           clamp(28px, 4.5vw, 44px); /* más espacio inferior para el caption */
  border-radius: 2px;
  box-shadow:
    0  2px  6px rgba(0 0 0 / 0.10),
    0  8px 20px rgba(0 0 0 / 0.08),
    0 20px 40px rgba(0 0 0 / 0.05);

  width: clamp(170px, 26vw, 270px);

  /* GPU hint: transform cambia frecuentemente en el peek */
  will-change: transform;
}

/* Contenedor de la foto: cuadrado con recorte */
.polaroid-frame__photo {
  width: 100%;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: #e8e3db; /* color de fondo mientras carga */
}

.polaroid-frame__photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;    /* recorta y escala sin deformar */
  object-position: center;
}

/* Placeholder cuando src está vacío */
.polaroid-frame__photo img:not([src]),
.polaroid-frame__photo img[src=""] {
  /* Oculta el ícono de imagen rota del navegador */
  visibility: hidden;
}

/* Subtítulo manuscrito debajo de la foto */
.polaroid-frame__caption {
  text-align: center;
  font-family: var(--font-body);
  font-size: clamp(0.6rem, 1vw, 0.72rem);
  color: #666;
  margin-top: clamp(6px, 1vw, 10px);
  line-height: 1.4;
  letter-spacing: 0.03em;
}


/* ────────────────────────────────────────────────────────────
   §10d EFECTO PEEK (asomado) DE LOS POLAROIDS
   ─────────────────────────────────────────────────────────
   .peek-anim           → base: propiedades de transición
   .peek-anim--bl       → posición esquina inferior-izquierda
   .peek-anim--tr       → posición esquina superior-derecha

   Estados:
     base               → completamente fuera del viewport
     .page.is-visible   → asomado (~55% visible, 45% oculto)
     .page.is-exiting   → regresa fuera del viewport

   La propiedad overflow: hidden del .page recorta
   automáticamente lo que sobresale, creando el efecto peek.
   Combinar translate y rotate en la misma propiedad transform
   preserva la rotación --polaroid-rotate en todos los estados.
──────────────────────────────────────────────────────────── */

/* Transición compartida */
.peek-anim {
  transition: transform 0.85s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ── Esquina inferior-izquierda ────────────────────────── */
.peek-anim--bl {
  bottom: 0;
  left:   0;
  transform-origin: bottom left;

  /* Estado inicial: fuera del viewport (abajo-izquierda) */
  transform: translate(-100%, 55%) rotate(var(--polaroid-rotate));

  /* Entrada con leve delay para que el texto aparezca primero */
  transition-delay: 0.5s;
}

/* ── Esquina superior-derecha ──────────────────────────── */
.peek-anim--tr {
  top:   0;
  right: 0;
  transform-origin: top right;

  /* Estado inicial: fuera del viewport (arriba-derecha) */
  transform: translate(100%, -55%) rotate(var(--polaroid-rotate));

  /* Entrada ligeramente más tarde que bl para escalonar */
  transition-delay: 0.8s;
}

/* ── Estado visible: asomado ──────────────────────────── */
.page.is-visible .peek-anim--bl {
  /* Deja ~40% del polaroid fuera por la izquierda y un poco por abajo */
  transform: translate(20%, 5%) rotate(var(--polaroid-rotate));
}

.page.is-visible .peek-anim--tr {
  /* Deja ~40% fuera por la derecha y un poco por arriba */
  transform: translate(5%, 10%) rotate(var(--polaroid-rotate));
}

/* ── Estado de salida: regresa rápido fuera de pantalla── */
.page.is-exiting .peek-anim--bl,
.page.is-exiting .peek-anim--tr {
  transition-delay:    0s    !important;
  transition-duration: 0.35s !important;
}

/* La posición exacta de salida se hereda del estado base
   (sin .is-visible), que mueve el polaroid fuera del viewport */


/* ────────────────────────────────────────────────────────────
   §10e  PÁGINA 4 — POLAROID STACK INTERACTIVO
   ─────────────────────────────────────────────────────────
   .polaroid-stack__item
     → extiende .polaroid-frame para el modo "pila centrada"
     → todas arrancan en top:50% left:50%, centradas con
       translate(-50%,-50%) + rotate(--polaroid-rotate)
     → al recibir .is-spread se mueven a sus posiciones finales

   Posiciones spread: modifica --spread-x / --spread-y por sección
   o ajusta los translate individuales si quieres un layout libre.

   z-index escalonado: data-stack-index 0 (fondo) → 3 (tope clickable)
──────────────────────────────────────────────────────────── */

/* Tokens de posición para el spread — fáciles de ajustar */
#page4 {
  --spread-x: clamp(95px, 20vw, 210px);   /* offset horizontal */
  /*--spread-y: clamp(75px, 11vh, 148px);   /* offset vertical   */
  --spread-y: clamp(-285px, -31vh, 20px)
}

/* ── Estado base: todos centrados, apilados ─────────────── */
.polaroid-stack__item {
  /* Ancla de posición: solo cambia transform al hacer spread */
  top:  50%;
  left: 50%;

  /* Centro + rotación de la pila */
  transform: translate(-50%, -50%) rotate(var(--polaroid-rotate));

  /*
    Transición exclusiva de transform para la dispersión.
    box-shadow se anima aparte para el efecto hover.
    0.6s ease-in-out solicitado por el usuario.
  */
  transition:
    transform  0.6s ease-in-out,
    box-shadow 0.25s ease;

  will-change: transform;
  cursor: pointer;
}

/* Profundidad visual de la pila: índice más alto = más al frente */
.polaroid-stack__item[data-stack-index="0"] { z-index: 4; }
.polaroid-stack__item[data-stack-index="1"] { z-index: 5; }
.polaroid-stack__item[data-stack-index="2"] { z-index: 6; }
.polaroid-stack__item[data-stack-index="3"] { z-index: 7; }

/* Hover: eleva ligeramente la carta del tope antes del click */
.polaroid-stack__item[data-stack-index="3"]:hover {
  box-shadow:
    0  6px 16px rgba(0 0 0 / 0.12),
    0 20px 40px rgba(0 0 0 / 0.09);
  transform: translate(-50%, -53%) rotate(var(--polaroid-rotate));
}

/* ── Indicador visual de "click me" en la carta del tope ─── */
/*
  Pulsa el borde exterior del polaroid para sugerir interacción.
  Solo visible antes del spread (cuando no tiene .is-spread).
  Se detiene al hacer click porque el elemento queda apagado
  de inmediato (JS añade .is-spread a todos).
*/
.polaroid-stack__item[data-stack-index="3"]:not(.is-spread)::after {
  content: '';
  position: absolute;
  inset: -6px;
  border-radius: 2px;
  animation: stack-pulse 2.2s ease-in-out 1.8s infinite;
  pointer-events: none;
}

@keyframes stack-pulse {
  0%, 100% { box-shadow: 0 0 0 0px rgba(0 0 0 / 0.08); }
  50%       { box-shadow: 0 0 0 6px rgba(0 0 0 / 0.12); }
}

/* ── Posiciones spread (distribución 2×2) ──────────────────
   Cada carta vuela a una esquina del espacio disponible.
   Las rotaciones finales difieren de las de la pila para
   que parezcan colocadas a mano, no alineadas a cuadrícula.

   Para un layout libre basta con cambiar los translate aquí;
   no hay que tocar nada del HTML ni del JS.
────────────────────────────────────────────────────────── */

/* Esquina superior-izquierda */
.polaroid-stack__item.is-spread[data-stack-index="0"] {
  transform:
    translate(calc(-50% - var(--spread-x)), calc(-50% - var(--spread-y)))
    rotate(25deg);
}

/* Esquina superior-derecha */
.polaroid-stack__item.is-spread[data-stack-index="1"] {
  transform:
    translate(calc(-50% + var(--spread-x)), calc(-95% - var(--spread-y)))
    rotate(-15deg);
}

/* Esquina inferior-izquierda */
.polaroid-stack__item.is-spread[data-stack-index="2"] {
  transform:
    translate(calc(-50% - var(--spread-x)), calc(10% + var(--spread-y)))
    rotate(15deg);
}

/* Esquina inferior-derecha */
.polaroid-stack__item.is-spread[data-stack-index="3"] {
  transform:
    translate(calc(-50% + var(--spread-x)), calc(-50% + var(--spread-y)))
    rotate(-15deg);
  /* Eleva el hover en estado spread */
  cursor: default;
}


/* ── Overlay del mensaje reveal ─────────────────────────── */
.reveal-overlay {
  position: absolute;
  inset: 0;
  z-index: 20;                          /* encima de todos los polaroids */

  display: flex;
  align-items: center;
  justify-content: center;

  /* Semi-transparente sobre el crema + blur sutil del fondo */
  background: rgba(10 10 15 / 0.65);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);

  /* Invisible hasta que JS añada .is-visible */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.55s ease;
}

.reveal-overlay.is-visible {
  opacity: 1;
  pointer-events: auto;
}

/*
  El reveal no usa tarjeta blanca: el texto aparece directamente
  sobre el overlay oscuro, igual al tratamiento de página 1.
  Esto mantiene coherencia visual y es más dramático para el reveal.
*/
.reveal-overlay {
  position: absolute;
  inset: 0;
  z-index: 20;  /* encima de todos los polaroids (z-index 4-7) */

  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;

  /*
    Oscurece el fondo igual que el overlay de página 1
    (linear-gradient de esquina a esquina, con distintas opacidades).
    Se hace gradiente para que los bordes sean más suaves.
  */
  background: linear-gradient(
    160deg,
    rgba(0 0 0 / 0.55) 0%,
    rgba(0 0 0 / 0.72) 100%
  );

  /* Invisible hasta que JS añada .is-visible */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.6s ease;
}

.reveal-overlay.is-visible {
  opacity: 1;
  pointer-events: auto;
}

/* El contenedor del texto sube desde abajo al aparecer */
.reveal-overlay__card {
  text-align: center;
  max-width: min(480px, 84vw);
  padding: 0 1.5rem;

  transform: translateY(24px);
  transition: transform 0.6s var(--ease-out);
}

.reveal-overlay.is-visible .reveal-overlay__card {
  transform: translateY(0);
}

.name-reveal {
  font-family: var(--font-body);
  font-size: clamp(1.2rem, 3vw, 2rem);
  font-weight: 400;
  line-height: 1;
  color: var(--p1-text);   /* crema cálido: #f0ece4 */
  margin-bottom: 1rem;
  margin-top: 1rem;
  font-style: italic;
}

/* Texto sobre fondo oscuro → crema claro, como página 1 */
.reveal-message {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 3.8vw, 2.1rem);
  /* font-style: italic; */
  font-weight: 400;
  color: var(--p1-text);   /* crema cálido: #f0ece4 */
  line-height: 1.2;
}

.reveal-message em {
  font-style: normal;
  font-weight: 600;
}

/* Pista de reset: pequeño, discreto, al pie del reveal */
.reveal-hint {
  font-family: var(--font-body);
  font-size: clamp(0.58rem, 1vw, 0.68rem);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--p1-text);
  opacity: 0.50;
  cursor: pointer;
  transition: opacity 0.2s ease;
  margin-top: 1.5rem;
}
.reveal-hint:hover { opacity: 0.65; }


/* ────────────────────────────────────────────────────────────
   §10f  PÁGINAS 5 Y 6 — CONTENIDO SOBRE FOTO OSCURA
   Reutiliza tokens y clases existentes (.eyebrow, .wedding-date,
   var(--font-display), var(--p1-text)) para mantener coherencia
   con página 1. Solo se definen clases verdaderamente nuevas.
──────────────────────────────────────────────────────────── */

/* ── Ícono decorativo (p5): pequeño, centrado, sobre fondo oscuro ── */
.event-icon {
  display: block;
  width: clamp(36px, 6vw, 60px);
  height: auto;
  object-fit: contain;
  opacity: 0.88;
}

.pg1-down.event-icon {
  margin-top: 1.5rem;
  width: clamp(200px, 40vw, 410px);
  animation: grow 2s ease-out 0.5s forwards;
  animation-delay: 850ms;
}

@keyframes grow {
  0%   { clip-path: circle(0% at 50% 50%); }
  100% { clip-path: circle(100% at 50% 50%); }
}

.pg1-up.event-icon {
  margin-bottom: 1.5rem;
  width: clamp(120px, 28vw, 195px);
}

/* Placeholder visual cuando src está vacío */
.event-icon:not([src]),
.event-icon[src=""] {
  height: clamp(36px, 6vw, 60px);
  border: 1.5px dashed rgba(255 255 255 / 0.28);
  border-radius: 4px;
}

/* ── PÁGINA 5: bloques de evento (ceremonia / recepción) ── */

/*
  Fecha principal: misma escala que .couple-names pero en una sola línea.
  Se separa en clase propia para poder ajustar el tamaño independientemente.
*/
.main-date {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 5.5vw, 3.4rem);
  font-weight: 400;
  letter-spacing: 0.04em;
  line-height: 1.1;
}

/* Separador decorativo entre los dos bloques de evento */
.event-sep {
  width: clamp(40px, 8vw, 70px);
  height: 1px;
  background: rgba(255 255 255 / 0.35);
  border: none;
  margin: 0;            /* el gap del .page__content maneja el espacio */
}

/* Contenedor de un evento (ceremonia o recepción) */
.event-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
}

/* Nombre del lugar: protagonista del bloque */
.event-name {
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 3vw, 1.75rem);
  font-style: italic;
  font-weight: 400;
  line-height: 1.2;
}

/* Hora: discreta, misma escala que .wedding-date */
.event-time {
  font-family: var(--font-body);
  font-size: clamp(0.7rem, 1.6vw, 0.88rem);
  letter-spacing: 0.2em;
  opacity: 0.6;
}

.pg5-up.event-icon {
  width: clamp(120px, 28vw, 195px);
}

.pg5-down.event-icon {
  width: clamp(50px, 9vw, 120px);
  /* clamp(36px, 6vw, 60px); */
}

/* ── PÁGINA 6: confirmación, vestimenta, regalo ─────────── */

/* Titular de la fecha límite */
.rsvp-deadline {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 4.5vw, 2.6rem);
  font-weight: 400;
  font-style: italic;
  line-height: 1.2;
}

/* Botón / hipervínculo de confirmación */
.rsvp-btn {
  display: inline-block;
  font-family: var(--font-body);
  font-size: clamp(0.72rem, 1.4vw, 0.85rem);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--p1-text);
  text-decoration: none;
  border: 1px solid rgba(255 255 255 / 0.55);
  padding: 0.75em 2em;
  border-radius: 1px;
  transition: background 0.25s ease, border-color 0.25s ease;
}
.rsvp-btn:hover,
.rsvp-btn:focus-visible {
  background: rgba(255 255 255 / 0.12);
  border-color: rgba(255 255 255 / 0.85);
  outline: none;
}

.rsvp-btn__icon {
  display: inline-block;
  width: clamp(16px, 2.5vw, 24px);
  height: auto;
  margin-left: 0.5em;
  vertical-align: middle;
}

/* Bloque de código de vestimenta */
.dress-code {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.45rem;
}

/* Restricciones de colores: dos líneas, una por género */
.dress-restriction {
  font-family: var(--font-body);
  font-size: clamp(0.68rem, 1.3vw, 0.82rem);
  line-height: 1.5;
  opacity: 0.72;
}
.dress-restriction strong {
  font-weight: 600;
  opacity: 1;           /* el <strong> no hereda la opacidad reducida del padre */
}

.closing-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.45rem;
}

/* Línea de cierre: cálida, un poco más grande */
.closing-line {
  font-family: var(--font-display);
  font-size: clamp(1rem, 2.5vw, 1.4rem);
  font-style: italic;
  opacity: 0.9;
}

/* Fecha principal (p5) — más grande que venue, más chica que couple-names */
.event-date {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 5.5vw, 3.4rem);
  font-weight: 400;
  letter-spacing: 0.03em;
  line-height: 1.1;
}

/* Separador horizontal entre bloques de evento (como <div>, no <hr>) */
.event-rule {
  width: clamp(40px, 8vw, 70px);
  height: 1px;
  background: rgba(255 255 255 / 0.30);
  flex-shrink: 0;
}

/* Separador ornamental ✦ entre ceremonia y recepción */
.event-ornament {
  font-size: 0.65rem;
  letter-spacing: 0.5em;
  opacity: 0.35;
}

/* Etiqueta "Ceremonia" / "Recepción" dentro de .event-block */
.event-block__label {
  font-family: var(--font-body);
  font-size: clamp(0.62rem, 1.2vw, 0.74rem);
  letter-spacing: 0.26em;
  text-transform: uppercase;
  opacity: 0.5;
}

/* Nombre del lugar: protagonista del bloque — alias de .event-name */
.event-block__venue {
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 3vw, 1.75rem);
  font-style: italic;
  font-weight: 400;
  line-height: 1.25;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1em;
}

/* Sublocación en segunda línea, ligeramente más pequeña */
.event-block__sublocation {
  font-size: 0.82em;
  opacity: 0.72;
  display: block;
}

/* Hora: discreta — alias de .event-time */
.event-block__time {
  font-family: var(--font-body);
  font-size: clamp(0.7rem, 1.5vw, 0.86rem);
  letter-spacing: 0.18em;
  opacity: 0.62;
}

/* Etiqueta "Código de vestimenta" */
.dress-code__label {
  font-family: var(--font-body);
  font-size: clamp(0.62rem, 1.2vw, 0.74rem);
  letter-spacing: 0.26em;
  text-transform: uppercase;
  opacity: 1;
}

/* "Formal": titular del bloque — grande e itálico */
.dress-code__style {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 4.2vw, 2.5rem);
  font-weight: 400;
  font-style: italic;
  line-height: 1.1;
}

/* Restricciones de colores — alias de .dress-restriction */
.dress-code__note {
  font-family: var(--font-body);
  font-size: clamp(0.66rem, 1.3vw, 0.80rem);
  line-height: 1.5;
  opacity: 0.68;
  text-align: center;
  max-width: 38ch;
}

/* Separador inline · entre restricciones de hombres/mujeres */
.dress-code__dot { opacity: 0.45; }

/* Reduce el gap del .page__content en páginas con mucho contenido */
#page5 .page__content,
#page6 .page__content {
  gap: 0.7rem;
}

/* ── PÁGINA 5: layout revisado ─────────────────────────────
   Los dos bloques de evento (ceremonia + recepción) se colocan
   en fila para dar aire vertical. La fecha queda como hero
   indiscutible con más margen inferior.
────────────────────────────────────────────────────────── */
#page5 .page__content {
  /* vh permite escalar el espacio con la altura real del viewport */
  gap: clamp(1.1rem, 2.8vh, 2rem);
}

/* La fecha necesita más presencia visual; la separamos del resto */
#page5 .event-date {
  font-size: clamp(2.2rem, 6.5vw, 4rem);
  margin-bottom: 0.3rem;
}

/* Línea decorativa más ancha debajo de la fecha */
#page5 .event-rule {
  width: clamp(60px, 12vw, 110px);
  margin-bottom: 0.2rem;
}

/* Fila horizontal: ceremonia · separador · recepción */
.event-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(1.5rem, 5vw, 3.5rem);
  width: 100%;
}

/* Divisor vertical entre los dos bloques en la fila */
.event-row__divider {
  width: 1px;
  align-self: stretch;
  background: rgba(255 255 255 / 0.22);
  flex-shrink: 0;
  margin-top: 0.2rem;
}

/* En mobile muy estrecho los bloques vuelven a columna */
@media (max-width: 400px) {
  .event-row {
    flex-direction: column;
    align-items: center;
    gap: 1rem;
  }
  .event-row__divider { display: none; }
}

/* Respiración vertical extra solo en la fila de p5 */
#page5 .event-row {
  padding: clamp(0.4rem, 1.5vh, 0.9rem) 0;
}

/* Más espacio interno entre label / venue / time en p5 */
#page5 .event-block {
  gap: 0.5rem;
}

/* ── PÁGINA 6: cierre rediseñado ────────────────────────────
   El gift-message se centra y se elimina el borde lateral para
   que respire; el cierre gana más protagonismo visual.
────────────────────────────────────────────────────────── */

/*
  Separación entre secciones de p6.
  Los dos .event-rule actúan como divisores de sección;
  se les da más margen propio para que las 3 secciones
  (confirmación / vestimenta / regalo) queden claramente distinguibles.
*/
#page6 .event-rule {
  margin: clamp(0.7rem, 2vh, 1.3rem) 0;
  width: clamp(50px, 10vw, 90px);
}

/* Override del gift-message en p6:
   centrado + línea superior que forma el techo del "marco" */
#page6 .gift-message {
  font-family: var(--font-display);
  border-top: 1px solid rgba(255 255 255 / 0.20);
  padding-top: clamp(0.8rem, 2vh, 1.2rem);
  text-align: center;
  font-size: clamp(0.82rem, 1.8vw, 1rem);
  font-style: italic;
  max-width: 42ch;
  opacity: 0.78;
  line-height: 1.7;
  letter-spacing: 0.07em;
}

/* Cierre: línea inferior del "marco" del regalo + mayor protagonismo */
#page6 .closing-message {
  font-family: var(--font-display);
  font-size: clamp(1.2rem, 2.8vw, 1.6rem);
  opacity: 0.88;
  letter-spacing: 0.02em;
  padding-top: clamp(0.8rem, 2vh, 1.4rem);
  border-top: 1px solid rgba(255 255 255 / 0.20);
  margin-top: 0.15rem;
  font-style: italic;
}


/* ────────────────────────────────────────────────────────────
   §11 SISTEMA DE ANIMACIÓN DE ENTRADA / SALIDA
   ─────────────────────────────────────────────────────────
   .anim-item      → estado base: invisible + desplazado
   .is-visible     → estado visible: opaco + en posición
   .is-exiting     → estado de salida: desaparece hacia arriba

   transition-delay se inyecta por JS desde data-delay:
     delay = parseInt(data-delay) * --stagger-step
──────────────────────────────────────────────────────────── */

/* ── Estado base ────────────────────────────────────────── */
.anim-item {
  opacity: 0;
  transform: translateY(26px);
  transition:
    opacity   var(--dur-enter) var(--ease-out),
    transform var(--dur-enter) var(--ease-out);
  /* transition-delay → inyectado por JS */
}

/* ── Visible ────────────────────────────────────────────── */
.page.is-visible .anim-item {
  opacity: 1;
  transform: translateY(0);
}

/* ── Exiting: fade + desplazamiento hacia arriba ────────── */
.page.is-exiting .anim-item {
  opacity: 0;
  transform: translateY(-18px);
  transition-duration:  var(--dur-exit) !important;
  transition-delay:     0s              !important;
  animation: none !important;
}

/* ────────────────────────────────────────────────────────────
   §12 CURSOR TYPEWRITER
──────────────────────────────────────────────────────────── */
.invitation-text::after {
  content: '|';
  display: inline-block;
  margin-left: 1px;
  font-style: normal;
  animation: cursor-blink 0.75s step-end infinite;
}

/* Cuando JS termina de escribir agrega .tw-done → oculta cursor */
.invitation-text.tw-done::after {
  animation: none;
  opacity: 0;
  transition: opacity 0.4s ease 0.8s;
}

@keyframes cursor-blink {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0; }
}


/* ────────────────────────────────────────────────────────────
   §13 NAVEGACIÓN LATERAL (dots)
──────────────────────────────────────────────────────────── */
.page-nav {
  position: fixed;
  right: clamp(16px, 2.8vw, 30px);
  top: 50%;
  transform: translateY(-50%);
  z-index: 100;
}

.page-nav__list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--dot-gap);
}

.page-nav__dot {
  display: block;
  width: var(--dot-size);
  height: var(--dot-size);
  border-radius: 50%;
  border: 1.5px solid rgba(255 255 255 / 0.55);
  background: rgba(255 255 255 / 0.35);
  cursor: pointer;
  padding: 0;
  transition:
    background    0.3s ease,
    border-color  0.3s ease,
    transform     0.3s ease;
}

.page-nav__dot:hover,
.page-nav__dot:focus-visible {
  background: rgba(255 255 255 / 1);
  transform: scale(1.25);
  outline: none;
}

.page-nav__dot.active {
  background: rgba(255 255 255 / 1);
  border-color: rgba(255 255 255 / 1);
  transform: scale(1.3);
}

/*
  Variante para páginas claras (JS añade .page-nav--light).
  Invierte la paleta de los dots para que sean visibles sobre fondo crema.
*/
.page-nav--light .page-nav__dot {
  border-color: rgba(0 0 0 / 0.3);
  background:   rgba(0 0 0 / 0.15);
}
.page-nav--light .page-nav__dot:hover,
.page-nav--light .page-nav__dot:focus-visible {
  background: rgba(0 0 0 / 0.7);
}
.page-nav--light .page-nav__dot.active {
  background:   rgba(0 0 0 / 0.7);
  border-color: rgba(0 0 0 / 0.7);
}


/* ────────────────────────────────────────────────────────────
   §14 PREFERS-REDUCED-MOTION
   Elimina parallax, transiciones largas y typewriter animado.
   El contenido sigue siendo visible sin animación.
──────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  #scroll-container { scroll-behavior: auto; }

  .page__parallax-bg {
    transform: none !important;
    transition: none !important;
  }

  .anim-item {
    opacity: 0;
    transform: none;
    transition: opacity 0.2s ease;
  }
  .page.is-visible .anim-item {
    opacity: 1;
    transform: none;
  }
  .page.is-exiting .anim-item {
    opacity: 0;
    transform: none !important;
  }

  .page-nav__dot { transition: none; }
  .invitation-text::after { animation: none; }
}


/* ────────────────────────────────────────────────────────────
   §15 RESPONSIVO
──────────────────────────────────────────────────────────── */
@media (max-width: 480px) {
  :root {
    --dot-size: 8px;
    --dot-gap:  10px;
  }

  .invitation-text { min-height: 6em; }
}
