/* =====================================================================
   INVITACIÓN MASTER — sistema de diseño
   Fábrica de invitaciones: obsidiana + cromo + neón carmesí (del video de portada),
   con una variación estratégica de matiz por estación (rojo, cian, violeta, oro, esmeralda).
   Todo lo que va sobre un fondo holográfico va dentro de un panel oscuro de vidrio,
   de papel marfil o de sobre negro: contraste alto garantizado.
   ===================================================================== */
:root{
  --ink:#05060B; --carbon:#0B0D14; --carbon-2:#12151F;
  --glass:rgba(7,9,16,.76); --glass-2:rgba(12,15,26,.9);
  --red:#FF2A4D; --red-deep:#B3122F; --red-dark:#5B0A1B;
  --chrome:#E4E9F3; --chrome-dim:#A2ADC1; --chrome-lo:#6F7B92;
  --gold:#F1CB74; --gold-deep:#B58A32;
  --ivory:#F4EEE3; --ivory-2:#E7DECE; --paper-ink:#1B1218; --paper-soft:#5B4A50;
  --text:#EEF1F8; --text-soft:#C3CADA;
  --neon:#FF2A4D; --neon-2:#FF7A93;           /* se redefine por estación */
  --f-display:'Cinzel','Trajan Pro',Georgia,serif;
  --f-serif:'Cormorant Garamond','Palatino Linotype',Georgia,serif;
  --f-script:'Great Vibes','Snell Roundhand',cursive;
  --f-body:'Jost','Segoe UI',system-ui,sans-serif;
  --f-mono:'Share Tech Mono','Consolas',monospace;
  --col:520px;
  --ease:cubic-bezier(.2,.8,.2,1);
}
[data-hue="red"]{--neon:#FF2A4D;--neon-2:#FF8AA0}
[data-hue="cyan"]{--neon:#35E0FF;--neon-2:#9BF0FF}
[data-hue="violet"]{--neon:#D45BFF;--neon-2:#EBA8FF}
[data-hue="gold"]{--neon:#FFC24A;--neon-2:#FFE29A}
[data-hue="emerald"]{--neon:#2CFFB0;--neon-2:#9DFFD8}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:auto;-webkit-text-size-adjust:100%}
body{margin:0;background:var(--ink);color:var(--text);font-family:var(--f-body);font-size:16px;line-height:1.6;overflow-x:hidden;-webkit-font-smoothing:antialiased}
img,video,canvas{max-width:100%;display:block}
a{color:inherit}
button{font:inherit;color:inherit;cursor:pointer}
h1,h2,h3,p{margin:0}
:focus-visible{outline:2px solid var(--neon-2);outline-offset:3px}
.mono{font-family:var(--f-mono);letter-spacing:.16em;text-transform:uppercase}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* fondo de escritorio: mismo neón, desenfocado, a los lados de la columna */
.desk-bg{position:fixed;inset:0;z-index:-2;background:var(--ink) url(../assets/bg/bg-red.jpg) center/cover no-repeat;filter:blur(26px) saturate(1.3) brightness(.55);transform:scale(1.12)}
.line{position:relative;width:min(100%,var(--col));margin-inline:auto;background:var(--ink);box-shadow:0 0 0 1px rgba(255,255,255,.06),0 0 90px rgba(255,42,77,.28)}

/* ---------- puerta de entrada: el toque abre la invitación y arranca la música ---------- */
.gate{position:fixed;inset:0;z-index:100;display:grid;place-items:center;padding:24px;background:
  radial-gradient(ellipse at 50% 40%,rgba(255,42,77,.22),transparent 60%),var(--ink);transition:opacity .9s var(--ease),visibility .9s;text-align:center}
.gate.is-open{opacity:0;visibility:hidden;pointer-events:none}
.gate-in{display:grid;gap:18px;justify-items:center;max-width:340px}
.gate-ring{width:132px;height:132px;border-radius:50%;display:grid;place-items:center;border:1px solid rgba(255,42,77,.55);box-shadow:0 0 40px rgba(255,42,77,.45),inset 0 0 40px rgba(255,42,77,.25);position:relative;animation:gatePulse 2.6s ease-in-out infinite}
.gate-ring::before,.gate-ring::after{content:"";position:absolute;inset:-14px;border-radius:50%;border:1px solid rgba(255,42,77,.28)}
.gate-ring::after{inset:-30px;border-color:rgba(255,42,77,.14)}
.gate-ring svg{width:54px;height:54px}
@keyframes gatePulse{50%{transform:scale(1.05);box-shadow:0 0 70px rgba(255,42,77,.7),inset 0 0 50px rgba(255,42,77,.35)}}
.gate h2{font-family:var(--f-display);font-weight:700;font-size:22px;letter-spacing:.2em;text-transform:uppercase;color:var(--chrome)}
.gate p{color:var(--text-soft);font-size:14px}
.btn{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:48px;padding:0 28px;border-radius:999px;border:1px solid var(--neon);background:linear-gradient(180deg,rgba(255,255,255,.1),rgba(255,255,255,0)),rgba(8,10,18,.85);color:#fff;font-family:var(--f-display);font-weight:700;font-size:13px;letter-spacing:.2em;text-transform:uppercase;text-decoration:none;box-shadow:0 0 22px color-mix(in srgb,var(--neon) 45%,transparent),inset 0 0 18px color-mix(in srgb,var(--neon) 22%,transparent);transition:transform .25s var(--ease),box-shadow .25s}
.btn:hover{transform:translateY(-2px);box-shadow:0 0 36px color-mix(in srgb,var(--neon) 70%,transparent),inset 0 0 22px color-mix(in srgb,var(--neon) 35%,transparent)}
.btn:active{transform:scale(.97)}
.btn.solid{background:linear-gradient(180deg,var(--neon-2),var(--neon));color:#0a0508;border-color:transparent}
.btn.ghost{background:transparent;box-shadow:none;border-color:rgba(255,255,255,.28)}
.btn.sm{min-height:40px;padding:0 18px;font-size:11.5px}
.btn[disabled]{opacity:.5;pointer-events:none}

/* ---------- reproductor: play / stop siempre a la mano ---------- */
.fab{position:fixed;z-index:60;bottom:calc(18px + env(safe-area-inset-bottom,0px));right:max(16px,calc(50vw - var(--col)/2 + 14px));display:flex;gap:8px;align-items:center;padding:6px;border-radius:999px;background:var(--glass-2);border:1px solid rgba(255,255,255,.14);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);box-shadow:0 8px 30px rgba(0,0,0,.5),0 0 22px color-mix(in srgb,var(--neon) 35%,transparent)}
.fab button{width:42px;height:42px;border-radius:50%;border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.06);display:grid;place-items:center;transition:background .2s,transform .2s}
.fab button:hover{background:rgba(255,255,255,.14)}
.fab button:active{transform:scale(.92)}
.fab svg{width:18px;height:18px;fill:#fff}
.fab .eq{display:flex;gap:3px;align-items:flex-end;height:18px;width:22px;margin:0 6px 0 4px}
.fab .eq i{flex:1;background:var(--neon);border-radius:2px;height:30%;box-shadow:0 0 8px var(--neon)}
.fab.is-playing .eq i{animation:eq 1s ease-in-out infinite}
.fab.is-playing .eq i:nth-child(2){animation-delay:-.3s}.fab.is-playing .eq i:nth-child(3){animation-delay:-.6s}.fab.is-playing .eq i:nth-child(4){animation-delay:-.15s}
@keyframes eq{0%,100%{height:25%}50%{height:100%}}
#yt-holder{position:fixed;left:-9999px;top:0;width:220px;height:220px;opacity:0;pointer-events:none}

/* ---------- PORTADA: video 3D con máquinas + título 3D ---------- */
.cover{position:relative;min-height:100svh;display:grid;align-content:center;justify-items:center;text-align:center;overflow:hidden;isolation:isolate;padding:80px 16px 96px}
.cover video,.cover .cover-poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-3}
.cover::before{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(180deg,rgba(5,6,11,.75) 0%,rgba(5,6,11,.15) 34%,rgba(5,6,11,.15) 58%,rgba(5,6,11,.92) 100%),radial-gradient(ellipse at 50% 42%,rgba(5,6,11,.5),transparent 62%)}
.cover-kicker{font-size:12px;color:var(--chrome);opacity:0;letter-spacing:.42em;text-shadow:0 0 14px rgba(255,42,77,.9)}
.cover-sub{font-family:var(--f-serif);font-style:italic;font-size:clamp(19px,5.2vw,24px);color:#fff;text-shadow:0 2px 16px #000;max-width:24ch;min-height:2.6em;margin-top:8px}
.cover-flag{position:absolute;top:calc(16px + env(safe-area-inset-top,0px));left:50%;transform:translateX(-50%);padding:7px 16px;border-radius:999px;background:var(--glass);border:1px solid rgba(255,255,255,.18);font-size:10.5px;color:var(--chrome);white-space:nowrap;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
.cover-how{margin-top:24px}
.scroll-cue{position:absolute;bottom:calc(26px + env(safe-area-inset-bottom,0px));left:50%;transform:translateX(-50%);display:grid;justify-items:center;gap:8px;font-size:10.5px;color:var(--chrome-dim)}
.scroll-cue::after{content:"";width:1px;height:34px;background:linear-gradient(var(--neon),transparent);animation:cue 1.8s ease-in-out infinite;transform-origin:top}
@keyframes cue{0%{transform:scaleY(0)}60%{transform:scaleY(1)}100%{transform:scaleY(1);opacity:0}}

/* título 3D extruido: cada letra es una pila de capas en Z, con aparición letra por letra */
.t3d{perspective:1100px;perspective-origin:50% 40%;margin:14px 0 6px}
.t3d-stage{transform-style:preserve-3d;transform:rotateX(var(--rx,10deg)) rotateY(var(--ry,0deg));transition:transform .25s ease-out;will-change:transform}
.t3d-line{display:block;transform-style:preserve-3d;white-space:nowrap;font-family:var(--f-display);font-weight:900;text-transform:uppercase;line-height:1.02}
.t3d-line.l1{font-size:clamp(34px,10.6vw,56px);letter-spacing:.06em}
.t3d-line.l2{font-size:clamp(50px,16.4vw,88px);letter-spacing:.08em;margin-top:.02em}
.ch{display:inline-block;position:relative;transform-style:preserve-3d;opacity:0}
.ch.in{opacity:1;animation:chIn 1.5s var(--ease) backwards;animation-delay:calc(var(--i) * 85ms)}   /* sin fill 'forwards': una animación de relleno aplanaba el 3D y tapaba la cara cromada */
.ch b{position:relative;display:block;font-weight:900;background:linear-gradient(180deg,#fff 0%,#d9dfec 34%,#7b869c 49%,#f1f4fa 60%,#a7b1c5 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent}
.ch i{position:absolute;inset:0;font-style:normal;font-weight:900;transform:translateZ(calc(var(--z) * -2.4px));color:hsl(350 82% calc(34% - var(--z) * 1.9%));pointer-events:none}
.ch i.deep{text-shadow:0 0 34px #ff1240,0 0 70px rgba(255,18,64,.7)}
@keyframes chIn{
  0%{opacity:0;transform:translate3d(0,40px,-620px) rotateX(-80deg) rotateY(40deg)}
  45%{opacity:1}
  100%{opacity:1;transform:none}}
.t3d.static .ch{opacity:1;animation:none}

/* ---------- SOBRE 3D (Three.js): ensamble, giro 360° y apertura con scroll ---------- */
.env-rail{position:relative;height:340svh;background:var(--ink)}
.env-pin{position:sticky;top:0;height:100svh;overflow:hidden;display:grid;isolation:isolate}
.env-pin .env-bgimg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-3;filter:saturate(1.1) brightness(.75)}
.env-pin::before{content:"";position:absolute;inset:0;z-index:-2;background:radial-gradient(ellipse at 50% 55%,rgba(5,6,11,.1),rgba(5,6,11,.75) 75%),linear-gradient(180deg,rgba(5,6,11,.85),transparent 26%,transparent 70%,rgba(5,6,11,.9))}
#env-canvas{position:absolute;inset:0;width:100%;height:100%;z-index:1;touch-action:pan-y}
.env-fallback{position:absolute;inset:0;display:grid;place-items:center;z-index:1}
.env-fallback img{width:86%;transform:perspective(900px) rotateY(calc(var(--p,0) * 360deg));filter:drop-shadow(0 30px 40px rgba(0,0,0,.8))}
.env-cap{position:absolute;left:0;right:0;z-index:2;text-align:center;padding:0 20px;pointer-events:none}
.env-cap.top{top:calc(64px + env(safe-area-inset-top,0px))}
.env-cap.bot{bottom:calc(46px + env(safe-area-inset-bottom,0px))}
.env-cap h2{font-family:var(--f-display);font-weight:900;font-size:clamp(22px,6.6vw,32px);letter-spacing:.14em;text-transform:uppercase;background:linear-gradient(180deg,#fff,#aab4c8);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;filter:drop-shadow(0 0 12px rgba(255,42,77,.6))}
.env-steps{display:flex;gap:8px;justify-content:center;margin-top:12px}
.env-steps span{font-size:10.5px;padding:6px 12px;border-radius:999px;border:1px solid rgba(255,255,255,.2);color:var(--chrome-dim);background:var(--glass);transition:all .4s var(--ease)}
.env-steps span.on{color:#fff;border-color:var(--neon);box-shadow:0 0 18px color-mix(in srgb,var(--neon) 55%,transparent);background:rgba(255,42,77,.2)}
.env-msg{font-family:var(--f-serif);font-style:italic;font-size:clamp(18px,5vw,22px);color:#fff;text-shadow:0 2px 14px #000;min-height:3em;max-width:30ch;margin:0 auto}
.env-bar{position:absolute;left:24px;right:24px;bottom:calc(20px + env(safe-area-inset-bottom,0px));height:2px;background:rgba(255,255,255,.12);z-index:2;border-radius:2px;overflow:hidden}
.env-bar i{display:block;height:100%;width:calc(var(--p,0) * 100%);background:linear-gradient(90deg,var(--red-deep),var(--neon-2));box-shadow:0 0 12px var(--neon)}

/* ---------- ESTACIÓN: cada sección de la invitación ---------- */
.station{position:relative;overflow:hidden;isolation:isolate;padding:96px 20px 104px;min-height:min(100svh,940px)}
/* sin will-change: con 14 estaciones en el DOM, prometer una capa GPU permanente para cada
   fondo (imágenes grandes) inflaba la memoria de video sin necesidad — el navegador ya
   promueve la capa cuando el transform realmente empieza a cambiar. */
/* fondo sin ningún efecto: antes escalaba con el progreso de scroll (--p) y ese continuo
   reescalado de una imagen grande, en varias secciones a la vez, era lo que se veía como
   parpadeo/corto — ahora es una imagen fija de verdad, ya no depende del scroll. */
.st-bg{position:absolute;inset:-8% -4%;z-index:-4;background:var(--bg) center/cover no-repeat;transform:scale(1.1) scaleX(var(--flip,1))}
/* luces del fondo fijas, sin movimiento y SIN mix-blend-mode: además de la animación que ya se
   quitó, "screen" obligaba al navegador a recalcular el color contra todo lo que tiene detrás
   en cada frame — y detrás está .st-bg, que sí cambia de escala con el scroll (--p). Esa mezcla
   recalculándose sobre un fondo que se mueve, encima en 14 secciones apiladas a la vez, es lo
   que se veía como "corto" (parpadeo intermitente) incluso ya sin animación propia. Con mezcla
   normal la capa es estática de verdad: mismo color, ya no depende de lo que haya debajo. */
.st-holo{position:absolute;inset:0;z-index:-2;pointer-events:none;opacity:.7;background:linear-gradient(112deg,transparent 30%,rgba(255,255,255,.05) 43%,color-mix(in srgb,var(--neon) 30%,transparent) 50%,rgba(255,255,255,.05) 57%,transparent 70%);background-size:260% 260%;background-position:35% 65%}
/* zona oscura mucho más ancha en los bordes de cada estación: antes el color vivo de una
   estación (p.ej. rojo) chocaba de golpe contra el de la siguiente (p.ej. cian) apenas cruzabas
   el borde — ahora hay un tramo largo casi negro de por medio, así el cambio de color se siente
   como una disolución suave en vez de un corte brusco al hacer scroll. */
.st-shade{position:absolute;inset:0;z-index:-1;background:linear-gradient(180deg,rgba(5,6,11,.97) 0%,rgba(5,6,11,.55) 38%,rgba(5,6,11,.55) 62%,rgba(5,6,11,.97) 100%)}
.st-tunnel{position:absolute;inset:0;z-index:-3;pointer-events:none;opacity:.62;overflow:hidden}
.st-tunnel i{position:absolute;left:8%;right:8%;top:6%;bottom:6%;border:2px solid var(--neon);border-radius:4px;box-shadow:0 0 20px var(--neon),inset 0 0 20px var(--neon);opacity:calc(.82 - var(--i) * .12);transform:scale(calc(.32 + var(--i) * .27))}
[data-shape="arch"] .st-tunnel i{border-radius:999px 999px 0 0}
.st-inner{position:relative;display:grid;gap:28px}
.st-head{display:grid;gap:12px;justify-items:center;text-align:center}
.st-tag{font-size:11px;color:var(--neon-2);text-shadow:0 0 12px color-mix(in srgb,var(--neon) 70%,transparent)}
.st-tag::before{content:"";display:inline-block;width:26px;height:1px;background:var(--neon);vertical-align:middle;margin-right:12px;box-shadow:0 0 8px var(--neon)}
.st-tag::after{content:"";display:inline-block;width:26px;height:1px;background:var(--neon);vertical-align:middle;margin-left:12px;box-shadow:0 0 8px var(--neon)}
.st-title{font-family:var(--f-display);font-weight:900;font-size:clamp(26px,8vw,38px);letter-spacing:.1em;line-height:1.12;text-transform:uppercase;text-wrap:balance;background:linear-gradient(180deg,#fff 10%,#b9c3d8 55%,#eef2fa);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;filter:drop-shadow(0 2px 18px color-mix(in srgb,var(--neon) 55%,transparent))}
.st-lead{font-family:var(--f-serif);font-style:italic;font-size:clamp(19px,5.4vw,23px);line-height:1.4;color:#fff;text-align:center;max-width:30ch;margin-inline:auto;text-shadow:0 2px 16px #000}

/* "Así funciona": la nota técnica que explica el efecto de cada sección */
.how{position:relative;display:grid;gap:6px;padding:14px 16px 14px 18px;border-radius:4px 14px 14px 4px;background:rgba(5,6,11,.9);border:1px solid color-mix(in srgb,var(--neon) 55%,transparent);border-left:3px solid var(--neon);box-shadow:0 0 24px color-mix(in srgb,var(--neon) 25%,transparent);text-align:left}
.how b{font-family:var(--f-mono);font-weight:400;font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--neon-2)}
.how b::before{content:"▸ "}
.how p{font-size:14px;line-height:1.55;color:var(--text)}
.how.center{max-width:340px}

/* ---------- recuadros decorados ---------- */
.panel{position:relative;padding:26px 22px;background:var(--glass);border:1px solid rgba(255,255,255,.14);border-radius:6px;box-shadow:0 20px 50px rgba(0,0,0,.55),0 0 0 1px rgba(0,0,0,.6),0 0 34px color-mix(in srgb,var(--neon) 22%,transparent)}   /* sin backdrop-filter: el fondo .glass ya es 76% opaco; el blur costaba fps al hacer scroll con muchos paneles en pantalla */
.panel::before,.panel::after{content:"";position:absolute;width:22px;height:22px;pointer-events:none;border:2px solid var(--neon);filter:drop-shadow(0 0 6px var(--neon))}
.panel::before{top:-1px;left:-1px;border-right:0;border-bottom:0;border-top-left-radius:6px}
.panel::after{bottom:-1px;right:-1px;border-left:0;border-top:0;border-bottom-right-radius:6px}
.panel > h3,.h3{font-family:var(--f-display);font-weight:700;font-size:17px;letter-spacing:.14em;text-transform:uppercase;color:#fff}

/* hoja / carta de papel marfil (para textos largos con máximo contraste) */
.paper{position:relative;color:var(--paper-ink);padding:34px 26px 30px;background:
  linear-gradient(135deg,transparent 0 calc(100% - 34px),#cbbfa9 calc(100% - 34px),#e4d9c6 100%) ,
  repeating-linear-gradient(0deg,rgba(90,70,50,.035) 0 1px,transparent 1px 3px),
  linear-gradient(180deg,#f8f3e9,#efe7d8);
  box-shadow:0 26px 50px rgba(0,0,0,.6),0 0 0 1px rgba(0,0,0,.4),0 0 44px color-mix(in srgb,var(--neon) 30%,transparent);
  clip-path:polygon(0 0,100% 0,100% calc(100% - 34px),calc(100% - 34px) 100%,0 100%)}
.paper h3{font-family:var(--f-display);font-weight:700;color:var(--red-deep);letter-spacing:.14em;text-transform:uppercase;font-size:15px}
.paper .seal{position:absolute;right:30px;bottom:-4px;width:54px;height:54px;border-radius:50%;background:radial-gradient(circle at 35% 30%,#ff6b85,var(--red-deep) 55%,#5b0a1b);box-shadow:0 4px 10px rgba(0,0,0,.5),inset 0 -3px 6px rgba(0,0,0,.35);display:grid;place-items:center;color:rgba(255,255,255,.85);font-size:20px;transform:rotate(-12deg)}

/* boleto perforado (itinerario, pases) */
.ticket{position:relative;display:grid;grid-template-columns:auto 1fr;gap:0;background:linear-gradient(135deg,#171a28,#0c0e17);border:1px solid rgba(255,255,255,.14);-webkit-mask:radial-gradient(circle 10px at 0 50%,#0000 97%,#000) left/51% 100% no-repeat,radial-gradient(circle 10px at 100% 50%,#0000 97%,#000) right/51% 100% no-repeat;mask:radial-gradient(circle 10px at 0 50%,#0000 97%,#000) left/51% 100% no-repeat,radial-gradient(circle 10px at 100% 50%,#0000 97%,#000) right/51% 100% no-repeat}
.ticket .tk-time{display:grid;place-items:center;padding:16px 16px 16px 22px;min-width:96px;font-family:var(--f-display);font-weight:700;font-size:22px;color:var(--neon-2);border-right:2px dashed rgba(255,255,255,.22);text-shadow:0 0 14px color-mix(in srgb,var(--neon) 70%,transparent)}
.ticket .tk-time small{display:block;font-family:var(--f-mono);font-weight:400;font-size:10px;letter-spacing:.2em;color:var(--chrome-dim);text-align:center}
.ticket .tk-body{padding:14px 22px 14px 18px;display:grid;gap:2px;align-content:center}
.ticket .tk-body b{font-family:var(--f-display);letter-spacing:.1em;text-transform:uppercase;font-size:14.5px;color:#fff}
.ticket .tk-body span{font-size:13.5px;color:var(--text-soft)}

/* tarjeta que gira 360° / 180° con información en la parte trasera */
.flip{perspective:1400px;cursor:pointer;-webkit-tap-highlight-color:transparent;position:relative}
.flip-in{position:relative;display:grid;transform-style:preserve-3d;-webkit-transform-style:preserve-3d;transition:transform .9s var(--ease)}
.flip.is-flipped .flip-in,.flip-in.auto{transform:rotateY(180deg)}
.flip-face{grid-area:1/1;backface-visibility:hidden;-webkit-backface-visibility:hidden;border-radius:6px;transition:visibility 0s linear .16s}
.flip-face.back{transform:rotateY(180deg);visibility:hidden}
/* seguro adicional, no solo backface-visibility: en algunos Safari de iPhone
   backface-visibility:hidden no oculta bien la cara trasera de un hijo de grid, y las dos caras
   se veían encimadas/combinadas al girar. Con esto la cara que no toca queda con
   visibility:hidden de verdad (nada que ver con el culling 3D del navegador) casi de inmediato
   al iniciar el giro (0.16s de 0.9s) — la delantera desaparece rápido, sin quedarse pegada a
   medio giro, y nunca se pueden leer las dos caras a la vez esté roto o no el navegador. */
.flip.is-flipped .flip-face.front,.flip-in.auto .flip-face.front{visibility:hidden;transition-delay:.16s}
.flip.is-flipped .flip-face.back,.flip-in.auto .flip-face.back{visibility:visible;transition-delay:0s}
.flip-hint{position:absolute;right:12px;bottom:10px;z-index:3;font-size:9.5px;color:var(--neon-2);display:flex;gap:6px;align-items:center;pointer-events:none;text-shadow:0 1px 6px #000}
.flip-hint::before{content:"↻";font-size:14px}
.flip.paper-face .flip-face.back{background:linear-gradient(180deg,#f8f3e9,#efe7d8);color:var(--paper-ink)}

/* sobre negro con solapa y sello de cera (frente de las tarjetas de ubicación): posición
   absoluta de verdad (no solo grid-area) para que ninguna cara "empuje" el tamaño de la otra
   ni dependa del soporte de grid-area del navegador para quedar apiladas exactamente igual. */
.env-card .flip-in{min-height:250px}
.env-card .front,.env-card .back{position:absolute;inset:0}
.env-card .front{background:linear-gradient(160deg,#181b29,#0a0c14);border:1px solid rgba(255,255,255,.14);overflow:hidden;display:grid;align-content:end;padding:0 22px 22px;box-shadow:0 22px 44px rgba(0,0,0,.6),0 0 30px color-mix(in srgb,var(--neon) 25%,transparent)}
.env-card .front::before{content:"";position:absolute;left:0;right:0;top:0;height:60%;background:linear-gradient(180deg,#242840,#141726);clip-path:polygon(0 0,100% 0,50% 100%);filter:drop-shadow(0 8px 10px #000)}
.env-card .front::after{content:"";position:absolute;left:0;right:0;bottom:0;height:56%;background:linear-gradient(200deg,#1c2033,#0f121d);clip-path:polygon(0 100%,50% 0,100% 100%);opacity:.9}
.env-card .front .wax{position:absolute;left:50%;top:44%;width:58px;height:58px;margin:-29px 0 0 -29px;z-index:2;border-radius:50%;background:radial-gradient(circle at 34% 28%,#ff7d94,var(--red-deep) 52%,#560a1a);box-shadow:0 8px 16px rgba(0,0,0,.6),inset 0 -4px 8px rgba(0,0,0,.4);display:grid;place-items:center;font-size:22px;color:rgba(255,255,255,.88)}
.env-card .front .lbl{position:relative;z-index:2;text-align:center;display:grid;gap:2px}
.env-card .front .lbl b{font-family:var(--f-display);letter-spacing:.16em;text-transform:uppercase;font-size:15px}
.env-card .front .lbl span{font-size:13px;color:var(--chrome-dim)}
.env-card .back{background:linear-gradient(180deg,#f8f3e9,#efe7d8);color:var(--paper-ink);padding:28px 26px;display:grid;gap:12px;align-content:center;min-height:250px;box-shadow:0 22px 44px rgba(0,0,0,.6)}
.env-card .back h3{font-family:var(--f-display);font-weight:700;font-size:18px;letter-spacing:.12em;text-transform:uppercase;color:var(--red-deep)}
.env-card .back p{font-size:16px;line-height:1.6;color:var(--paper-ink)}
.env-card .back .acts{display:flex;gap:8px;flex-wrap:wrap;margin-top:4px}
.env-card .back .btn{color:var(--paper-ink);background:transparent;border-color:var(--red-deep);box-shadow:none;font-size:10.5px;min-height:38px;padding:0 16px}

/* figuras 3D generadas: viñeta oscura + giro por scroll */
.fig{position:relative;justify-self:center;width:min(78%,340px);aspect-ratio:1;perspective:900px}
/* el degradado es más generoso que antes (antes se cerraba a partir del 46% del radio y dejaba
   la parte de arriba de objetos altos, como el reloj de arena, con pinta de transparente) */
/* máscara mucho menos agresiva: a 64%/94% el objeto (p.ej. las llaves) se veía desvanecido,
   medio transparente, en vez de sólido — ahora casi toda la figura queda 100% opaca y el
   desvanecido solo alcanza a la esquina, apenas perceptible. */
.fig img{width:100%;height:100%;object-fit:cover;-webkit-mask:radial-gradient(circle at 50% 50%,#000 86%,transparent 100%);mask:radial-gradient(circle at 50% 50%,#000 86%,transparent 100%);filter:drop-shadow(0 26px 30px rgba(0,0,0,.8)) saturate(1.1)}
.fig::after{content:"";position:absolute;left:14%;right:14%;bottom:-2%;height:12%;background:radial-gradient(ellipse,color-mix(in srgb,var(--neon) 70%,transparent),transparent 70%);filter:blur(10px);opacity:.75;z-index:-1}
.fig.float img{animation:bob 6s ease-in-out infinite}
@keyframes bob{50%{translate:0 -12px}}
@keyframes turn{to{transform:rotateY(360deg)}}

/* caja 3D real (sobre, regalo): antes eran una sola foto plana rotando en Y, lo que se veía
   como una tarjeta girando sin cuerpo. Ahora son 4 caras (frente, atrás y dos costados que
   asoman al girar) armando un objeto sólido de verdad. --d controla el grosor: fino para el
   sobre (una carta), grueso para el regalo (un cubo). --w lo sincroniza js/main.js con el
   ancho real en px del recuadro (rotateY/translateZ no aceptan porcentajes). */
.fig-box{position:relative;justify-self:center;width:min(78%,340px);aspect-ratio:1;perspective:1100px}
.fig-box::after{content:"";position:absolute;left:14%;right:14%;bottom:-2%;height:12%;background:radial-gradient(ellipse,color-mix(in srgb,var(--neon) 70%,transparent),transparent 70%);filter:blur(10px);opacity:.75;z-index:-1}
.fig-box-in{position:relative;width:100%;height:100%;transform-style:preserve-3d;filter:drop-shadow(0 26px 30px rgba(0,0,0,.8)) saturate(1.1);animation:turn 14s linear infinite}
.fig-box-in.still{animation:none;transform:rotateY(-26deg)}
/* sin la máscara circular de .fig img: las fotos ya vienen sobre fondo negro sólido (mismo
   truco de estudio que las demás figuras), y unos cantos rectos limpios son los que hacen que
   los costados encajen sin costura al girar — un desvanecido circular dejaría un borde
   despareja donde empieza el costado recto. */
.fbx-face{position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;border-radius:6px;overflow:hidden}
.fbx-face img{width:100%;height:100%;object-fit:cover;display:block}
.fbx-face.front{transform:translateZ(calc(var(--d) / 2))}
.fbx-face.back{transform:rotateY(180deg) translateZ(calc(var(--d) / 2));background:radial-gradient(circle at 50% 50%,#1a1c26 0%,#07080b 68%,transparent 94%)}
.fbx-side{position:absolute;top:0;bottom:0;width:var(--d);left:calc(50% - (var(--d) / 2));background:linear-gradient(90deg,#020204 0%,#282b38 46%,#020204 100%);opacity:.97}
.fbx-side.right{transform:rotateY(90deg) translateZ(calc(var(--w, 300px) / 2))}
.fbx-side.left{transform:rotateY(-90deg) translateZ(calc(var(--w, 300px) / 2))}

/* ---------- efectos de aparición ---------- */
/* aparición mucho más sutil: antes el zoom arrancaba en 82% + 8px de desenfoque, left/right
   venían de 60px con 18° de giro, y las tarjetas "assemble" volaban desde hasta 80px de
   distancia — todo eso junto, con varias cajas revelándose a la vez mientras se hace scroll,
   se siente como si el contenido (y el fondo detrás) diera un salto/zoom. Ahora es un
   desvanecido corto y casi sin desplazamiento: presente, pero nunca brusco. */
.js:not(.reduce) [data-reveal]{opacity:0;transition:opacity .7s var(--ease),transform .7s var(--ease),filter .7s var(--ease)}
.js:not(.reduce) [data-reveal="up"]{transform:translateY(14px)}
.js:not(.reduce) [data-reveal="left"]{transform:translateX(-18px)}
.js:not(.reduce) [data-reveal="right"]{transform:translateX(18px)}
.js:not(.reduce) [data-reveal="zoom"]{transform:scale(.96)}
.js:not(.reduce) [data-reveal="flip"]{transform:translateY(14px)}
.js:not(.reduce) [data-reveal="assemble"]{transform:translate3d(calc(var(--ax,0) * .25px),calc(var(--ay,60) * .25px),0) scale(.96)}
.js [data-reveal].is-in{opacity:1;transform:none;filter:none}
.js:not(.reduce) [data-type]{visibility:hidden}
.js [data-type].typing,.js [data-type].typed{visibility:visible}
.caret::after{content:"▍";margin-left:2px;color:var(--neon-2);animation:blink .8s steps(2) infinite;-webkit-text-fill-color:var(--neon-2)}
@keyframes blink{50%{opacity:0}}

/* ---------- secciones específicas ---------- */
.names{font-family:var(--f-script);font-size:clamp(56px,17vw,84px);line-height:1;color:#fff;text-align:center;text-shadow:0 0 30px color-mix(in srgb,var(--neon) 70%,transparent),0 4px 20px #000}
.names small{display:block;font-family:var(--f-mono);letter-spacing:.3em;font-size:12px;color:var(--neon-2);margin:10px 0}
.date-big{display:grid;justify-items:center;gap:0;font-family:var(--f-display);text-transform:uppercase;text-align:center;color:#fff}
.date-big b{font-size:clamp(66px,20vw,96px);font-weight:900;line-height:1;background:linear-gradient(180deg,#fff,#9aa5bb);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;filter:drop-shadow(0 0 16px color-mix(in srgb,var(--neon) 70%,transparent))}
.date-big span{letter-spacing:.3em;font-size:14px}

.count{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}
.cd{perspective:600px}
.cd-in{display:grid;place-items:center;aspect-ratio:.82;border-radius:8px;background:linear-gradient(180deg,#1b1f31 0%,#1b1f31 49.5%,#05060b 50%,#10131f 100%);border:1px solid color-mix(in srgb,var(--neon) 60%,transparent);box-shadow:0 0 22px color-mix(in srgb,var(--neon) 35%,transparent),inset 0 0 16px rgba(0,0,0,.6);position:relative;transform-style:preserve-3d}
.cd-in b{font-family:var(--f-display);font-size:clamp(28px,9vw,44px);font-weight:900;color:#fff;font-variant-numeric:tabular-nums;text-shadow:0 0 16px var(--neon)}
.cd-in.tick{animation:tick .7s var(--ease)}
@keyframes tick{0%{transform:rotateX(0)}45%{transform:rotateX(-90deg)}55%{transform:rotateX(90deg)}100%{transform:rotateX(0)}}
.cd small{display:block;text-align:center;margin-top:8px;font-family:var(--f-mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--chrome)}

.gears{position:absolute;right:-70px;top:38%;width:220px;height:220px;opacity:.5;z-index:-1;animation:turn 26s linear infinite;pointer-events:none;color:var(--neon)}
.gears.l{right:auto;left:-80px;top:64%;animation-direction:reverse}
.timeline{position:relative;display:grid;gap:14px;padding-left:0}
.timeline::before{content:"";position:absolute;left:34px;top:0;bottom:0;width:2px;background:linear-gradient(var(--neon),transparent);opacity:.5}

.map-frame{position:relative;border-radius:6px;overflow:hidden;border:1px solid color-mix(in srgb,var(--neon) 60%,transparent);box-shadow:0 0 30px color-mix(in srgb,var(--neon) 30%,transparent);aspect-ratio:4/3;background:#0b0d14}
.map-frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0;filter:invert(.92) hue-rotate(180deg) saturate(.6) brightness(.9) contrast(1.05)}
.venue-shot{position:relative;border-radius:6px;overflow:hidden;aspect-ratio:4/5}
.venue-shot img{width:100%;height:100%;object-fit:cover;transform:scale(1.1)}

.dress-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.dress-card .front,.dress-card .back{min-height:300px;padding:22px 16px;display:grid;align-content:center;justify-items:center;gap:12px;text-align:center;background:var(--glass-2);border:1px solid rgba(255,255,255,.14);box-shadow:0 20px 40px rgba(0,0,0,.55),0 0 26px color-mix(in srgb,var(--neon) 24%,transparent)}
.dress-card .back{background:linear-gradient(180deg,#f8f3e9,#efe7d8);color:var(--paper-ink)}
.dress-card h3{font-family:var(--f-display);font-size:16px;letter-spacing:.16em;text-transform:uppercase}
.dress-card .back h3{color:var(--red-deep)}
.dress-card p{font-size:13.5px;line-height:1.45}
.dress-card .back p{color:var(--paper-ink)}
.swatches{display:flex;gap:8px;justify-content:center}
.swatches i{width:30px;height:30px;border-radius:50%;border:2px solid rgba(255,255,255,.5);box-shadow:0 4px 10px rgba(0,0,0,.5)}
.dress-card .glyph{font-size:44px;filter:drop-shadow(0 0 12px var(--neon))}

.tag{position:relative;background:linear-gradient(160deg,#f8f3e9,#e9dfcc);color:var(--paper-ink);padding:30px 22px 22px 56px;clip-path:polygon(0 0,calc(100% - 26px) 0,100% 26px,100% 100%,0 100%);box-shadow:0 20px 40px rgba(0,0,0,.6)}
.tag::before{content:"";position:absolute;left:20px;top:22px;width:20px;height:20px;border-radius:50%;background:#0b0d14;box-shadow:inset 0 2px 4px #000,0 0 0 4px rgba(181,138,50,.6)}
.tag h3{font-family:var(--f-display);font-weight:700;letter-spacing:.12em;text-transform:uppercase;font-size:15px;color:var(--red-deep)}
.tag p{font-size:14.5px;color:var(--paper-ink);margin-top:4px}
.tag .code{display:inline-block;margin-top:10px;padding:6px 14px;border:1px dashed var(--red-deep);border-radius:4px;font-family:var(--f-mono);letter-spacing:.14em;font-size:14px;color:var(--red-deep);background:rgba(179,18,47,.06)}
.gift-list{display:grid;gap:14px}

/* hoteles en un solo carril: los 3 comparten la misma posición y se deslizan con el dedo
   (scroll-snap nativo, sin JS de por medio), en vez de apilarse uno debajo del otro. */
.hotels{position:relative;padding:0 6px;min-width:0;width:100%}
.hotels-track{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:none;border-radius:10px;min-width:0;width:100%}
.hotels-track::-webkit-scrollbar{display:none}
.hotels-track .polaroid{flex:0 0 100%;scroll-snap-align:center;transform:none;min-width:0}
.hotels-track .polaroid img{min-width:0}
.hotels-nav{position:absolute;top:38%;z-index:3;width:42px;height:42px;border-radius:50%;display:grid;place-items:center;padding:0;border:1px solid var(--neon);background:rgba(8,10,18,.85);color:#fff;font-size:24px;line-height:1;box-shadow:0 0 18px color-mix(in srgb,var(--neon) 40%,transparent)}
.hotels-nav.prev{left:-8px}
.hotels-nav.next{right:-8px}
.hotels-dots{display:flex;gap:8px;justify-content:center;margin-top:14px}
.hotels-dots i{width:7px;height:7px;border-radius:50%;background:rgba(255,255,255,.28)}
.hotels-dots i.on{background:var(--neon);box-shadow:0 0 8px var(--neon)}
.polaroid .front,.polaroid .back{min-height:330px}
.polaroid .front{background:#f6f1e7;padding:12px 12px 16px;display:grid;grid-template-rows:1fr auto;gap:10px;box-shadow:0 22px 44px rgba(0,0,0,.6),0 0 24px color-mix(in srgb,var(--neon) 24%,transparent)}
.polaroid .front img{width:100%;height:100%;object-fit:cover;min-height:0;border:1px solid rgba(0,0,0,.15)}
.polaroid .front figcaption{font-family:var(--f-script);font-size:30px;line-height:1;color:var(--paper-ink);text-align:center;padding-bottom:2px}
.polaroid .back{background:var(--glass-2);border:1px solid rgba(255,255,255,.16);padding:26px 22px;display:grid;gap:10px;align-content:center}
.polaroid .back h3{font-family:var(--f-display);font-size:15px;letter-spacing:.14em;text-transform:uppercase}
.polaroid .back p{font-size:14px;color:var(--text-soft)}
.polaroid .back .stars{color:var(--gold);letter-spacing:.2em}
.polaroid .back .rate{font-family:var(--f-mono);font-size:12px;letter-spacing:.12em;color:var(--neon-2)}

.phone{position:relative;justify-self:center;width:min(74%,300px);aspect-ratio:9/19;border-radius:38px;padding:10px;background:linear-gradient(145deg,#2a2f42,#0b0d14);box-shadow:0 0 0 2px #3a4058,0 40px 60px rgba(0,0,0,.7),0 0 50px color-mix(in srgb,var(--neon) 40%,transparent);transform:perspective(1000px) rotateY(-6deg)}
.phone::before{content:"";position:absolute;top:16px;left:50%;width:74px;height:20px;margin-left:-37px;border-radius:12px;background:#000;z-index:3}
.phone video{width:100%;height:100%;object-fit:cover;border-radius:30px;background:#000}
.phone .snd{position:absolute;right:20px;bottom:20px;z-index:3;width:40px;height:40px;border-radius:50%;background:rgba(5,6,11,.8);border:1px solid rgba(255,255,255,.3);display:grid;place-items:center}
.phone .snd svg{width:18px;height:18px;fill:#fff}

.closing{display:grid;gap:26px;justify-items:center;text-align:center}
.gracias{font-family:var(--f-script);font-size:clamp(64px,20vw,100px);line-height:1;color:#fff;text-shadow:0 0 34px color-mix(in srgb,var(--neon) 80%,transparent),0 4px 20px #000}
.station.closing-st{display:grid;align-content:center}
.foot{padding:26px 20px 110px;text-align:center;background:var(--ink);font-size:12px;color:var(--chrome-lo)}

@media (min-width:600px){.station{padding-inline:26px}}
/* movimiento reducido: se respeta por defecto; el botón de la puerta ("Activar efectos completos") lo desactiva a petición */
html.reduce *,html.reduce *::before,html.reduce *::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}
html.reduce [data-reveal],html.reduce [data-type]{opacity:1!important;transform:none!important;filter:none!important;visibility:visible!important}
html.reduce .ch{opacity:1}
html.reduce .env-rail{height:auto}html.reduce .env-pin{position:relative;height:auto;min-height:100svh}
.gate-fx{margin-top:4px;background:none;border:0;color:var(--neon-2);font-family:var(--f-mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;text-decoration:underline;text-underline-offset:4px;display:none;line-height:1.6}
html.reduce .gate-fx{display:inline-block}
