/* =========================================================
   PLANTILLA "LIGA DE HÉROES" — cumpleaños infantil, estilo cómic.
   Original (sin marca). Hoja de estilo AUTOCONTENIDA: NO depende de
   base.css/temas.css. Comparte el mismo contrato de datos (clases/IDs/
   data-rol/data-modulo) que el motor (motor.js) ya manipula.
   Mobile-first · accesible · sin dependencias.

   Rediseño "edición de colección" (v0.12.1): portada de cómic impresa,
   tinta densa, medios tonos Ben-Day, secciones como viñetas con sombra offset.
   Paleta rebalanceada al AZUL (v0.15.1): azul marino DOMINANTE (fondos, botones,
   banners, acentos), AMARILLO como acento "pop" (emblema, palabras de estallido,
   estrellas) y ROJO reducido al mínimo decorativo (halftone de esquina + estado
   de error del RSVP). Todo calibrado AA. Elegante primero.
   ========================================================= */

:root {
  --tinta:     #14182b;
  --tinta-90:  rgba(20,24,43,.90);
  --rojo:      #e5322a;   /* solo texto/relleno GRANDE (>=24px o 18.66 bold) */
  --azul:      #1f5fd0;   /* AA con blanco a cualquier tamaño (5.8:1) */
  --amarillo:  #ffd23e;   /* SIEMPRE con texto tinta, jamás con blanco */
  --rojo-txt:  #bf1b12;   /* blanco normal AA (5.9:1) — texto <24px sobre rojo */
  --rojo-d:    #a3160e;
  --azul-d:    #163f8c;
  --azul-noche:#0f265c;   /* respaldo dramático del hero */
  --papel:     #fff7ec;
  --blanco:    #ffffff;
  --texto:     #1b2138;

  --comic-display: "Bangers", system-ui, cursive;
  --comic-text:    "Fredoka", system-ui, -apple-system, sans-serif;

  --esp-1:4px; --esp-2:8px; --esp-3:16px; --esp-4:24px; --esp-5:40px; --esp-6:64px; --esp-7:88px;
  --radio: 12px; --radio-sm: 8px;
  --borde:        3px solid var(--tinta);
  --borde-grueso: 4px solid var(--tinta);
  --pop-sm: 3px 3px 0 var(--tinta);
  --pop:    6px 6px 0 var(--tinta);
  --pop-lg: 9px 9px 0 var(--tinta);
  --pop-2t: 4px 4px 0 var(--rojo), 8px 8px 0 var(--tinta);
  --dot-color: var(--azul); --dot-size: 16px; --dot-r: 1.4px;
  --transicion: .15s ease;
  --ease-pop:   cubic-bezier(.33, 1.28, .5, 1);

  /* --sec-*: tokens de la sección dinámica (alberca) + saludo del invitado —
     SPEC 0006. ADITIVO: solo lo consume secciones.css (compartido); no altera
     el look existente de esta plantilla. */
  --sec-bg:            var(--papel);
  --sec-borde:         var(--tinta);
  --sec-radio:         var(--radio);
  --sec-titulo-font:   var(--comic-display);
  --sec-titulo-color:  var(--azul);
  --sec-texto-color:   var(--texto);
  --sec-acento:        var(--azul);
  --sec-acento-bg:     var(--azul);
  --sec-acento-tinta:  var(--blanco);
  --sec-acento-boton-bg:    var(--amarillo);
  --sec-acento-boton-tinta: var(--tinta);

  /* --portada-*: tokens de la PORTADA DE APERTURA (SPEC 0008). Los consume la
     capa compartida secciones.css con fallback AA; aquí se mapean a la paleta
     cómic. Además esta hoja SOBREESCRIBE .ti-portada con la variante póster. */
  --portada-bg:          var(--azul-noche);
  --portada-tinta:       var(--blanco);
  --portada-acento:      var(--amarillo);
  --portada-titulo-font: var(--comic-display);
  --portada-radio:       var(--radio-sm);
  --portada-cta-bg:      var(--amarillo);
  --portada-cta-tinta:   var(--tinta);
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
[hidden] { display: none !important; }
html { scroll-behavior: smooth; }
body {
  font-family: var(--comic-text);
  font-size: 16px; line-height: 1.6;
  color: var(--texto);
  background-color: var(--papel);
  /* trama de medios tonos Ben-Day muy tenue en toda la página */
  background-image: radial-gradient(var(--dot-color) var(--dot-r), transparent calc(var(--dot-r) + .1px));
  background-size: var(--dot-size) var(--dot-size);
  background-attachment: fixed;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  /* leve deriva de la trama de medios tonos */
  animation: trama-deriva 30s linear infinite;
}
/* velo de papel que suaviza la trama (mejora legibilidad general) */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: var(--papel); opacity: .72;
}
@keyframes trama-deriva {
  0%   { background-position: 0 0; }
  100% { background-position: 32px 32px; }
}
img { max-width: 100%; display: block; }
iframe { border: 0; }

/* Reveal al hacer scroll */
.fade-up { opacity: 0; transform: translateY(22px); transition: opacity .8s ease, transform .8s ease; }
.fade-up.is-visible { opacity: 1; transform: none; }

/* REVEAL DIRECCIONAL — modificadores decorativos de .fade-up; se apoyan en
   .is-visible del observer (motor.js). No tocan el JS ni el .fade-up base. */
.fade-up.reveal--left,
.fade-up.reveal--right,
.fade-up.reveal--pop {
  transition: opacity .7s ease, transform .8s var(--ease-pop);
}
.fade-up.reveal--left  { transform: translateX(-44px) rotate(-2.5deg); }
.fade-up.reveal--right { transform: translateX(44px)  rotate(2.5deg); }
.fade-up.reveal--pop   { transform: scale(.9) rotate(-1.5deg); }
/* settle: gana al estado inicial (0,3,0 > 0,2,0), sin depender del orden */
.fade-up.reveal--left.is-visible,
.fade-up.reveal--right.is-visible,
.fade-up.reveal--pop.is-visible { transform: none; }

/* =========================================================
   HERO — portada de cómic (entrada "slam")
   ========================================================= */
.hero {
  position: relative; isolation: isolate;
  min-height: 100svh;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  padding: var(--esp-6) var(--esp-3);
  /* Fondo PLANO en el propio elemento; el sunburst/halftone/viñeta van en los
     pseudos animados de abajo (::before gira, ::after es la viñeta estática).
     ⚠️ Los pseudos SOLO animan `transform` (rotate) — nunca `opacity` con
     scroll-timeline: la transparencia del título la causaba el parallax con
     opacity (ver "CAUSA RAÍZ" al final), no el sunburst. */
  background: var(--azul-noche);
  color: var(--blanco);
  overflow: hidden;
}
/* estallido de rayos (sunburst) que gira lento — DETRÁS del contenido (z-index -2) */
.hero::before {
  content: ""; position: absolute; inset: -25%; z-index: -2;
  background: repeating-conic-gradient(from 0deg at 50% 42%, var(--azul) 0 7deg, var(--azul-noche) 7deg 14deg);
  animation: girar-lento 120s linear infinite;
}
/* viñeta + medios tonos (halftone) sobre el estallido, estáticos (z-index -1) */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(circle at 50% 40%, transparent 34%, rgba(8,12,28,.62) 100%),
    radial-gradient(rgba(255,255,255,.16) 1.5px, transparent 1.7px);
  background-size: 100% 100%, 13px 13px;
}
.hero__overlay { display: none; } /* el motor/markup puede traerlo; aquí no se usa */

