/* global React, ReactDOM */ /* shared.jsx — componentes y utilidades comunes a todas las páginas */ const { useState, useEffect, useRef } = React; /* Base de assets resuelta desde la URL de ESTE script (shared.jsx, siempre en la raíz del sitio). Hace que las imágenes locales carguen igual en la home y en subpáginas como /tu-evento/ (subcarpeta), tanto en local (file://) como en el servidor — sin depender de rutas relativas ni de un prefijo fijo. */ const ASSET_BASE = (function () { try { var s = document.querySelector('script[src*="shared.jsx"]'); if (s && s.src) return s.src.replace(/[^/]*shared\.jsx.*$/, ''); } catch (e) {} return ''; })(); /* ────────── STOCK IMAGES (Unsplash) ────────── */ const IMG = { hero: 'https://images.unsplash.com/photo-1519741497674-611481863552?auto=format&fit=crop&w=2000&q=80', hero2: 'https://images.unsplash.com/photo-1464366400600-7168b8af9bc3?auto=format&fit=crop&w=2000&q=80', hero3: 'https://images.unsplash.com/photo-1465495976277-4387d4b0b4c6?auto=format&fit=crop&w=2000&q=80', sobre: ASSET_BASE + 'uploads/sesion/mom.webp', expBoda: 'https://images.unsplash.com/photo-1511795409834-ef04bbd61622?auto=format&fit=crop&w=1400&q=80', expRet: 'https://images.unsplash.com/photo-1517457373958-b7bdd4587205?auto=format&fit=crop&w=1400&q=80', expInt: 'https://images.unsplash.com/photo-1530023367847-a683933f4172?auto=format&fit=crop&w=1400&q=80', espExpl: ASSET_BASE + 'uploads/explanada.webp', espJard: ASSET_BASE + 'uploads/jardin.webp', espCasa: ASSET_BASE + 'uploads/santuario.webp', espAmen: ASSET_BASE + 'uploads/caminos.webp', bodas: 'https://images.unsplash.com/photo-1519741497674-611481863552?auto=format&fit=crop&w=2000&q=80', intimas: 'https://images.unsplash.com/photo-1530023367847-a683933f4172?auto=format&fit=crop&w=2000&q=80', parallax1: 'https://images.unsplash.com/photo-1505373877841-8d25f7d46678?auto=format&fit=crop&w=2400&q=85', parallax2: 'https://images.unsplash.com/photo-1465495976277-4387d4b0b4c6?auto=format&fit=crop&w=2400&q=85', gal: [], blog: [ 'https://images.unsplash.com/photo-1469371670807-013ccf25f16a?auto=format&fit=crop&w=1000&q=80', 'https://images.unsplash.com/photo-1465495976277-4387d4b0b4c6?auto=format&fit=crop&w=1000&q=80', 'https://images.unsplash.com/photo-1517457373958-b7bdd4587205?auto=format&fit=crop&w=1000&q=80'] }; /* ────────── CUSTOM CURSOR ────────── */ function CustomCursor() { const dotRef = useRef(null); const ringRef = useRef(null); useEffect(() => { let dx = 0,dy = 0,rx = 0,ry = 0,mx = 0,my = 0; const move = (e) => {mx = e.clientX;my = e.clientY;}; window.addEventListener('mousemove', move); let raf; const loop = () => { dx += (mx - dx) * 0.85; dy += (my - dy) * 0.85; rx += (mx - rx) * 0.18; ry += (my - ry) * 0.18; if (dotRef.current) dotRef.current.style.transform = `translate(${dx}px, ${dy}px) translate(-50%, -50%)`; if (ringRef.current) ringRef.current.style.transform = `translate(${rx}px, ${ry}px) translate(-50%, -50%)`; raf = requestAnimationFrame(loop); }; raf = requestAnimationFrame(loop); const hover = (e) => { const t = e.target; if (t.closest && t.closest('.wa-float')) { dotRef.current?.classList.remove('hover'); ringRef.current?.classList.remove('hover'); dotRef.current?.classList.add('neutral'); ringRef.current?.classList.add('neutral'); } else if (t.closest && t.closest('a, button, .btn, .exp-card, .gal-item, .blog-card, input, textarea, select')) { dotRef.current?.classList.remove('neutral'); ringRef.current?.classList.remove('neutral'); dotRef.current?.classList.add('hover'); ringRef.current?.classList.add('hover'); } else { dotRef.current?.classList.remove('neutral'); ringRef.current?.classList.remove('neutral'); dotRef.current?.classList.remove('hover'); ringRef.current?.classList.remove('hover'); } }; window.addEventListener('mouseover', hover); return () => { cancelAnimationFrame(raf); window.removeEventListener('mousemove', move); window.removeEventListener('mouseover', hover); }; }, []); return ( <>
); } /* ────────── REVEAL OBSERVER ────────── */ function useReveal() { useEffect(() => { const els = document.querySelectorAll('.reveal, .reveal-stagger, .split-line, .manifiesto, .curtain, .ornament, .draw-underline, .mask-reveal'); const io = new IntersectionObserver((entries) => { entries.forEach((e) => {if (e.isIntersecting) e.target.classList.add('in');}); }, { threshold: 0.15 }); els.forEach((el) => io.observe(el)); return () => io.disconnect(); }, []); } /* ────────── PARALLAX ────────── */ function useParallax() { useEffect(() => { const els = document.querySelectorAll('[data-parallax]'); const onScroll = () => { els.forEach((el) => { const speed = parseFloat(el.dataset.parallax) || 0.3; const rect = el.getBoundingClientRect(); const center = rect.top + rect.height / 2 - window.innerHeight / 2; el.style.transform = `translateY(${center * -speed}px)`; }); }; onScroll(); window.addEventListener('scroll', onScroll, { passive: true }); return () => window.removeEventListener('scroll', onScroll); }, []); } /* ────────── BG PARALLAX (background-image style) ────────── */ function useBgParallax() { useEffect(() => { const els = document.querySelectorAll('[data-bg-parallax]'); const onScroll = () => { els.forEach((el) => { const speed = parseFloat(el.dataset.bgParallax) || 0.2; const rect = el.getBoundingClientRect(); const center = rect.top + rect.height / 2 - window.innerHeight / 2; el.style.backgroundPosition = `center calc(50% + ${center * speed}px)`; }); }; onScroll(); window.addEventListener('scroll', onScroll, { passive: true }); return () => window.removeEventListener('scroll', onScroll); }, []); } /* ────────── SOCIAL LINKS (reutilizable en nav y overlay móvil) ────────── */ function SocialLinks({ className = 'nav-socials' }) { return (
); } /* ────────── NAV ────────── */ function Nav({ home = '/' }) { const [scrolled, setScrolled] = useState(false); const [menuOpen, setMenuOpen] = useState(false); useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 80); window.addEventListener('scroll', onScroll, { passive: true }); return () => window.removeEventListener('scroll', onScroll); }, []); useEffect(() => { document.body.style.overflow = menuOpen ? 'hidden' : ''; return () => { document.body.style.overflow = ''; }; }, [menuOpen]); const close = () => setMenuOpen(false); const links = [ ['/', 'Inicio'], ['/tu-evento', 'Tu evento'], ['/#galeria', 'Galería'], ['/blog', 'Blog'], ['/#contacto', 'Contacto']]; return ( <>
Hablemos
); } /* ────────── HELPERS ────────── */ function splitWords(text) { return text.split(' ').map((w, i) => {w} ); } function Particles({ count = 14 }) { const arr = Array.from({ length: count }); return (
{arr.map((_, i) => )}
); } function MagneticBtn({ children, ...props }) { const ref = useRef(null); const onMove = (e) => { const r = ref.current.getBoundingClientRect(); const x = e.clientX - r.left - r.width / 2; const y = e.clientY - r.top - r.height / 2; ref.current.style.transform = `translate(${x * 0.25}px, ${y * 0.35}px)`; }; const onLeave = () => {ref.current.style.transform = 'translate(0,0)';}; return ( {children} ); } /* ────────── MARQUEE ────────── */ function Ornament({ glyph = '❧' }) { return (
{glyph}
); } function Marquee({ items }) { const list = [...items, ...items]; return (
{list.map((item, i) => {item.text} )}
); } /* ────────── PARALLAX BG SECTION ────────── */ /* Sección con imagen full-bleed como background y overlay con texto */ function ParallaxSection({ image, overlay = 'light', minHeight = 90, speed = 0.18, padding = '128px 40px', children, className = '' }) { const overlayStyle = overlay === 'dark' ? { position: 'absolute', inset: 0, zIndex: 1, pointerEvents: 'none', background: 'linear-gradient(to top, rgba(5,3,2,0.92) 0%, rgba(5,3,2,0.60) 40%, rgba(5,3,2,0.28) 100%)' } : { position: 'absolute', inset: 0, zIndex: 1, pointerEvents: 'none', background: 'linear-gradient(135deg, rgba(250,248,244,0.88) 0%, rgba(243,239,232,0.72) 100%)' }; return (
{children}
); } /* ────────── SUB-HERO compacto para LP titulares ────────── */ function PageHero({ image, eyebrow, title, lead, cta }) { const imgRef = useRef(null); useEffect(() => { const onScroll = () => { if (!imgRef.current) return; const y = window.scrollY; imgRef.current.style.transform = `translateY(${y * 0.32}px) scale(1.05)`; }; window.addEventListener('scroll', onScroll, { passive: true }); return () => window.removeEventListener('scroll', onScroll); }, []); return (
{eyebrow}

{title}

{lead}

{cta &&
{cta}
}
Scroll
); } /* ────────── CONTACTO ────────── */ function Contacto() { const WA_PHONE = '5214421715407'; const loadedAt = useRef(Date.now()); const sendWhatsApp = (e) => { e.preventDefault(); const f = e.currentTarget; const get = (n) => ((f.elements[n] && f.elements[n].value) || '').trim(); // Anti-bot: si el campo trampa (honeypot) está lleno, o el envío es casi // instantáneo tras cargar, lo ignoramos en silencio (comportamiento de bot). if (get('empresa')) return; if (Date.now() - loadedAt.current < 2500) return; const nombre = get('nombre'); const correo = get('correo'); const tipo = get('tipo'); const fecha = get('fecha'); const msg = get('mensaje'); const lines = [ 'Hola, me gustaría más información sobre Quinta Mompaní.', '', `*Nombre:* ${nombre}`, `*Correo:* ${correo}`, `*Tipo de evento:* ${tipo}`]; if (fecha) lines.push(`*Fecha tentativa:* ${fecha}`); if (msg) lines.push(`*Mensaje:* ${msg}`); const url = `https://wa.me/${WA_PHONE}?text=${encodeURIComponent(lines.join('\n'))}`; window.open(url, '_blank', 'noopener,noreferrer'); }; return (
Hablemos

¿Listo para
empezar a soñar?

Platicar con nosotros es fácil. Nuestro asistente virtual está disponible 24/7 para darte respuestas al instante sobre fechas y paquetes. Si detecta que estás listo, te canalizará con un anfitrión humano de inmediato.

Hablemos. Respuestas al instante.
Horario Martes a sábado de 9 a 5
— Formulario rápido

Cuéntanos de tu visión.

{/* honeypot anti-bot: oculto para humanos, los bots tienden a rellenarlo */}
); } /* ────────── FOOTER ────────── */ function Footer() { return ( ); } /* ────────── WHATSAPP FLOATING ────────── */ function WhatsAppFloat() { return ( Hablemos.Respuestas al instante ); } /* Expose to other Babel scripts */ Object.assign(window, { IMG, CustomCursor, useReveal, useParallax, useBgParallax, Nav, Hero: null, splitWords, Particles, MagneticBtn, Ornament, Marquee, ParallaxSection, PageHero, Contacto, Footer, WhatsAppFloat });