BODA
Robert & Patricia
BODA
Robert & Patricia
10 · 01 · 2026
document.addEventListener( "DOMContentLoaded", function () { const cover = document.getElementById( "inviteCover" ); const button = document.getElementById( "openInvite" ); const background = document.getElementById( "coverBackground" ); const music = document.getElementById( "lumiereMusic" ); if ( !cover || !button ) { return; } const finalVolume = 0.65; if (music) { music.volume = 0; } function fadeInMusic() { if (!music) { return; } let currentVolume = 0; music.volume = 0; const fadeInterval = setInterval( function () { currentVolume += 0.05; if ( currentVolume >= finalVolume ) { music.volume = finalVolume; clearInterval( fadeInterval ); return; } music.volume = currentVolume; }, 70 ); } button.addEventListener( "click", function () { if ( cover.classList.contains( "is-opening" ) ) { return; } if (music) { music.currentTime = 0; music.volume = 0; const musicPromise = music.play(); if ( musicPromise !== undefined ) { musicPromise.catch( function (error) { console.log( "Lumière: audio bloqueado", error ); } ); } } button.classList.add( "is-pressed" ); setTimeout( function () { button.classList.remove( "is-pressed" ); cover.classList.add( "is-opening" ); }, 220 ); setTimeout( function () { if (background) { background.classList.add( "is-hidden" ); } }, 1750 ); setTimeout( function () { const invitation = document.getElementById( "invitacion" ); if (invitation) { invitation.scrollIntoView({ behavior: "smooth", block: "start" }); } else { window.location.hash = "invitacion"; } setTimeout( function () { fadeInMusic(); }, 300 ); }, 2050 ); } ); } );
Robert & Patricia
¡Nuestra Boda!
“te elijo hoy por siempre”
FALTAN
00
DÍAS
00
HORAS
00
MIN
00
SEG
/* ================================================== FECHA DEL EVENTO CAMBIAR PARA CADA CLIENTE ================================================== */ const eventDate = new Date( "2026-10-01T18:30:00" ).getTime(); /* ================================================== ACTUALIZAR CONTEO ================================================== */ function updateCountdown() { const now = new Date().getTime(); const distance = eventDate - now; if (distance <= 0) { document.getElementById("days").textContent = "00"; document.getElementById("hours").textContent = "00"; document.getElementById("minutes").textContent = "00"; document.getElementById("seconds").textContent = "00"; return; } const days = Math.floor( distance / (1000 * 60 * 60 * 24) ); const hours = Math.floor( ( distance % (1000 * 60 * 60 * 24) ) / (1000 * 60 * 60) ); const minutes = Math.floor( ( distance % (1000 * 60 * 60) ) / (1000 * 60) ); const seconds = Math.floor( ( distance % (1000 * 60) ) / 1000 ); document.getElementById("days").textContent = String(days).padStart(2,"0"); document.getElementById("hours").textContent = String(hours).padStart(2,"0"); document.getElementById("minutes").textContent = String(minutes).padStart(2,"0"); document.getElementById("seconds").textContent = String(seconds).padStart(2,"0"); } updateCountdown(); setInterval( updateCountdown, 1000 );
CEREMONIA
10 · 01 · 2026
6:30 PM
The Rooftop
139 Hunter's Grv Ln #400 · Lehi, Utah 84043
¿CÓMO LLEGAR?
RECEPCIÓN
10 · 01 · 2026
5:30 PM
The Rooftop
139 Hunter's Grv Ln #400 · Lehi, Utah 84043
¿CÓMO LLEGAR?
DRESS CODE
FORMAL
Acompáñanos con un look elegante para celebrar juntos esta ocasión tan especial
(function () { const openButton = document.getElementById( "dressMoreButton" ); const modal = document.getElementById( "dressModal" ); const closeButton = document.getElementById( "dressModalClose" ); const overlay = modal ? modal.querySelector( ".dress-modal-overlay" ) : null; if ( !openButton || !modal || !closeButton ) { return; } function openModal() { modal.classList.add( "is-open" ); modal.setAttribute( "aria-hidden", "false" ); document.body.style.overflow = "hidden"; } function closeModal() { modal.classList.remove( "is-open" ); modal.setAttribute( "aria-hidden", "true" ); document.body.style.overflow = ""; } openButton.addEventListener( "click", openModal ); closeButton.addEventListener( "click", closeModal ); if (overlay) { overlay.addEventListener( "click", closeModal ); } document.addEventListener( "keydown", function (event) { if ( event.key === "Escape" && modal.classList.contains( "is-open" ) ) { closeModal(); } } ); })();
(function () { const control = document.getElementById( "lumiereMusicControl" ); const controlWrap = document.getElementById( "lumiereMusicControlWrap" ); const trigger = document.getElementById( "lumiereMusicTrigger" ); if (!control) { console.log( "Lumière: control de música no encontrado" ); return; } /* ================================================== MOSTRAR DESPUÉS DEL DRESS CODE ================================================== */ if ( controlWrap && trigger ) { const observer = new IntersectionObserver( function (entries) { entries.forEach( function (entry) { if (entry.isIntersecting) { controlWrap.classList.add( "is-visible" ); observer.disconnect(); } }); }, { threshold: 0, rootMargin: "0px 0px -10% 0px" } ); observer.observe( trigger ); } /* ================================================== CLICK EN LA NOTA MUSICAL ================================================== */ control.addEventListener( "click", function () { const music = document.getElementById( "lumiereMusic" ); if (!music) { console.log( "Lumière: no se encontró #lumiereMusic" ); return; } /* ================================================== SI ESTÁ SONANDO → PAUSAR ================================================== */ if (!music.paused) { music.pause(); control.classList.add( "is-paused" ); control.setAttribute( "aria-label", "Reanudar música" ); control.setAttribute( "title", "Reanudar música" ); return; } /* ================================================== SI ESTÁ PAUSADA → REANUDAR ================================================== */ const playPromise = music.play(); if ( playPromise !== undefined ) { playPromise .then(function () { control.classList.remove( "is-paused" ); control.setAttribute( "aria-label", "Pausar música" ); control.setAttribute( "title", "Pausar música" ); }) .catch(function (error) { console.log( "Lumière: no se pudo reanudar la música", error ); }); } }); })();
RECUERDOS
Un poco de nuestra historia
/* ================================================== EMBED 08 — POPUP DE FOTOGRAFÍAS ================================================== */ (function () { const modal = document.getElementById( "momentsModal" ); const modalImage = document.getElementById( "momentsModalImage" ); const closeButton = document.getElementById( "momentsModalClose" ); const overlay = modal ? modal.querySelector( ".moments-modal-overlay" ) : null; const photos = document.querySelectorAll( ".moments-photo" ); if ( !modal || !modalImage || !closeButton ) { return; } function openModal(imageUrl) { modalImage.src = imageUrl; modal.classList.add( "is-open" ); modal.setAttribute( "aria-hidden", "false" ); document.body.style.overflow = "hidden"; } function closeModal() { modal.classList.remove( "is-open" ); modal.setAttribute( "aria-hidden", "true" ); document.body.style.overflow = ""; setTimeout( function () { if ( !modal.classList.contains( "is-open" ) ) { modalImage.src = ""; } }, 300 ); } photos.forEach( function (photo) { photo.addEventListener( "click", function () { const imageUrl = photo.getAttribute( "data-full" ); if (imageUrl) { openModal( imageUrl ); } } ); } ); closeButton.addEventListener( "click", closeModal ); if (overlay) { overlay.addEventListener( "click", closeModal ); } document.addEventListener( "keydown", function (event) { if ( event.key === "Escape" && modal.classList.contains( "is-open" ) ) { closeModal(); } } ); })();
REGALOS
Tu presencia es nuestro mejor regalo pero si deseas tener un detalle con nosotros puedes hacerlo aquí
(function () { /* ================================================== CONFIGURACIÓN DEL CLIENTE ================================================== CAMBIAR SOLAMENTE ESTA SECCIÓN PARA CADA CLIENTE true = mostrar false = ocultar ================================================== */ const giftConfig = { /* ================================================ BLOQUE GENERAL ================================================ */ showSection: true, /* ================================================ TEXTO PRINCIPAL ================================================ */ description: "Tu presencia es nuestro mejor regalo pero si deseas tener un detalle con nosotros puedes hacerlo aquí", /* ================================================ LISTA DE REGALOS ================================================ */ showRegistry: true, registryUrl: "https://www.amazon.com/wedding/share/robertypatricia", /* ================================================ DINERO ================================================ */ showMoney: true, /* ================================================ ZELLE ================================================ */ showZelle: true, zelle: "[email protected]", /* ================================================ BANCO ================================================ */ showBank: true, bank: "Banco Ejemplo
Cuenta: XXXX XXXX XXXX XXXX" }; /* ================================================== ELEMENTOS ================================================== */ const section = document.getElementById( "lumiereGiftSection" ); const description = document.getElementById( "giftDescription" ); const registryButton = document.getElementById( "giftRegistryButton" ); const moneyButton = document.getElementById( "giftMoneyButton" ); const modal = document.getElementById( "moneyModal" ); const closeButton = document.getElementById( "moneyModalClose" ); const zelleMethod = document.getElementById( "moneyZelleMethod" ); const zelleText = document.getElementById( "moneyZelleText" ); const bankMethod = document.getElementById( "moneyBankMethod" ); const bankText = document.getElementById( "moneyBankText" ); const overlay = modal ? modal.querySelector( ".money-modal-overlay" ) : null; /* ================================================== TEXTO ================================================== */ if ( description && giftConfig.description ) { description.textContent = giftConfig.description; } /* ================================================== LISTA DE REGALOS ================================================== */ if (registryButton) { if ( giftConfig.showRegistry && giftConfig.registryUrl ) { registryButton.style.display = "inline-block"; registryButton.href = giftConfig.registryUrl; } else { registryButton.style.display = "none"; } } /* ================================================== ZELLE ================================================== */ if (zelleMethod) { if ( giftConfig.showZelle && giftConfig.zelle ) { zelleMethod.style.display = "block"; if (zelleText) { zelleText.textContent = giftConfig.zelle; } } else { zelleMethod.style.display = "none"; } } /* ================================================== BANCO ================================================== */ if (bankMethod) { if ( giftConfig.showBank && giftConfig.bank ) { bankMethod.style.display = "block"; if (bankText) { bankText.innerHTML = giftConfig.bank; } } else { bankMethod.style.display = "none"; } } /* ================================================== DETERMINAR SI EXISTE ALGÚN MÉTODO DE DINERO ================================================== */ const hasMoneyMethod = ( giftConfig.showZelle && giftConfig.zelle ) || ( giftConfig.showBank && giftConfig.bank ); /* ================================================== BOTÓN DINERO ================================================== */ if (moneyButton) { if ( giftConfig.showMoney && hasMoneyMethod ) { moneyButton.style.display = "inline-block"; } else { moneyButton.style.display = "none"; } } /* ================================================== SI NO HAY NINGUNA OPCIÓN DE REGALO OCULTAR TODO EL BLOQUE ================================================== */ const hasRegistry = giftConfig.showRegistry && giftConfig.registryUrl; const hasMoney = giftConfig.showMoney && hasMoneyMethod; if ( section && ( !giftConfig.showSection || (!hasRegistry && !hasMoney) ) ) { section.style.display = "none"; } /* ================================================== SI NO HAY DINERO NO NECESITAMOS EL MODAL ================================================== */ if ( modal && !hasMoney ) { modal.style.display = "none"; } /* ================================================== FUNCIONES DEL MODAL ================================================== */ function openModal() { if (!modal) { return; } modal.classList.add( "is-open" ); modal.setAttribute( "aria-hidden", "false" ); document.body.style.overflow = "hidden"; } function closeModal() { if (!modal) { return; } modal.classList.remove( "is-open" ); modal.setAttribute( "aria-hidden", "true" ); document.body.style.overflow = ""; } /* ================================================== CLICK EN DINERO ================================================== */ if ( moneyButton && hasMoney ) { moneyButton.addEventListener( "click", openModal ); } /* ================================================== CERRAR ================================================== */ if (closeButton) { closeButton.addEventListener( "click", closeModal ); } if (overlay) { overlay.addEventListener( "click", closeModal ); } document.addEventListener( "keydown", function (event) { if ( event.key === "Escape" && modal && modal.classList.contains( "is-open" ) ) { closeModal(); } } ); })();
CONFIRMACIÓN
Nos encantará compartir este día contigo
Por favor confirma tu asistencia antes del 20 de septiembre
¿NOS ACOMPAÑAS?
¡GRACIAS!
(function () { const form = document.getElementById( "rsvpForm" ); const yesOption = document.getElementById( "rsvpYes" ); const noOption = document.getElementById( "rsvpNo" ); const companionsSelect = document.getElementById( "rsvpCompanions" ); const companionNames = document.getElementById( "rsvpCompanionNames" ); const success = document.getElementById( "rsvpSuccess" ); const successText = document.getElementById( "rsvpSuccessText" ); const description = document.getElementById( "rsvpDescription" ); const deadline = document.getElementById( "rsvpDeadline" ); const submitButton = document.getElementById( "rsvpSubmit" ); const hiddenFrame = document.getElementById( "rsvpHiddenFrame" ); if ( !form || !yesOption || !noOption || !companionsSelect || !success || !successText || !submitButton || !hiddenFrame ) { return; } let submitting = false; let submittedAttendance = ""; let submittedCompanions = 0; /* ================================================== SI CAMBIA A NO LIMPIAR ACOMPAÑANTES ================================================== */ noOption.addEventListener( "change", function () { if (!noOption.checked) { return; } companionsSelect.value = "0"; companionNames.value = ""; companionNames.required = false; } ); /* ================================================== NOMBRES OBLIGATORIOS SI HAY ACOMPAÑANTES ================================================== */ companionsSelect.addEventListener( "change", function () { const quantity = Number( companionsSelect.value ); companionNames.required = quantity > 0; if (quantity === 0) { companionNames.value = ""; } } ); /* ================================================== MENSAJE FINAL ================================================== */ function createSuccessMessage() { if ( submittedAttendance === "No" ) { successText.innerHTML = "Gracias por dejarnos saber.

" + "Lamentaremos no poder compartir juntos"; return; } if ( submittedCompanions > 0 ) { successText.innerHTML = "Hemos recibido tu confirmación.

" + "Estamos muy emocionados de compartir juntos este día tan especial"; return; } successText.innerHTML = "Hemos recibido tu confirmación.

" + "Estamos muy emocionados de compartir este día tan especial contigo."; } /* ================================================== GOOGLE RECIBIÓ LA RESPUESTA ================================================== */ hiddenFrame.addEventListener( "load", function () { if (!submitting) { return; } submitting = false; if (description) { description.style.display = "none"; } if (deadline) { deadline.style.display = "none"; } form.style.display = "none"; createSuccessMessage(); success.style.display = "block"; success.scrollIntoView({ behavior: "smooth", block: "center" }); } ); /* ================================================== ENVÍO ================================================== */ form.addEventListener( "submit", function (event) { if (submitting) { event.preventDefault(); return; } if (yesOption.checked) { submittedAttendance = "Sí"; submittedCompanions = Number( companionsSelect.value || 0 ); } else { submittedAttendance = "No"; submittedCompanions = 0; } submitting = true; submitButton.disabled = true; submitButton.textContent = "ENVIANDO..."; } ); })();
IMPORTANTE
Algunos detalles para disfrutar juntos este día
(function () { const openButton = document.getElementById( "notesMoreButton" ); const modal = document.getElementById( "notesModal" ); const closeButton = document.getElementById( "notesModalClose" ); const overlay = modal ? modal.querySelector( ".notes-modal-overlay" ) : null; if ( !openButton || !modal || !closeButton ) { return; } function openModal() { modal.classList.add( "is-open" ); modal.setAttribute( "aria-hidden", "false" ); document.body.style.overflow = "hidden"; } function closeModal() { modal.classList.remove( "is-open" ); modal.setAttribute( "aria-hidden", "true" ); document.body.style.overflow = ""; } openButton.addEventListener( "click", openModal ); closeButton.addEventListener( "click", closeModal ); if (overlay) { overlay.addEventListener( "click", closeModal ); } document.addEventListener( "keydown", function (event) { if ( event.key === "Escape" && modal.classList.contains( "is-open" ) ) { closeModal(); } } ); })();
Robert & Patricia
Gracias por ser parte de nuestra historia
10 · 01 · 2026
(function () { const section = document.querySelector(".final-section"); if (!section) { return; } if ("IntersectionObserver" in window) { const observer = new IntersectionObserver( function (entries) { entries.forEach( function (entry) { if (entry.isIntersecting) { section.classList.add( "is-visible" ); observer.unobserve( section ); } }); }, { threshold: .25 } ); observer.observe( section ); } else { section.classList.add( "is-visible" ); } })();