/* z-index:1 fuerza el contenido a su propia capa POR ENCIMA del sunburst
   animado (.hero::before). Sin esto, el fondo animado se compone sobre el
   texto y las letras se ven "transparentes" (el sunburst las atraviesa). */
.hero__contenido { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; }

/* cintillo "masthead" decorativo (opcional en el partial) */
.hero__masthead {
  font-family: var(--comic-text); font-weight: 700;
  font-size: clamp(.7rem, 3vw, .85rem); letter-spacing: .28em; text-transform: uppercase;
  color: var(--amarillo); margin-bottom: var(--esp-2);
  animation: sube-suave .5s ease .05s both;
}
/* líneas de acción detrás del título (opcional en el partial) */
.hero__lineas {
  position: absolute; z-index: -1; pointer-events: none;
  top: 50%; left: 50%; width: 130%; height: 130%;
  transform: translate(-50%, -50%);
  background: repeating-conic-gradient(from 0deg at 50% 50%,
    rgba(255,255,255,.10) 0 2deg, transparent 2deg 8deg);
  -webkit-mask-image: radial-gradient(circle at 50% 50%, transparent 30%, #000 62%);
          mask-image: radial-gradient(circle at 50% 50%, transparent 30%, #000 62%);
}

/* emblema con la inicial (lo llena motor.js → data-rol="hero-sello") */
.emblema {
  width: 76px; height: 76px; margin-bottom: var(--esp-3);
  display: grid; place-items: center;
  background: var(--amarillo); color: var(--tinta);
  border: var(--borde-grueso); border-radius: 50%;
  box-shadow: var(--pop-sm), inset 0 0 0 4px var(--blanco);
  font-family: var(--comic-display); font-size: 2.4rem; line-height: 1;
  transform: rotate(-4deg);
}
.emblema:empty { display: none; }
/* Retrato de héroe: cuando el festejado tiene foto, el motor la inyecta como
   .hero__sello-foto dentro del emblema. Conserva el marco grueso del cómic y
   añade un aro blanco interior (fondo + padding) para el look de viñeta; la foto
   se recorta al círculo (border-radius:inherit, definido en secciones.css). */
.emblema:has(.hero__sello-foto) {
  padding: 4px;
  background: var(--blanco);
  overflow: hidden;
}
/* EDAD en el medallón: el número es el protagonista (Bangers/--comic-display),
   con "AÑOS" pequeño debajo. El sello crece para alojarlo y conserva el marco
   grueso amarillo + aro blanco interior del cómic. Lo pinta motor.js dentro de
   [data-rol="hero-sello"] cuando CFG.edad > 0 (prioridad sobre foto/inicial). */
.emblema:has(.hero__sello-edad) { width: 108px; height: 108px; }
.hero__sello-edad { display: grid; place-items: center; line-height: .78; }
.hero__sello-edad-num {
  font-family: var(--comic-display); font-weight: 400;
  font-size: clamp(2.8rem, 12vw, 3.6rem); line-height: .78; color: var(--tinta);
}
.hero__sello-edad-label {
  font-family: var(--comic-display); font-weight: 400;
  font-size: .8rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--tinta); margin-top: 2px;
}
/* el emblema late suave (vida cómic) */
.emblema { animation: emblema-late 2.6s ease-in-out infinite; }
@keyframes emblema-late {
  0%, 100% { transform: rotate(-4deg) scale(1); }
  50%      { transform: rotate(-4deg) scale(1.08); box-shadow: var(--pop), inset 0 0 0 4px var(--blanco); }
}

.hero__intro {
  display: inline-block;
  font-family: var(--comic-display); font-size: clamp(1.1rem, 5vw, 1.6rem);
  letter-spacing: 1px; color: var(--tinta);
  background: var(--amarillo); border: var(--borde); border-radius: var(--radio-sm);
  padding: .1em .7em; box-shadow: var(--pop-sm);
  transform: rotate(-2deg);
  animation: sube-suave .5s ease .15s both;
}
.hero__nombres {
  font-family: var(--comic-display); font-weight: 400;
  font-size: clamp(3.8rem, 20vw, 8rem); line-height: .9;
  letter-spacing: 2px; color: #ffd23e;
  margin: var(--esp-4) 0 var(--esp-3);
  /* Contorno por text-shadow (robusto en TODOS los navegadores). NO usar -webkit-text-stroke:
     deja las letras huecas/transparentes en algunos navegadores. Relleno sólido por `color`. */
  text-shadow:
    2px 0 0 var(--tinta), -2px 0 0 var(--tinta), 0 2px 0 var(--tinta), 0 -2px 0 var(--tinta),
    2px 2px 0 var(--tinta), -2px -2px 0 var(--tinta), 2px -2px 0 var(--tinta), -2px 2px 0 var(--tinta),
    6px 6px 0 var(--rojo), 9px 9px 0 var(--tinta);
  transform: rotate(-3deg);
  /* Entrada "slam" por TIEMPO (no ligada a scroll): el keyframe termina en
     opacity 1 → sólida al reposar. La transparencia NO venía de aquí sino del
     parallax de scroll-timeline sobre .hero__contenido (ver "CAUSA RAÍZ" abajo). */
  animation: heroe-slam 1.05s var(--ease-pop) both;
}
.hero__amp { display: block; font-size: .4em; color: var(--blanco); }
.hero__sub {
  font-family: var(--comic-text); font-weight: 600;
  font-size: clamp(1rem, 4.4vw, 1.25rem);
  color: var(--blanco); text-shadow: 2px 2px 0 var(--tinta);
  margin-bottom: var(--esp-4);
  animation: sube-suave .5s ease .30s both;
}
/* fecha en banner */
.hero__fecha {
  display: inline-block; font-family: var(--comic-text); font-weight: 700;
  font-size: clamp(.95rem, 4vw, 1.15rem); letter-spacing: 1px;
  color: var(--blanco); background: var(--azul);
  border: var(--borde); border-radius: var(--radio-sm);
  padding: .35em .9em; box-shadow: var(--pop-sm);
  animation: sube-suave .5s ease .42s both;
}
.hero__scroll {
  margin-top: var(--esp-5);
  font-family: var(--comic-display); font-size: 1.2rem; letter-spacing: 1px;
  color: var(--amarillo); text-decoration: none; text-shadow: 2px 2px 0 var(--tinta);
}
.hero__scroll:focus-visible { outline: 3px solid var(--amarillo); outline-offset: 3px; border-radius: 4px; }
.hero__flecha { display: inline-block; animation: rebote 1.6s infinite; }
@keyframes rebote { 0%,100%{transform:translateY(0)} 50%{transform:translateY(7px)} }
@keyframes girar-lento { to { transform: rotate(360deg); } }

/* Decoración de superhéroe (.hero-decor) eliminada a pedido del cliente (v0.15.2). */

/* ─────────────────────────────────────────────────────────────────────────
   PERSONAJES del hero (dato POR INVITACIÓN — CFG.personajes, no de la plantilla)
   Hasta 2 imágenes decorativas que asoman desde las esquinas INFERIORES de la
   portada. Las pinta motor.js (data-rol hero-heroe-1 = IZQ, hero-heroe-2 = DER)
   solo si la invitación trae URLs; por defecto van [hidden]. Se posicionan
   absolutas respecto al .hero (position:relative; overflow:hidden). z-index:2 →
   POR ENCIMA del sunburst (::before, z-index -2); como el título/medallón están
   centrados-arriba, las esquinas de abajo no los tapan. El scroll-hint se sube a
   z-index:3 (regla de abajo) para nunca quedar cubierto. Solo `transform` en las
   animaciones (jamás `opacity` con scroll-timeline — ver CAUSA RAÍZ al final).
   ───────────────────────────────────────────────────────────────────────── */
.hero__heroe {
  position: absolute;
  bottom: 11%;            /* elevados respecto al borde inferior. */
  z-index: 2;
  width: clamp(120px, 34vw, 240px);
  height: auto;
  max-height: 62svh;      /* que no invadan el centro (título/medallón). */
  pointer-events: none;   /* decorativo: no interfiere con toques/enlaces. */
  user-select: none;
  -webkit-user-select: none;
}
/* Anclados a las esquinas; un translate suave hacia afuera los hace "asomar". */
.hero__heroe--izq { left: 0;  transform: translateX(-6%); }
.hero__heroe--der { right: 0; transform: translateX(6%); }

/* El scroll-hint "Ver la misión" (centrado abajo) SIEMPRE por encima de los
   personajes. Regla aditiva (no altera la definición base de .hero__scroll). */
.hero__scroll { position: relative; z-index: 3; }

/* Flote sutil de entrada/vida — SOLO transform (nunca opacity/scroll-timeline).
   El guard global de prefers-reduced-motion (más abajo) lo desactiva. */
@media (prefers-reduced-motion: no-preference) {
  .hero__heroe--izq { animation: heroe-flota-izq 5.5s ease-in-out infinite; }
  .hero__heroe--der { animation: heroe-flota-der 6s   ease-in-out infinite; }
}
@keyframes heroe-flota-izq {
  0%, 100% { transform: translateX(-6%) translateY(0); }
  50%      { transform: translateX(-6%) translateY(-3%); }
}
@keyframes heroe-flota-der {
  0%, 100% { transform: translateX(6%) translateY(0); }
  50%      { transform: translateX(6%) translateY(-3%); }
}
/* En pantallas anchas los personajes crecen (más presencia en la "revista"). */
@media (min-width: 900px) {
  .hero__heroe { width: clamp(240px, 26vw, 340px); max-height: 78svh; }
}

/* =========================================================
   ESTRUCTURA GENERAL — paneles de cómic (viñetas)
   ========================================================= */
main { padding: var(--esp-5) var(--esp-3) var(--esp-6); }
.panel {
  position: relative;
  max-width: 560px; margin: 0 auto var(--esp-6);
  background: var(--blanco);
  border: var(--borde-grueso); border-radius: var(--radio);
  box-shadow: var(--pop-lg);
  padding: var(--esp-6) var(--esp-4) var(--esp-5);
  text-align: center;
}
/* trama de medios tonos en una esquina del panel */
.panel::after {
  content: ""; position: absolute; top: 12px; right: 12px;
  width: 58px; height: 58px; border-radius: 6px; pointer-events: none;
  background-image: radial-gradient(var(--rojo) 2px, transparent 2.3px);
  background-size: 9px 9px; opacity: .28;
}
/* lengüeta amarilla (pestaña de archivador de cómic) en la esquina superior */
.panel::before {
  content: ""; position: absolute; top: -4px; left: 22px;
  width: 52px; height: 12px;
  background: var(--amarillo); border: var(--borde); border-top: none;
  border-radius: 0 0 6px 6px; z-index: 2;
}
.galeria.panel { padding-left: 0; padding-right: 0; overflow: hidden; }
.galeria.panel::before { display: none; }

/* título de sección = caja de rótulo (caption box) */
.seccion__titulo {
  display: inline-block;
  font-family: var(--comic-display); font-weight: 400;
  font-size: clamp(1.9rem, 7.5vw, 2.7rem); letter-spacing: 1px; line-height: 1.05;
  color: var(--tinta); background: var(--amarillo);
  border: var(--borde-grueso); border-radius: var(--radio-sm);
  padding: .12em .6em; box-shadow: var(--pop-sm);
  transform: rotate(-1.5deg);
  margin-bottom: var(--esp-4);
}
/* el divisor del esqueleto no se usa en esta plantilla */
.divisor { display: none; }

/* =========================================================
   SECCIÓN DINÁMICA (alberca) — adopta el look de VIÑETA de cómic.
   El motor la genera como .ti-sec (secciones.css le da la estructura base);
   aquí se le da el MISMO formato que las demás secciones (.panel) de esta
   plantilla: borde grueso, sombra offset, pestaña amarilla, halftone y el
   título en placa amarilla. secciones.css carga antes → estas reglas ganan.
   ========================================================= */
.ti-sec {
  position: relative; max-width: 560px; margin: 0 auto var(--esp-6);
  background: var(--blanco); color: var(--texto);
  border: var(--borde-grueso); border-radius: var(--radio);
  box-shadow: var(--pop-lg);
  padding: var(--esp-6) var(--esp-4) var(--esp-5); text-align: center;
}
.ti-sec::after {
  content: ""; position: absolute; top: 12px; right: 12px;
  width: 58px; height: 58px; border-radius: 6px; pointer-events: none;
  background-image: radial-gradient(var(--rojo) 2px, transparent 2.3px);
  background-size: 9px 9px; opacity: .28;
}
.ti-sec::before {
  content: ""; position: absolute; top: -4px; left: 22px;
  width: 52px; height: 12px; background: var(--amarillo);
  border: var(--borde); border-top: none; border-radius: 0 0 6px 6px; z-index: 2;
}
.ti-sec__titulo {
  display: inline-block; font-family: var(--comic-display); font-weight: 400;
  font-size: clamp(1.9rem, 7.5vw, 2.7rem); letter-spacing: 1px; line-height: 1.05;
  color: var(--tinta); background: var(--amarillo);
  border: var(--borde-grueso); border-radius: var(--radio-sm);
  padding: .12em .6em; box-shadow: var(--pop-sm); transform: rotate(-1.5deg);
  margin-bottom: var(--esp-4);
}
.ti-sec__texto { max-width: 460px; margin: 0 auto; font-weight: 500; color: var(--texto); }

/* =========================================================
   BIENVENIDA
   ========================================================= */
.bienvenida { text-align: center; }
.bienvenida__titulo {
  display: inline-block;
  font-family: var(--comic-display); font-size: clamp(2rem, 8vw, 3rem);
  color: var(--blanco); background: var(--azul);
  border: var(--borde); border-radius: var(--radio-sm); padding: .1em .5em;
  box-shadow: var(--pop-sm); transform: rotate(-2deg);
  text-shadow: 2px 2px 0 var(--tinta); margin-bottom: var(--esp-3);
}
.bienvenida__texto {
  max-width: 480px; margin: 0 auto; font-size: 1.12rem; font-weight: 500;
  color: var(--texto);
}

/* =========================================================
   CUENTA REGRESIVA — fichas (con latido al entrar)
   ========================================================= */
.contador__lista { list-style: none; display: flex; gap: var(--esp-2); justify-content: center; flex-wrap: wrap; }
.contador__item {
  background: var(--azul); color: var(--blanco);
  border: var(--borde); border-radius: var(--radio-sm); box-shadow: var(--pop-sm);
  min-width: 70px; padding: var(--esp-2) var(--esp-2) var(--esp-1);
}
.contador.fade-up.is-visible .contador__item { animation: ficha-late 2.4s ease-in-out infinite; }
.contador.fade-up.is-visible .contador__item:nth-child(2) { animation-delay: .15s; }
.contador.fade-up.is-visible .contador__item:nth-child(3) { animation-delay: .30s; }
.contador.fade-up.is-visible .contador__item:nth-child(4) { animation-delay: .45s; }
.contador__num {
  display: block; font-family: var(--comic-display); font-size: clamp(1.9rem, 8vw, 2.6rem);
  line-height: 1; color: #ffd23e;
  text-shadow: 1.5px 0 0 var(--tinta), -1.5px 0 0 var(--tinta), 0 1.5px 0 var(--tinta), 0 -1.5px 0 var(--tinta), 1.5px 1.5px 0 var(--tinta), -1.5px -1.5px 0 var(--tinta), 1.5px -1.5px 0 var(--tinta), -1.5px 1.5px 0 var(--tinta);
}
.contador__label {
  display: block; margin-top: 2px; font-family: var(--comic-text); font-weight: 600;
  font-size: .62rem; text-transform: uppercase; letter-spacing: .1em; color: var(--blanco);
}

/* =========================================================
   EVENTO (La gran fiesta) + MAPA
   ========================================================= */
.evento__hora {
  display: inline-block; font-family: var(--comic-text); font-weight: 700;
  font-size: 1rem; letter-spacing: .04em; color: var(--blanco);
  background: var(--azul); border: var(--borde); border-radius: 6px;
  padding: .15em .6em; box-shadow: var(--pop-sm); margin-bottom: var(--esp-3);
}
.evento__lugar { font-family: var(--comic-display); font-size: clamp(1.6rem, 6vw, 2.2rem); color: var(--azul); line-height: 1.05; text-shadow: 1px 0 0 var(--tinta), -1px 0 0 var(--tinta), 0 1px 0 var(--tinta), 0 -1px 0 var(--tinta), 1px 1px 0 var(--tinta), -1px -1px 0 var(--tinta); }
.evento__direccion { font-weight: 500; color: var(--texto); margin: var(--esp-2) 0 var(--esp-4); }
.evento__mapa { border: var(--borde); border-radius: var(--radio-sm); overflow: hidden; box-shadow: var(--pop-sm); }
.evento__mapa iframe { width: 100%; height: 280px; display: block; }
.boton-accion, .evento__boton, .mesa-regalos__link, .hospedaje__link {
  display: inline-block; margin-top: var(--esp-4);
  font-family: var(--comic-display); font-size: 1.1rem; letter-spacing: 1px;
  color: var(--blanco); background: var(--azul); text-decoration: none;
  border: var(--borde); border-radius: var(--radio-sm); padding: .3em .9em;
  box-shadow: var(--pop); transition: transform var(--transicion), box-shadow var(--transicion);
}
.boton-accion:hover, .evento__boton:hover, .mesa-regalos__link:hover, .hospedaje__link:hover { transform: translate(-1px,-1px); box-shadow: var(--pop-lg); }
.boton-accion:active, .evento__boton:active, .mesa-regalos__link:active, .hospedaje__link:active { transform: translate(2px,2px); box-shadow: 2px 2px 0 var(--tinta); }
.boton-accion:focus-visible, .evento__boton:focus-visible, .mesa-regalos__link:focus-visible, .hospedaje__link:focus-visible { outline: 3px solid var(--azul); outline-offset: 3px; }

/* =========================================================
   ITINERARIO — "plan de la misión" numerado
   ========================================================= */
.itinerario__lista { list-style: none; max-width: 440px; margin: 0 auto; text-align: left; counter-reset: mis; }
.itinerario__item {
  display: grid; grid-template-columns: 40px 86px 1fr; align-items: center; gap: var(--esp-2);
  padding: var(--esp-3) 0; border-bottom: 2px dashed var(--azul);
}
.itinerario__item:last-child { border-bottom: none; }
.itinerario__item::before {
  counter-increment: mis; content: counter(mis);
  width: 34px; height: 34px; display: grid; place-items: center;
  font-family: var(--comic-display); font-size: 1.2rem; color: var(--tinta);
  background: var(--amarillo); border: var(--borde); border-radius: 50%;
  box-shadow: var(--pop-sm);
}
.itinerario__hora { font-family: var(--comic-display); font-size: 1.15rem; color: var(--azul); }
.itinerario__actividad { font-weight: 500; color: var(--texto); }

/* =========================================================
   DRESS CODE — "tu disfraz"
   ========================================================= */
.dress-code__descripcion { max-width: 460px; margin: 0 auto var(--esp-4); font-weight: 500; }
.dress-code__colores { display: flex; flex-wrap: wrap; gap: var(--esp-2); justify-content: center; }
.dress-code__color { width: 42px; height: 42px; border-radius: 50%; border: var(--borde); box-shadow: var(--pop-sm); display: inline-block; }

/* =========================================================
   MESA DE REGALOS
   ========================================================= */
.mesa-regalos__mensaje { max-width: 460px; margin: 0 auto var(--esp-4); font-weight: 500; }
.mesa-regalos__lista { display: flex; flex-wrap: wrap; gap: var(--esp-3); justify-content: center; }
.mesa-regalos__link { margin-top: 0; background: var(--azul); }

/* =========================================================
   GALERÍA — tira de cómic
   ========================================================= */
.galeria { }
.carrusel { position: relative; }
.carrusel__track { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.carrusel__track::-webkit-scrollbar { display: none; }
.carrusel__slide { flex: 0 0 86%; scroll-snap-align: center; padding: 0 var(--esp-1); }
.carrusel__slide img { width: 100%; aspect-ratio: 4/5; object-fit: cover; border: var(--borde); border-radius: 8px; box-shadow: var(--pop-sm); cursor: zoom-in; }
.carrusel__nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 44px; height: 44px; border-radius: 50%; border: var(--borde);
  background: var(--amarillo); color: var(--tinta); font-family: var(--comic-display); font-size: 1.5rem; line-height: 1;
  cursor: pointer; display: grid; place-items: center; box-shadow: var(--pop-sm);
}
.carrusel__nav:focus-visible { outline: 3px solid var(--azul); outline-offset: 2px; }
.carrusel__nav--prev { left: 8px; }
.carrusel__nav--next { right: 8px; }
.carrusel__dots { display: flex; justify-content: center; gap: 8px; margin-top: var(--esp-4); }
.carrusel__dot { width: 12px; height: 12px; border: 2px solid var(--tinta); background: var(--blanco); border-radius: 50%; padding: 0; cursor: pointer; }
.carrusel__dot:focus-visible { outline: 3px solid var(--azul); outline-offset: 2px; }
.carrusel__dot.is-active { background: var(--azul); }

/* Lightbox */
.lightbox { position: fixed; inset: 0; z-index: 50; display: flex; align-items: center; justify-content: center; background: rgba(10,14,30,.92); padding: var(--esp-3); opacity: 0; visibility: hidden; transition: opacity var(--transicion); }
.lightbox.is-open { opacity: 1; visibility: visible; }
.lightbox__img { max-width: 100%; max-height: 85vh; border: var(--borde); border-radius: 8px; }
.lightbox__cerrar { position: absolute; top: var(--esp-3); right: var(--esp-3); background: var(--amarillo); border: var(--borde); border-radius: 50%; width: 44px; height: 44px; color: var(--tinta); font-size: 1.6rem; cursor: pointer; line-height: 1; }
.lightbox__nav { position: absolute; top: 50%; transform: translateY(-50%); background: var(--amarillo); border: var(--borde); border-radius: 50%; width: 44px; height: 44px; color: var(--tinta); font-size: 1.6rem; cursor: pointer; }
.lightbox__cerrar:focus-visible, .lightbox__nav:focus-visible { outline: 3px solid var(--blanco); outline-offset: 2px; }
.lightbox__nav--prev { left: var(--esp-2); }
.lightbox__nav--next { right: var(--esp-2); }

/* =========================================================
   RSVP — "¿aceptas la misión?"
   ========================================================= */
.rsvp__nota { font-weight: 500; color: var(--texto); margin-bottom: var(--esp-4); }
.rsvp__form { max-width: 420px; margin: 0 auto; text-align: left; }
.rsvp__auto { margin: calc(-1 * var(--esp-2)) 0 var(--esp-3); font-size: .82rem; font-weight: 500; color: var(--azul); }
.campo { margin-bottom: var(--esp-3); border: none; }
.campo__label { display: block; margin-bottom: var(--esp-1); font-family: var(--comic-text); font-weight: 700; font-size: .9rem; color: var(--tinta); }
.campo__input {
  width: 100%; padding: var(--esp-2) var(--esp-3); font-family: var(--comic-text); font-size: 1rem; color: var(--texto);
  background: var(--papel); border: var(--borde); border-radius: 8px;
}
.campo__input:focus-visible { outline: 3px solid var(--azul); outline-offset: 2px; border-color: var(--azul); }
.rsvp__opciones { display: flex; flex-direction: column; gap: var(--esp-2); }
.rsvp__radio { display: flex; align-items: center; gap: var(--esp-2); cursor: pointer; font-weight: 500; accent-color: var(--azul); min-height: 44px; padding: 6px 0; }
.rsvp__radio input { accent-color: var(--azul); width: 18px; height: 18px; }
.boton {
  display: block; width: 100%; margin-top: var(--esp-3);
  font-family: var(--comic-display); font-size: 1.5rem; letter-spacing: 1px;
  color: var(--blanco); background: var(--azul);
  border: var(--borde); border-radius: var(--radio); padding: .4em;
  box-shadow: var(--pop); cursor: pointer;
  transition: transform var(--transicion), box-shadow var(--transicion);
}
.boton:hover { transform: translate(-1px,-1px); box-shadow: var(--pop-lg); }
.boton:active { transform: translate(3px,3px); box-shadow: 2px 2px 0 var(--tinta); }
.boton:focus-visible { outline: 3px solid var(--azul); outline-offset: 3px; }
.boton:disabled { opacity: .6; cursor: default; box-shadow: var(--pop-sm); transform: none; }
.rsvp__estado { margin-top: var(--esp-3); text-align: center; font-weight: 700; min-height: 1.4em; }
.rsvp__estado--ok { color: var(--azul); }
.rsvp__estado--error { color: var(--rojo-d); }

/* =========================================================
   MÚSICA (botón flotante)
   ========================================================= */
.musica { position: fixed; bottom: var(--esp-3); right: var(--esp-3); z-index: 40; width: 52px; height: 52px; border-radius: 50%; border: var(--borde); background: var(--amarillo); color: var(--tinta); box-shadow: var(--pop-sm); cursor: pointer; display: grid; place-items: center; font-size: 1.4rem; }
.musica:focus-visible { outline: 3px solid var(--azul); outline-offset: 2px; }
.musica[aria-pressed="true"] .musica__icono { animation: girar 3s linear infinite; }
@keyframes girar { to { transform: rotate(360deg); } }

/* =========================================================
   PIE — colofón de cómic
   ========================================================= */
.pie {
  text-align: center; padding: var(--esp-6) var(--esp-3) calc(var(--esp-6) + 60px);
  background: var(--tinta); color: var(--blanco);
  background-image: radial-gradient(rgba(255,255,255,.10) 1.5px, transparent 1.6px);
  background-size: 14px 14px;
}
.pie__nombres { font-family: var(--comic-display); font-size: 2.6rem; color: #ffd23e; text-shadow: 2px 0 0 #000, -2px 0 0 #000, 0 2px 0 #000, 0 -2px 0 #000, 2px 2px 0 #000, -2px -2px 0 #000, 2px -2px 0 #000, -2px 2px 0 #000; letter-spacing: 1px; }
.pie__fecha { font-family: var(--comic-text); font-weight: 600; letter-spacing: .04em; margin: var(--esp-2) 0 var(--esp-3); }
/* AA: rojo normal sobre tinta falla → el crédito va en amarillo (10:1 sobre tinta). */
.pie__credito { font-family: var(--comic-display); font-size: 1.1rem; letter-spacing: 1px; color: var(--amarillo); }

/* =========================================================
   BARRA DE PREVIEW (dev)
   ========================================================= */
.preview { position: fixed; bottom: 0; left: 0; right: 0; z-index: 60; background: rgba(20,18,16,.95); color: #fff; padding: var(--esp-2) var(--esp-3); display: flex; gap: var(--esp-4); flex-wrap: wrap; justify-content: center; font-family: system-ui, sans-serif; }
.preview__chip { background: rgba(255,255,255,.12); color: #fff; border: 1px solid transparent; padding: 4px 10px; border-radius: 999px; font-size: .8rem; cursor: pointer; }
.preview__chip.is-active { background: #fff; color: #111; }

/* =========================================================
   ESTALLIDOS DE ACCIÓN — "POW! / ZAP! / BOOM!"
   Markup decorativo (aria-hidden) en los paneles. Aparecen con
   POP (scale + rotación) cuando la sección entra (.fade-up.is-visible).
   ========================================================= */
.estallido {
  position: absolute; z-index: 3; pointer-events: none;
  display: grid; place-items: center;
  width: 84px; height: 84px;
  font-family: var(--comic-display); font-weight: 400; line-height: 1;
  font-size: 1.45rem; letter-spacing: .5px; text-align: center;
  /* base azul con palabra amarilla — el contorno de tinta (text-shadow) garantiza
     legibilidad a cualquier tamaño (no depende del contraste fondo/texto). */
  color: var(--amarillo); background: var(--azul);
  border: var(--borde);
  text-shadow: 1px 0 0 var(--tinta), -1px 0 0 var(--tinta), 0 1px 0 var(--tinta), 0 -1px 0 var(--tinta), 2px 2px 0 var(--tinta);
  /* forma de estrella/estallido recortada */
  clip-path: polygon(50% 0%, 61% 22%, 86% 13%, 78% 39%, 100% 50%, 78% 61%, 86% 87%, 61% 78%, 50% 100%, 39% 78%, 14% 87%, 22% 61%, 0% 50%, 22% 39%, 14% 13%, 39% 22%);
  /* estado de reposo: oculto y "desinflado" hasta que la sección se revela */
  opacity: 0; transform: scale(.2) rotate(-18deg);
  transition: opacity .35s ease, transform .45s cubic-bezier(.33, 1.28, .5, 1);
}
.estallido--azul     { background: var(--azul);     color: var(--blanco); }
.estallido--amarillo { background: var(--amarillo); color: var(--tinta); text-shadow: 2px 2px 0 var(--blanco); }
/* posiciones (se asoman fuera del panel, contenidas por overflow-x del body) */
.estallido--tl { top: -26px; left: -18px; }
.estallido--tr { top: -22px; right: -14px; }
.estallido--br { bottom: -24px; right: -10px; }
.estallido--bl { bottom: -22px; left: -14px; }
.estallido--sm { width: 64px; height: 64px; font-size: 1.05rem; }
/* POP al revelar la sección */
.fade-up.is-visible .estallido {
  opacity: 1;
  transform: scale(1) rotate(var(--giro, -8deg));
  animation: estallido-vibra 3.4s ease-in-out .5s infinite;
}
.estallido--tr, .estallido--br { --giro: 7deg; }
@keyframes estallido-vibra {
  0%, 92%, 100% { transform: scale(1) rotate(var(--giro, -8deg)); }
  95%           { transform: scale(1.1) rotate(calc(var(--giro, -8deg) - 4deg)); }
}

/* =========================================================
   STAGGER DE HIJOS — cascadas en cascada al revelar el panel.
   Los hijos los crea el motor; se alcanzan por descendencia del panel
   padre con .is-visible (CSS puro, sin tocar motor.js). Cap a 6 pasos.
   ========================================================= */
/* Itinerario: pasos desde la izquierda en cascada */
.itinerario.fade-up .itinerario__item { opacity: 0; transform: translateX(-16px); transition: opacity .55s ease, transform .55s var(--ease-pop); }
.itinerario.fade-up.is-visible .itinerario__item { opacity: 1; transform: none; transition-delay: .40s; } /* cap ítems 7+ */
.itinerario.fade-up.is-visible .itinerario__item:nth-child(1) { transition-delay: .06s; }
.itinerario.fade-up.is-visible .itinerario__item:nth-child(2) { transition-delay: .12s; }
.itinerario.fade-up.is-visible .itinerario__item:nth-child(3) { transition-delay: .18s; }
.itinerario.fade-up.is-visible .itinerario__item:nth-child(4) { transition-delay: .24s; }
.itinerario.fade-up.is-visible .itinerario__item:nth-child(5) { transition-delay: .30s; }
.itinerario.fade-up.is-visible .itinerario__item:nth-child(6) { transition-delay: .36s; }

/* Dress-code: swatches "pop" en secuencia */
.dress-code.fade-up .dress-code__color { opacity: 0; transform: scale(.4); transition: opacity .45s ease, transform .5s var(--ease-pop); }
.dress-code.fade-up.is-visible .dress-code__color { opacity: 1; transform: none; }
.dress-code.fade-up.is-visible .dress-code__color:nth-child(1) { transition-delay: .10s; }
.dress-code.fade-up.is-visible .dress-code__color:nth-child(2) { transition-delay: .18s; }
.dress-code.fade-up.is-visible .dress-code__color:nth-child(3) { transition-delay: .26s; }
.dress-code.fade-up.is-visible .dress-code__color:nth-child(4) { transition-delay: .34s; }
.dress-code.fade-up.is-visible .dress-code__color:nth-child(5) { transition-delay: .42s; }

/* Mesa de regalos: enlaces desde abajo en cascada */
.mesa-regalos.fade-up .mesa-regalos__link { opacity: 0; transform: translateY(14px); transition: opacity .5s ease, transform .55s var(--ease-pop); }
.mesa-regalos.fade-up.is-visible .mesa-regalos__link { opacity: 1; transform: none; }
.mesa-regalos.fade-up.is-visible .mesa-regalos__link:nth-child(1) { transition-delay: .08s; }
.mesa-regalos.fade-up.is-visible .mesa-regalos__link:nth-child(2) { transition-delay: .16s; }
.mesa-regalos.fade-up.is-visible .mesa-regalos__link:nth-child(3) { transition-delay: .24s; }
.mesa-regalos.fade-up.is-visible .mesa-regalos__link:nth-child(4) { transition-delay: .32s; }

/* Galería (bajo perfil): solo opacidad, NO translate (no pelear con scroll-snap) */
.galeria.fade-up .carrusel__slide { opacity: 0; transition: opacity .55s ease; }
.galeria.fade-up.is-visible .carrusel__slide { opacity: 1; }
.galeria.fade-up.is-visible .carrusel__slide:nth-child(1) { transition-delay: .08s; }
.galeria.fade-up.is-visible .carrusel__slide:nth-child(2) { transition-delay: .18s; }
.galeria.fade-up.is-visible .carrusel__slide:nth-child(3) { transition-delay: .28s; }

/* =========================================================
   MICROINTERACCIONES
   ========================================================= */
/* a) Título de sección tipo "sello/estampa" (baseline rotate(-1.5deg) preservado) */
@keyframes sello-estampa {
  0%   { opacity: 0; transform: rotate(-1.5deg) scale(1.4); }
  60%  { opacity: 1; transform: rotate(-1.5deg) scale(.94); }
  100% {            transform: rotate(-1.5deg) scale(1); }
}
.fade-up.is-visible .seccion__titulo { animation: sello-estampa .6s var(--ease-pop) both; }

/* b) Fotos galería — zoom + tilt en hover/focus (solo transform) */
.carrusel__slide img { transition: transform .3s var(--ease-pop), box-shadow .3s ease; }
.carrusel__slide img:hover,
.carrusel__slide img:focus-visible { transform: scale(1.04) rotate(-1.2deg); box-shadow: var(--pop); }

/* c) Botón música — pulso que invita, solo cuando NO suena; se detiene en hover */
@keyframes musica-invita {
  0%,100% { transform: scale(1);    box-shadow: var(--pop-sm); }
  50%     { transform: scale(1.08); box-shadow: var(--pop); }
}
.musica:not([aria-pressed="true"]) { animation: musica-invita 2.8s ease-in-out 2s infinite; }
.musica:hover { animation: none; transform: scale(1.08); }

/* =========================================================
   SALUDO — bocadillo de cómic personalizado (?i=codigo)
   Clases FIJAS que inyecta el motor (motor.js): .saludo > .saludo__hola,
   .saludo__pases. El .saludo se inserta como PRIMER hijo de <main id="detalles">.
   Todo se ancla a #detalles: el fallback compartido secciones.css estiliza
   .saludo (specificity 0,1,0), así que un selector con ID (0,1,1) gana siempre
   por especificidad —independiente del orden de carga— sin !important, sin
   tocar el JS, sin afectar a las otras 14 plantillas. (SPEC 0006: el motor ya
   NO inyecta <style id="estilo-invitado">; su estilo lo sirve secciones.css o
   el .saludo nativo de cada plantilla.)
   ========================================================= */
#detalles .saludo {
  position: relative; max-width: 560px; margin: 0 auto var(--esp-6);
  background: var(--blanco); color: var(--texto);
  border: var(--borde-grueso); border-radius: var(--radio);
  box-shadow: var(--pop-lg); padding: var(--esp-5) var(--esp-4); text-align: center;
  animation: bocadillo-pop .65s var(--ease-pop) both; transform: rotate(-1deg);
}
/* cola del bocadillo (contorno tinta + relleno blanco) */
#detalles .saludo::before {
  content: ""; position: absolute; top: -18px; left: 38px; width: 0; height: 0;
  border-left: 16px solid transparent; border-right: 16px solid transparent;
  border-bottom: 18px solid var(--tinta); pointer-events: none;
}
#detalles .saludo::after {
  content: ""; position: absolute; top: -11px; left: 41px; width: 0; height: 0;
  border-left: 13px solid transparent; border-right: 13px solid transparent;
  border-bottom: 14px solid var(--blanco); pointer-events: none;
}
#detalles .saludo__hola {
  font-family: var(--comic-display); font-weight: 400; font-size: clamp(1.9rem, 7vw, 2.6rem);
  line-height: 1.05; letter-spacing: 1px; color: var(--tinta); text-shadow: 2px 2px 0 var(--azul);
}
#detalles .saludo__pases {
  margin-top: var(--esp-2); font-family: var(--comic-text); font-weight: 600;
  font-size: 1.1rem; letter-spacing: .02em; color: var(--texto);
}

