/* ===== Los 40 de Jona — App ===== */
const { useState, useEffect, useRef, useMemo, useCallback } = React;

const DEV_MODE = new URLSearchParams(location.search).has('dev');

// === Event details ===
const EVENT = {
  title: "Los 40 de Jona",
  date: new Date('2026-06-05T21:00:00-04:00'),
  endDate: new Date('2026-06-06T02:00:00-04:00'),
  location: "ConserBar",
  address: "Av. Condell 1189, Providencia, Santiago, Chile",
  outfit: "Ropa Negra",
  giftListUrl: "https://milistaderegalos.cl/cumpleanos/los40deJona",
  whatsapp: "+56942194611",
};

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "intensity": "high",
  "palette": "green",
  "showStarfield": true,
  "showShootingStars": true,
  "musicByDefault": false
}/*EDITMODE-END*/;

// === Starfield ===
function Starfield({ enabled, shooters }) {
  const stars = useMemo(() => {
    const arr = [];
    for (let i = 0; i < 80; i++) {
      arr.push({
        id: i,
        x: Math.random() * 100,
        y: Math.random() * 100,
        size: Math.random() * 2 + 0.5,
        dur: Math.random() * 3 + 2,
        delay: Math.random() * 4,
      });
    }
    return arr;
  }, []);
  const shootingStars = useMemo(() => {
    const arr = [];
    for (let i = 0; i < 4; i++) {
      arr.push({
        id: i,
        x: Math.random() * 60,
        y: Math.random() * 50,
        dur: Math.random() * 3 + 4,
        delay: i * 3 + Math.random() * 2,
      });
    }
    return arr;
  }, []);
  if (!enabled) return null;
  return (
    <div className="starfield">
      {stars.map(s => (
        <div key={s.id} className="star" style={{
          left: `${s.x}%`, top: `${s.y}%`,
          width: `${s.size}px`, height: `${s.size}px`,
          '--dur': `${s.dur}s`, '--delay': `${s.delay}s`,
        }} />
      ))}
      {shooters && shootingStars.map(s => (
        <div key={'sh' + s.id} className="shooting-star" style={{
          left: `${s.x}%`, top: `${s.y}%`,
          '--dur': `${s.dur}s`, '--delay': `${s.delay}s`,
        }} />
      ))}
    </div>
  );
}

// === Hero ===
function Hero({ intensity, onJonaTap }) {
  const particles = useMemo(() => {
    const count = intensity === 'low' ? 0 : intensity === 'med' ? 6 : 12;
    return Array.from({ length: count }, (_, i) => ({
      id: i,
      x: Math.random() * 90 + 5,
      y: Math.random() * 90 + 5,
      dx: (Math.random() - 0.5) * 50,
      dy: (Math.random() - 0.5) * 60 - 10,
      dur: Math.random() * 4 + 4,
      delay: Math.random() * 3,
    }));
  }, [intensity]);

  return (
    <div className="hero">
      <div className="hero-img-wrap">
        <img className="hero-img" src="assets/hero-top.png" alt="Los 40 de Jona" />
      </div>
      {intensity !== 'low' && <div className="portal-glow" />}
      {particles.map(p => (
        <div key={p.id} className="hero-particle" style={{
          left: `${p.x}%`, top: `${p.y}%`,
          '--dx': `${p.dx}px`, '--dy': `${p.dy}px`,
          '--dur': `${p.dur}s`, '--delay': `${p.delay}s`,
        }} />
      ))}
      <div className="hero-glow-ring" />
      {onJonaTap && <button className="jona-head" onClick={onJonaTap} aria-label="Easter egg" />}
    </div>
  );
}

// === Countdown ===
function useCountdown(target) {
  const [now, setNow] = useState(() => Date.now());
  useEffect(() => {
    const t = setInterval(() => setNow(Date.now()), 1000);
    return () => clearInterval(t);
  }, []);
  const diff = Math.max(0, target.getTime() - now);
  const d = Math.floor(diff / 86400000);
  const h = Math.floor((diff % 86400000) / 3600000);
  const m = Math.floor((diff % 3600000) / 60000);
  const s = Math.floor((diff % 60000) / 1000);
  return { d, h, m, s, isOver: diff === 0 };
}