/* =========================================================
   MICROANIMACIONES — keyframes (disparador = IntersectionObserver
   EXISTENTE del motor.js vía .fade-up.is-visible; no se duplica aquí)
   ========================================================= */
@keyframes heroe-slam {
  0%   { opacity: 0; transform: rotate(-3deg) scale(1.4); }
  55%  { opacity: 1; transform: rotate(-3deg) scale(.93); }
  78%  { transform: rotate(-3deg) scale(1.05); }
  100% { transform: rotate(-3deg) scale(1); }
}
@keyframes sube-suave { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes ficha-late { 0%,70%,100% { transform: scale(1); } 80% { transform: scale(1.09); } 90% { transform: scale(.98); } }
@keyframes bocadillo-pop {
  0%   { opacity: 0; transform: scale(.85) rotate(-1deg); }
  70%  { opacity: 1; transform: scale(1.03) rotate(-1deg); }
  100% { transform: scale(1) rotate(-1deg); }
}

/* ─────────────────────────────────────────────────────────────────────────
   CAUSA RAÍZ del "título transparente" (resuelto v0.14.5) — LEER ANTES DE TOCAR:
   El culpable era una `opacity` DENTRO de una animación de scroll-timeline sobre
   .hero__contenido. La versión anterior usaba
       animation-timeline: view(); animation-range: cover 0% cover 60%;
       @keyframes heroe-parallax { to { transform: translateY(-8%); opacity: .7; } }
   Como el hero mide 100svh, AL CARGAR el elemento ya está muy avanzado en ese
   rango (~83%), así que el fade a opacity .7 se aplicaba DESDE EL INICIO (todo el
   contenido, título incluido, a ~0.75 de opacidad) sin necesidad de hacer scroll.
   No lo reproduce Chrome headless con --disable-gpu (no implementa scroll-driven
   animations); solo navegadores reales con GPU → por eso costó tanto verlo.

   REGLA DURA: una animación sobre el contenido del hero puede MOVER (transform)
   pero NUNCA debe tocar `opacity` con un scroll-timeline. La versión segura de
   abajo respeta eso: solo transform, y acotada a la fase `exit` (arranca cuando el
   hero empieza a SALIR del viewport, no al cargar) → imposible que dé transparencia.
   ───────────────────────────────────────────────────────────────────────── */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .hero__contenido {
      animation: heroe-parallax linear both;
      animation-timeline: view();
      animation-range: exit 0% exit 100%; /* solo al salir el hero, no al cargar */
    }
    /* SOLO transform — jamás `opacity` aquí (ver CAUSA RAÍZ arriba). */
    @keyframes heroe-parallax { to { transform: translateY(-6%); } }
  }
}