function Countdown() {
  const { d, h, m, s } = useCountdown(EVENT.date);
  const pad = n => String(n).padStart(2, '0');
  return (
    <div className="countdown">
      {[
        { v: pad(d), l: 'Días' },
        { v: pad(h), l: 'Hrs' },
        { v: pad(m), l: 'Min' },
        { v: pad(s), l: 'Seg' },
      ].map((u, i) => (
        <div key={i} className="countdown-unit">
          <div className="countdown-num">{u.v}</div>
          <div className="countdown-lbl">{u.l}</div>
        </div>
      ))}
    </div>
  );
}

// === Calendar links ===
function buildCalendarLinks() {
  const fmt = (d) => d.toISOString().replace(/[-:]/g, '').replace(/\.\d{3}/, '');
  const start = fmt(EVENT.date);
  const end = fmt(EVENT.endDate);
  const title = encodeURIComponent(EVENT.title);
  const details = encodeURIComponent(`¡Estás invitado a la celebración de los 40 de Jona!\n\nOutfit: ${EVENT.outfit}\nLista de regalos: ${EVENT.giftListUrl}`);
  const loc = encodeURIComponent(`${EVENT.location}, ${EVENT.address}`);
  const google = `https://www.google.com/calendar/render?action=TEMPLATE&text=${title}&dates=${start}/${end}&details=${details}&location=${loc}`;
  // ICS file (data URL)
  const ics = [
    'BEGIN:VCALENDAR', 'VERSION:2.0', 'PRODID:-//jona//40//ES',
    'BEGIN:VEVENT',
    `UID:${Date.now()}@jona40`,
    `DTSTAMP:${start}`,
    `DTSTART:${start}`,
    `DTEND:${end}`,
    `SUMMARY:${EVENT.title}`,
    `LOCATION:${EVENT.location}, ${EVENT.address}`,
    `DESCRIPTION:¡Estás invitado a la celebración de los 40 de Jona!`,
    'END:VEVENT', 'END:VCALENDAR',
  ].join('\r\n');
  const icsUrl = 'data:text/calendar;charset=utf8,' + encodeURIComponent(ics);
  return { google, icsUrl };
}

// === Card (flippable) ===
function Card({ icon, iconClass, label, value, sub, hint, children, tall }) {
  const [flipped, setFlipped] = useState(false);
  return (
    <div className={`card${tall ? ' card-tall' : ''}${flipped ? ' flipped' : ''}`}
         onClick={() => setFlipped(f => !f)}>
      <div className="card-inner">
        <div className="card-face card-front">
          <div className={`card-icon ${iconClass || ''}`}>{icon}</div>
          <div className="card-content">
            <div className="card-label">{label}</div>
            <div className="card-value">{value}</div>
            {sub && <div className="card-sub">{sub}</div>}
          </div>
          <div className="card-hint">{hint || 'TAP →'}</div>
        </div>
        <div className="card-face card-back" onClick={(e) => e.stopPropagation()}>
          <div onClick={() => setFlipped(false)} style={{ position: 'absolute', top: 6, right: 10, color: 'var(--ink-dim)', fontSize: 12, cursor: 'pointer', fontFamily: 'Space Mono, monospace' }}>✕</div>
          {children}
        </div>
      </div>
    </div>
  );
}

// === Toast hook ===
function useToast() {
  const [toast, setToast] = useState(null);
  const show = useCallback((msg) => {
    setToast(msg);
    setTimeout(() => setToast(null), 2200);
  }, []);
  return [toast, show];
}

// === Confetti ===
function fireConfetti() {
  const canvas = document.getElementById('confetti-canvas');
  if (!canvas) return;
  const ctx = canvas.getContext('2d');
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  const colors = ['#39ff14', '#a855f7', '#d946ef', '#22d3ee', '#ffffff'];
  const particles = [];
  for (let i = 0; i < 140; i++) {
    particles.push({
      x: canvas.width / 2 + (Math.random() - 0.5) * 80,
      y: canvas.height * 0.6,
      vx: (Math.random() - 0.5) * 14,
      vy: -Math.random() * 18 - 6,
      g: 0.4,
      size: Math.random() * 6 + 3,
      color: colors[Math.floor(Math.random() * colors.length)],
      rot: Math.random() * Math.PI,
      vrot: (Math.random() - 0.5) * 0.3,
      life: 1,
    });
  }
  let frame = 0;
  const animate = () => {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    particles.forEach(p => {
      p.vy += p.g;
      p.x += p.vx;
      p.y += p.vy;
      p.rot += p.vrot;
      p.life -= 0.008;
      ctx.save();
      ctx.translate(p.x, p.y);
      ctx.rotate(p.rot);
      ctx.globalAlpha = Math.max(0, p.life);
      ctx.fillStyle = p.color;
      ctx.fillRect(-p.size / 2, -p.size / 2, p.size, p.size * 0.5);
      ctx.restore();
    });
    frame++;
    if (frame < 200) requestAnimationFrame(animate);
    else ctx.clearRect(0, 0, canvas.width, canvas.height);
  };
  animate();
}

// === Background music (Web Audio synthesized, no external file) ===
class MusicEngine {
  constructor() { this.ctx = null; this.playing = false; this.nodes = []; }
  start() {
    if (this.playing) return;
    const AC = window.AudioContext || window.webkitAudioContext;
    if (!AC) return;
    this.ctx = new AC();
    const ctx = this.ctx;
    const master = ctx.createGain();
    master.gain.value = 0.08;
    master.connect(ctx.destination);

    // Spacy pad: two oscillators detuned + slow LFO + reverb-ish delay
    const makeOsc = (freq, type, detune) => {
      const o = ctx.createOscillator();
      o.type = type; o.frequency.value = freq; o.detune.value = detune;
      const g = ctx.createGain(); g.gain.value = 0.5;
      o.connect(g).connect(master);
      o.start();
      return { o, g };
    };
    // Chord: A minor (220Hz) -> F (174.6) -> C (261) -> G (196) — 4-bar loop
    const root = 110;
    const chords = [
      [110, 165, 220], // A2 E3 A3
      [87.3, 130.8, 174.6], // F2 C3 F3
      [98, 130.8, 196], // G2 C3 G3
      [130.8, 196, 261.6], // C3 G3 C4
    ];
    let chordIdx = 0;
    const oscs = [
      makeOsc(110, 'sine', 0),
      makeOsc(110, 'triangle', 8),
      makeOsc(220, 'sine', -6),
    ];
    this.nodes.push(...oscs.map(x => x.o));
    // LFO
    const lfo = ctx.createOscillator();
    lfo.frequency.value = 0.2;
    const lfoGain = ctx.createGain();
    lfoGain.gain.value = 0.04;
    lfo.connect(lfoGain).connect(master.gain);
    lfo.start();
    this.nodes.push(lfo);

    const setChord = (c) => {
      oscs[0].o.frequency.linearRampToValueAtTime(c[0], ctx.currentTime + 0.3);
      oscs[1].o.frequency.linearRampToValueAtTime(c[1], ctx.currentTime + 0.3);
      oscs[2].o.frequency.linearRampToValueAtTime(c[2], ctx.currentTime + 0.3);
    };
    setChord(chords[0]);
    this.interval = setInterval(() => {
      chordIdx = (chordIdx + 1) % chords.length;
      setChord(chords[chordIdx]);
    }, 3200);

    this.master = master;
    this.playing = true;
  }
  stop() {
    if (!this.playing) return;
    if (this.interval) clearInterval(this.interval);
    if (this.master) this.master.gain.linearRampToValueAtTime(0, this.ctx.currentTime + 0.3);
    setTimeout(() => {
      this.nodes.forEach(n => { try { n.stop(); } catch(e){} });
      try { this.ctx.close(); } catch(e){}
      this.nodes = [];
      this.playing = false;
    }, 400);
  }
}
const music = new MusicEngine();