/* =========================================================
   PORTADA DE APERTURA — variante CÓMIC (SPEC 0008)
   ---------------------------------------------------------
   La CREA motor.js (initPortada) con la estructura del contrato §4.1; el
   andamiaje base (position/fallbacks) viene de secciones.css (que carga ANTES,
   así estas reglas ganan por cascada sin !important). Aquí se le da el look de
   PÓSTER de cómic: sunburst + trama Ben-Day (reusa el lenguaje del hero), nombre
   en Bangers con contorno por text-shadow (NUNCA -webkit-text-stroke). Concepto
   "sobre dirigido al invitado": masthead "EDICIÓN ESPECIAL" + emblema + título de
   estado + NOMBRE DEL INVITADO (protagonista) + CTA "¡ÁBRELA!". NO muestra el
   festejado/edad/fecha (eso lo revela el hero al abrir — no se repite).
   Animación de apertura robusta (solo transform/opacity, composited): la portada
   sube + escala y se desvanece con un POP del CTA. NO toca el hero.
   ========================================================= */
.ti-portada {
  background: var(--azul-noche);
  color: var(--blanco);
  /* Sube el bloque respecto al centro exacto (se veía "bajo"): más aire abajo. */
  padding-bottom: clamp(64px, 15vh, 150px);
}
/* estallido de rayos girando lento — detrás de todo (mismo recurso que el hero) */
.ti-portada::before {
  content: ""; position: absolute; inset: -25%; z-index: 0; pointer-events: none;
  background: repeating-conic-gradient(from 0deg at 50% 44%, var(--azul) 0 7deg, var(--azul-noche) 7deg 14deg);
  animation: girar-lento 120s linear infinite;
}
/* viñeta + medios tonos (halftone), estáticos, sobre el estallido */
.ti-portada::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(circle at 50% 42%, transparent 32%, rgba(8,12,28,.66) 100%),
    radial-gradient(rgba(255,255,255,.16) 1.5px, transparent 1.7px);
  background-size: 100% 100%, 13px 13px;
}
/* el contenido, por encima del estallido/halftone */
.ti-portada__lienzo {
  position: relative; z-index: 1;
  gap: var(--esp-2);
  max-width: 620px;
}

/* (masthead "EDICIÓN ESPECIAL" retirado a pedido del cliente: hereda el
   display:none del fallback base de secciones.css.) */

/* emblema decorativo: estallido amarillo (guiño de cómic, sin la edad). */
.ti-portada__emblema {
  display: block; width: 76px; height: 76px; margin: 2px auto;
  background: var(--amarillo);
  clip-path: polygon(50% 0%, 61% 22%, 86% 13%, 78% 39%, 100% 50%, 78% 61%, 86% 87%, 61% 78%, 50% 100%, 39% 78%, 14% 87%, 22% 61%, 0% 50%, 22% 39%, 14% 13%, 39% 22%);
  filter: drop-shadow(3px 3px 0 var(--tinta));
}

/* título de ESTADO ("¡Estás invitado!" / "¡Tienes una invitación!"). */
.ti-portada__titulo {
  font-family: var(--comic-display); font-weight: 400;
  font-size: clamp(1.7rem, 7.4vw, 2.6rem); line-height: 1.02; letter-spacing: 1px;
  color: var(--blanco); text-shadow: 3px 3px 0 var(--tinta);
  transform: rotate(-1.5deg);
}

/* destinatario ("PARA <nombre>") retirado a pedido del cliente: la portada no
   muestra para quién es. Se oculta el contenedor (el motor sigue creándolo, inerte). */