// === Easter egg modal ===
function EasterEggModal({ onClose }) {
  return (
    <div className="easter-modal" onClick={onClose}>
      <div className="easter-content" onClick={e => e.stopPropagation()}>
        <div className="easter-emoji">👽</div>
        <div className="easter-title">¡Wubba Lubba Dub Dub!</div>
        <div className="easter-msg">
          Has descubierto el portal secreto de Jona.<br/>
          Hay un shot de tequila esperándote en el bar 🍹<br/>
          <span style={{ color: 'var(--neon)', fontWeight: 700 }}>Pídelo diciendo "los 40"</span>
        </div>
        <button className="easter-close" onClick={onClose}>CERRAR PORTAL</button>
      </div>
    </div>
  );
}

// === RSVP card ===
function RsvpCard({ onConfirm, whatsappLink }) {
  const [name, setName] = useState('');
  const [choice, setChoice] = useState(null);
  const [companions, setCompanions] = useState(0);
  const [confirmed, setConfirmed] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState(null);

  // Restore desde backend (con fallback a localStorage)
  useEffect(() => {
    fetch('/api/rsvp/me', { credentials: 'same-origin' })
      .then(r => r.ok ? r.json() : null)
      .then(data => {
        if (data && data.rsvp) {
          setName(data.rsvp.nombre_completo || '');
          setChoice(data.rsvp.choice || null);
          setCompanions(data.rsvp.companions || 0);
          setConfirmed(true);
          return;
        }
        try {
          const saved = JSON.parse(localStorage.getItem('jona40_rsvp') || 'null');
          if (saved) {
            setName(saved.name || '');
            setChoice(saved.choice || null);
            setCompanions(saved.companions || 0);
            setConfirmed(saved.confirmed || false);
          }
        } catch(e){}
      })
      .catch(() => {});
  }, []);

  const trimmed = name.trim();
  const nameValid = /\S+\s+\S+/.test(trimmed) && trimmed.length >= 3 && trimmed.length <= 80;

  const submit = async () => {
    setError(null);
    if (!nameValid) { setError('Escribe tu nombre y apellido.'); return; }
    if (!choice) return;
    setSubmitting(true);
    try {
      const r = await fetch('/api/rsvp', {
        method: 'POST',
        credentials: 'same-origin',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ nombre_completo: trimmed, choice, companions })
      });
      if (!r.ok) {
        const j = await r.json().catch(() => ({}));
        throw new Error(j.error || 'No pudimos guardar tu respuesta. Intenta de nuevo.');
      }
      const payload = { name: trimmed, choice, companions, confirmed: true, ts: Date.now() };
      localStorage.setItem('jona40_rsvp', JSON.stringify(payload));
      setConfirmed(true);
      if (choice === 'yes') fireConfetti();
      onConfirm(payload);
    } catch(e) {
      setError(e.message || 'Error al enviar.');
    } finally {
      setSubmitting(false);
    }
  };

  const reset = () => {
    localStorage.removeItem('jona40_rsvp');
    setConfirmed(false);
    setChoice(null);
    setName('');
    setCompanions(0);
    setError(null);
  };

  if (confirmed) {
    const firstName = trimmed.split(/\s+/)[0] || trimmed;
    const messages = {
      yes: { emoji: '🎉', title: '¡NOS VEMOS!', msg: `Gracias ${firstName}. Te esperamos el viernes 5 de junio a las 21:00 en ConserBar.` },
      maybe: { emoji: '🤔', title: 'AVÍSANOS', msg: `${firstName}, esperamos confirmes pronto. ¡La fiesta no será igual sin ti!` },
      no: { emoji: '😢', title: 'TE EXTRAÑAREMOS', msg: `Lamentamos que no puedas, ${firstName}. ¡Será una noche memorable!` },
    };
    const m = messages[choice];
    return (
      <div className="rsvp-card">
        <div className="rsvp-confirmed">
          <div className="rsvp-confirmed-emoji">{m.emoji}</div>
          <div className="rsvp-confirmed-title">{m.title}</div>
          <div className="rsvp-confirmed-msg">{m.msg}</div>
          <div style={{ marginTop: 14, display: 'flex', gap: 8, justifyContent: 'center', flexWrap: 'wrap' }}>
            <button onClick={reset} style={{
              padding: '8px 16px', background: 'transparent',
              border: '1px solid var(--ink-dim)', borderRadius: 8, color: 'var(--ink-dim)',
              fontFamily: 'Inter', fontSize: 12, cursor: 'pointer'
            }}>Modificar respuesta</button>
            {whatsappLink && (
              <a href={whatsappLink} target="_blank" rel="noopener" style={{
                padding: '8px 16px', background: 'rgba(37,211,102,0.15)',
                border: '1px solid #25d366', borderRadius: 8, color: '#25d366',
                fontFamily: 'Inter', fontSize: 12, textDecoration: 'none'
              }}>💬 Avisar por WhatsApp</a>
            )}
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="rsvp-card">
      <div className="rsvp-title">¡CONFIRMA TU ASISTENCIA!</div>
      <input className="input" placeholder="Nombre y apellido"
             value={name} onChange={e => setName(e.target.value)}
             autoComplete="name" maxLength={80} />
      <div className="rsvp-options">
        <button className={`rsvp-opt yes${choice === 'yes' ? ' active' : ''}`} onClick={() => setChoice('yes')}>
          <span className="rsvp-emoji">✅</span>
          <span>SÍ VOY</span>
        </button>
        <button className={`rsvp-opt maybe${choice === 'maybe' ? ' active' : ''}`} onClick={() => setChoice('maybe')}>
          <span className="rsvp-emoji">🤔</span>
          <span>TAL VEZ</span>
        </button>
        <button className={`rsvp-opt no${choice === 'no' ? ' active' : ''}`} onClick={() => setChoice('no')}>
          <span className="rsvp-emoji">❌</span>
          <span>NO PUEDO</span>
        </button>
      </div>
      {choice === 'yes' && (
        <div style={{ marginTop: 12 }}>
          <label style={{ fontSize: 12, color: 'var(--ink-dim)', display: 'block', marginBottom: 6 }}>
            ¿Vienes con acompañantes?
          </label>
          <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
            <button onClick={() => setCompanions(Math.max(0, companions - 1))}
                    style={{ width: 36, height: 36, borderRadius: 8, background: 'rgba(57,255,20,0.1)', border: '1px solid var(--neon)', color: 'var(--neon)', fontSize: 18, cursor: 'pointer' }}>−</button>
            <div style={{ flex: 1, textAlign: 'center', fontFamily: 'Space Mono, monospace', fontSize: 16, color: 'white' }}>
              {companions === 0 ? 'Solo yo' : `+${companions} ${companions === 1 ? 'persona' : 'personas'}`}
            </div>
            <button onClick={() => setCompanions(Math.min(1, companions + 1))}
                    style={{ width: 36, height: 36, borderRadius: 8, background: 'rgba(57,255,20,0.1)', border: '1px solid var(--neon)', color: 'var(--neon)', fontSize: 18, cursor: 'pointer' }}>+</button>
          </div>
        </div>
      )}
      {error && (
        <div style={{ marginTop: 10, padding: '8px 12px', background: 'rgba(239,68,68,0.15)',
                      border: '1px solid #ef4444', borderRadius: 8, color: '#fca5a5',
                      fontSize: 12, fontFamily: 'Inter' }}>{error}</div>
      )}
      <button className="rsvp-submit" disabled={!nameValid || !choice || submitting} onClick={submit}>
        {submitting ? 'ENVIANDO…' : 'ENVIAR RSVP'}
      </button>
    </div>
  );
}