.ti-portada__invitado { display: none; }

.ti-portada__mensaje {
  font-family: var(--comic-text); font-weight: 600;
  color: var(--blanco); text-shadow: 2px 2px 0 var(--tinta); opacity: 1;
  max-width: 28ch;
}

/* CTA "¡ÁBRELA!" tipo botón cómic, con estallido detrás */
.ti-portada__cta {
  position: relative; margin-top: var(--esp-3);
  font-family: var(--comic-display); font-weight: 400;
  font-size: clamp(1.95rem, 8.4vw, 2.7rem); letter-spacing: 1px;
  color: var(--blanco); background: var(--rojo);
  border: var(--borde-grueso); border-radius: var(--radio);
  padding: .25em .9em; box-shadow: var(--pop);
  transform: rotate(-1.5deg);
  transition: transform var(--transicion), box-shadow var(--transicion);
}
.ti-portada__cta::before {
  content: ""; position: absolute; inset: -14px -22px; z-index: -1; pointer-events: none;
  background: var(--amarillo);
  clip-path: polygon(50% 0%, 61% 22%, 86% 13%, 78% 39%, 100% 50%, 78% 61%, 86% 87%, 61% 78%, 50% 100%, 39% 78%, 14% 87%, 22% 61%, 0% 50%, 22% 39%, 14% 13%, 39% 22%);
  opacity: .9;
}
.ti-portada__cta:hover { transform: rotate(-1.5deg) translate(-1px,-1px); box-shadow: var(--pop-lg); }
.ti-portada__cta:active { transform: rotate(-1.5deg) translate(2px,2px); box-shadow: var(--pop-sm); }
.ti-portada__cta:focus-visible { outline: 3px solid var(--blanco); outline-offset: 3px; }