// === Main App ===
function App() {
  const tweaks = (typeof useTweaks !== 'undefined') ? useTweaks(TWEAK_DEFAULTS) : [TWEAK_DEFAULTS, () => {}];
  const [t, setTweak] = tweaks;
  const [toast, showToast] = useToast();
  const [musicOn, setMusicOn] = useState(false);
  const [easterEgg, setEasterEgg] = useState(false);
  const [easterCount, setEasterCount] = useState(0);
  const easterTimerRef = useRef(null);

  // Apply palette variant
  useEffect(() => {
    document.body.classList.remove('variant-pink', 'variant-cyan');
    if (t.palette === 'pink') document.body.classList.add('variant-pink');
    else if (t.palette === 'cyan') document.body.classList.add('variant-cyan');
  }, [t.palette]);

  // Tracking de visitas: una por sesion del tab
  useEffect(() => {
    if (sessionStorage.getItem('cumple_visited_session')) return;
    sessionStorage.setItem('cumple_visited_session', '1');
    fetch('/api/visit', { method: 'POST', credentials: 'same-origin' }).catch(() => {});
  }, []);

  const onJonaTap = () => {
    const c = easterCount + 1;
    setEasterCount(c);
    if (easterTimerRef.current) clearTimeout(easterTimerRef.current);
    easterTimerRef.current = setTimeout(() => setEasterCount(0), 2000);
    if (c >= 5) {
      setEasterEgg(true);
      setEasterCount(0);
      fireConfetti();
    } else if (c >= 3) {
      showToast(`Sigue tocando... ${5 - c} más`);
    }
  };

  const toggleMusic = () => {
    if (musicOn) { music.stop(); setMusicOn(false); }
    else { music.start(); setMusicOn(true); }
  };

  const calLinks = useMemo(() => buildCalendarLinks(), []);
  const mapsUrl = `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(EVENT.location + ', ' + EVENT.address)}`;
  // Uber deep-link: abre la app o m.uber.com con destino pre-cargado
  const uberUrl = `https://m.uber.com/ul/?action=setPickup&pickup=my_location&dropoff[formatted_address]=${encodeURIComponent(EVENT.location + ', ' + EVENT.address)}&dropoff[nickname]=${encodeURIComponent(EVENT.location)}`;

  const [whatsappLink, setWhatsappLink] = useState(null);

  const copyToClipboard = (text, msg) => {
    navigator.clipboard?.writeText(text).then(() => showToast(msg || 'Copiado ✓'));
  };

  const onRsvpConfirm = (payload) => {
    showToast('¡RSVP confirmado!');
    // WhatsApp queda como secundario opcional, no se auto-abre
    const choiceText = { yes: 'SÍ asistiré', maybe: 'TAL VEZ asisto', no: 'NO podré ir' }[payload.choice];
    const compText = payload.choice === 'yes' && payload.companions > 0
      ? ` (con ${payload.companions} acompañante${payload.companions > 1 ? 's' : ''})` : '';
    const msg = `¡Hola Jona! 🎉 Soy ${payload.name}. ${choiceText}${compText} a tu cumpleaños el 5 de junio.`;
    setWhatsappLink(`https://wa.me/${EVENT.whatsapp.replace(/\D/g, '')}?text=${encodeURIComponent(msg)}`);
  };

  return (
    <>
      <Starfield enabled={t.showStarfield} shooters={t.showShootingStars && t.intensity !== 'low'} />
      <div className="app">
        <Hero intensity={t.intensity} onJonaTap={DEV_MODE ? onJonaTap : undefined} />

        <div style={{ height: 24 }}></div>

        <div className="cards">
          {/* FECHA */}
          <Card icon="📅" iconClass="calendar" label="FECHA"
                value="VIE 05 DE JUNIO" sub="2026" tall>
            <div className="back-title">AGENDAR EVENTO</div>
            <a className="btn" style={{ padding: '8px 12px' }} href={calLinks.google} target="_blank" rel="noopener">
              📆 Google Calendar
            </a>
            <a className="btn btn-secondary" style={{ padding: '8px 12px' }} href={calLinks.icsUrl}
               download="los40-de-jona.ics">
              🍎 Apple / Outlook (.ics)
            </a>
          </Card>

          {/* HORA — cuenta regresiva */}
          <Card icon="🕘" iconClass="clock" label="HORA"
                value="DESDE LAS 21:00" sub="HASTA LAS 2:00" tall>
            <div className="back-title">CUENTA REGRESIVA</div>
            <Countdown />
          </Card>

          {/* LUGAR */}
          <Card icon="📍" iconClass="pin" label="LUGAR"
                value="CONSERBAR" sub="Av. Condell 1189, Providencia" tall>
            <div className="back-title">CÓMO LLEGAR</div>
            <div style={{ textAlign: 'center', fontSize: 12, color: 'var(--ink-dim)', lineHeight: 1.5, marginBottom: 6 }}>
              <div style={{ color: 'var(--neon)', fontFamily: 'Bangers, BangersFallback, Impact, sans-serif', letterSpacing: 1, fontSize: 15 }}>
                CONSERBAR
              </div>
              Av. Condell 1189, Providencia
            </div>
            <div style={{ display: 'flex', gap: 8 }}>
              <a className="btn" style={{ flex: 1, padding: '10px 8px' }} href={mapsUrl} target="_blank" rel="noopener">
                🗺️ Maps
              </a>
              <a className="btn btn-purple" style={{ flex: 1, padding: '10px 8px' }} href={uberUrl} target="_blank" rel="noopener">
                🚗 Uber
              </a>
            </div>
          </Card>

          {/* OUTFIT */}
          <Card icon="👕" iconClass="shirt" label="OUTFIT"
                value="ROPA NEGRA" hint="">
            <div className="back-title">DRESS CODE</div>
            <div style={{ fontSize: 12, color: 'var(--ink-dim)', textAlign: 'center', lineHeight: 1.5 }}>
              Total black con accesorios neón ✨<br/>
              <span style={{ color: 'var(--neon)' }}>Acepta pulseras y zapatillas fluo</span>
            </div>
          </Card>

          {/* LISTA DE REGALO */}
          <Card icon="🎁" iconClass="gift" label="LISTA DE REGALO"
                value="MILISTADEREGALOS.CL" sub="cumpleanos/los40deJona" tall>
            <div className="back-title">REGALOS</div>
            <a className="btn" href={EVENT.giftListUrl} target="_blank" rel="noopener">
              🎁 Abrir lista
            </a>
            <button className="btn btn-secondary" onClick={(e) => {
              e.stopPropagation();
              copyToClipboard(EVENT.giftListUrl, '¡Link copiado! 📋');
            }}>
              📋 Copiar link
            </button>
          </Card>
        </div>

        <RsvpCard onConfirm={onRsvpConfirm} whatsappLink={whatsappLink} />

        <div className="footer">
          MADE WITH 💚 FOR JONA · 2026
        </div>
      </div>

      <button className={`music-toggle${musicOn ? ' playing' : ''}`} onClick={toggleMusic}
              aria-label="Música de fondo">
        {musicOn ? '🎵' : '🔇'}
      </button>

      <canvas id="confetti-canvas"></canvas>

      {easterEgg && <EasterEggModal onClose={() => setEasterEgg(false)} />}
      {toast && <div className="toast">{toast}</div>}

      {/* Tweaks panel — solo en modo dev (?dev=1) */}
      {DEV_MODE && typeof TweaksPanel !== 'undefined' && (
        <TweaksPanel title="Tweaks">
          <TweakSection title="Animación">
            <TweakRadio label="Intensidad" value={t.intensity}
                        options={[
                          { value: 'low', label: 'Baja' },
                          { value: 'med', label: 'Media' },
                          { value: 'high', label: 'Alta' },
                        ]}
                        onChange={v => setTweak('intensity', v)} />
            <TweakToggle label="Estrellas" value={t.showStarfield}
                         onChange={v => setTweak('showStarfield', v)} />
            <TweakToggle label="Estrellas fugaces" value={t.showShootingStars}
                         onChange={v => setTweak('showShootingStars', v)} />
          </TweakSection>
          <TweakSection title="Color">
            <TweakRadio label="Paleta" value={t.palette}
                        options={[
                          { value: 'green', label: 'Verde' },
                          { value: 'pink', label: 'Rosa' },
                          { value: 'cyan', label: 'Cyan' },
                        ]}
                        onChange={v => setTweak('palette', v)} />
          </TweakSection>
        </TweaksPanel>
      )}
    </>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