/* ANIMACIÓN DE APERTURA — sube + escala + fundido (composited); POP del CTA.
   Solo transform/opacity en la PROPIA capa; jamás toca el hero. */
.ti-portada__lienzo { transition: transform .6s var(--ease-pop), opacity .5s ease; }
.ti-portada--abriendo { opacity: 0; transition: opacity .55s ease .05s; }
.ti-portada--abriendo .ti-portada__lienzo {
  transform: translateY(-40px) scale(1.12) rotate(-2deg); opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .ti-portada--abriendo .ti-portada__cta { animation: ti-portada-cta-pop .35s var(--ease-pop) both; }
  @keyframes ti-portada-cta-pop {
    0%   { transform: rotate(-1.5deg) scale(1); }
    40%  { transform: rotate(-1.5deg) scale(1.18); }
    100% { transform: rotate(-1.5deg) scale(.6); opacity: 0; }
  }
  /* el CTA "invita" con un latido suave (cesa al abrir) */
  .ti-portada:not(.ti-portada--abriendo) .ti-portada__cta { animation: ti-portada-late 2.6s ease-in-out infinite; }
  @keyframes ti-portada-late {
    0%,100% { box-shadow: var(--pop); transform: rotate(-1.5deg) scale(1); }
    50%     { box-shadow: var(--pop-lg); transform: rotate(-1.5deg) scale(1.05); }
  }
}
/* Reduced-motion: el reset global (* { transition:none !important }) mataría la
   transición y la revelación caería al timeout de respaldo (1.4 s). Restauramos
   un fundido corto (mayor especificidad que `*`) para revelar rápido, sin giros. */
@media (prefers-reduced-motion: reduce) {
  .ti-portada { transition: opacity .2s linear !important; }
  .ti-portada__lienzo { transition: opacity .2s linear !important; transform: none !important; }
  .ti-portada--abriendo .ti-portada__lienzo { transform: none !important; opacity: 0; }
  .ti-portada::before { animation: none !important; }
}

/* =========================================================
   RESPONSIVE
   ========================================================= */
@media (min-width: 768px) {
  main { padding-top: var(--esp-6); }
  .panel { max-width: 620px; padding: var(--esp-6) var(--esp-5); }
  .carrusel__slide { flex: 0 0 60%; }
  .carrusel__slide img { aspect-ratio: 16/10; }
  .evento__mapa iframe { height: 340px; }
}

/* ─────────────────────────────────────────────────────────────────────────
   ESCRITORIO (≥900px) — "REVISTA DE CÓMIC ABIERTA"
   En PC el contenido dejaba de leerse como una tira angosta perdida entre
   márgenes vacíos: el <main id="detalles"> se vuelve una HOJA DE PAPEL central
   (marco de tinta grueso + sombra pop) flotando sobre una "mesa" azul marino
   (el velo body::before se tiñe de azul-noche). Las viñetas (.panel/.ti-sec/
   saludo) se ensanchan a un ancho legible y el evento reparte texto | mapa en
   dos columnas. El HERO se queda full-width (no se toca). MÓVIL no cambia.
   ───────────────────────────────────────────────────────────────────────── */
@media (min-width: 900px) {
  /* La "mesa": el velo de papel pasa a azul marino para que la hoja resalte. */
  body::before { background: var(--azul-noche); opacity: .94; }

  /* La HOJA de la revista: papel enmarcado, centrado, sobre la mesa azul. */
  main {
    max-width: 920px;
    margin: var(--esp-6) auto var(--esp-6);
    padding: var(--esp-6) var(--esp-6) var(--esp-5);
    background: var(--papel);
    border: var(--borde-grueso);
    border-radius: var(--radio);
    box-shadow: var(--pop-lg);
    background-image: radial-gradient(var(--dot-color) var(--dot-r), transparent calc(var(--dot-r) + .1px));
    background-size: var(--dot-size) var(--dot-size);
  }

  /* Viñetas más anchas pero con medida de lectura contenida por los max-width
     internos de cada bloque de texto (.bienvenida__texto, .ti-sec__texto…). */
  .panel,
  .ti-sec,
  #detalles .saludo { max-width: 760px; }

  /* EVENTO en dos columnas: datos a la izquierda, mapa al lado (columna derecha
     que ocupa toda la altura). El título ocupa el ancho completo arriba. */
  .evento.panel {
    display: grid;
    grid-template-columns: 1.05fr .95fr;
    column-gap: var(--esp-5); row-gap: var(--esp-2);
    align-items: start; text-align: left;
  }
  .evento.panel > .seccion__titulo {
    grid-column: 1 / -1; justify-self: center; text-align: center;
    margin-bottom: var(--esp-3);
  }
  .evento__hora, .evento__lugar, .evento__direccion { grid-column: 1; }
  /* el chip de hora se blockifica como grid item: que hugue su contenido. */
  .evento__hora { justify-self: start; }
  .evento__boton { grid-column: 1; justify-self: start; margin-top: var(--esp-3); }
  .evento__mapa {
    grid-column: 2; grid-row: 2 / span 5; align-self: start;
    margin: 0;
  }
  .evento__mapa iframe { height: 360px; }

  /* La galería puede lucir más aire en la hoja ancha. */
  .carrusel__slide { flex: 0 0 46%; }
}

/* =========================================================
   ACCESIBILIDAD — prefers-reduced-motion
   ========================================================= */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .fade-up { opacity: 1; transform: none; }
  .hero__nombres { transform: rotate(-3deg); opacity: 1; }
  .hero__intro, .hero__sub, .hero__fecha { opacity: 1; transform: none; }
  .hero__masthead { opacity: 1; }
  .emblema { transform: rotate(-4deg); }
  /* los estallidos quedan visibles y quietos (POW estáticos) */
  .estallido { opacity: 1; transform: scale(1) rotate(var(--giro, -8deg)); }
  #detalles .saludo { opacity: 1; transform: rotate(-1deg); }
  /* reveal direccional + stagger: todo visible y estático */
  .fade-up.reveal--left,
  .fade-up.reveal--right,
  .fade-up.reveal--pop { opacity: 1; transform: none; }
  .itinerario.fade-up .itinerario__item,
  .dress-code.fade-up .dress-code__color,
  .mesa-regalos.fade-up .mesa-regalos__link,
  .galeria.fade-up .carrusel__slide { opacity: 1; transform: none; }
  .fade-up.is-visible .seccion__titulo { animation: none; transform: rotate(-1.5deg); opacity: 1; }
  .carrusel__slide img:hover,
  .carrusel__slide img:focus-visible { transform: none; }
}
