/* ==========================================================================
   GUÍA RÁPIDA PARA EDITAR ESTE ARCHIVO
   --------------------------------------------------------------------------
   Busca (Ctrl + F) los títulos con ===== para saltar a cada parte:

     ===== TEXTO DE CADA NORMA AL ABRIRSE =====  -> cambiar lo que dice cada
                                                    tarjeta al tocar "Ver detalle"
     ===== NÚMERO DE WHATSAPP =====              -> cambiar el número del botón
                                                    que sale dentro de las normas
     ===== COLORES AZULES POR SECCIÓN =====      -> cómo cambia el fondo al bajar
                                                    (los colores se editan en
                                                    index.html, en data-tono="...")
     ===== VIDEO personacomprando =====          -> botones de pausa y sonido
   ========================================================================== */

gsap.registerPlugin(ScrollTrigger);

const reducir = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const conRaton = window.matchMedia('(hover: hover) and (pointer: fine)').matches;

AOS.init({
  duration: 800,
  once: true,
  offset: 80,
  disable: reducir
});

/* Año del pie de página: se actualiza solo */
const anio = document.getElementById('anio');
if (anio) anio.textContent = new Date().getFullYear();

const navbar   = document.getElementById('navbar');
const burger   = document.getElementById('burger');
const menu     = document.getElementById('menu');
const progreso = document.getElementById('progreso');


/* ===== BARRA DE PROGRESO Y SOMBRA DEL MENÚ ===== */
function alHacerScroll() {
  navbar.classList.toggle('con-sombra', window.scrollY > 10);
  const total = document.documentElement.scrollHeight - window.innerHeight;
  progreso.style.transform = 'scaleX(' + (total > 0 ? window.scrollY / total : 0) + ')';
}
window.addEventListener('scroll', alHacerScroll, { passive: true });
alHacerScroll();


/* ===== MENÚ DE CELULAR (hamburguesa) ===== */
burger.addEventListener('click', () => {
  const abierto = menu.classList.toggle('abierto');
  burger.setAttribute('aria-expanded', abierto);
});

menu.querySelectorAll('a').forEach(enlace => {
  enlace.addEventListener('click', () => {
    menu.classList.remove('abierto');
    burger.setAttribute('aria-expanded', 'false');
  });
});


/* ===== ANIMACIÓN DE ENTRADA DE LA PORTADA ===== */
if (!reducir) {
  gsap.from('.hero-etiqueta, .hero-contenido h1, .hero-contenido p, .hero-botones', {
    y: 36,
    opacity: 0,
    duration: 1,
    stagger: 0.18,
    ease: 'power3.out',
    delay: 0.2
  });
}


/* ===== COLORES AZULES POR SECCIÓN =====
   Cada <section data-tono="#......"> tiene su propio azul marino.
   Al llegar a la sección, el fondo de toda la página cambia suavemente.
   Para cambiar un color: edita data-tono en index.html. */
gsap.set(document.body, { backgroundColor: '#0f1733' });

document.querySelectorAll('[data-tono]').forEach(seccion => {
  ScrollTrigger.create({
    trigger: seccion,
    start: 'top 55%',
    end: 'bottom 55%',
    onToggle: self => {
      if (!self.isActive) return;
      gsap.to(document.body, {
        backgroundColor: seccion.dataset.tono,
        duration: reducir ? 0 : 1.1,
        ease: 'power1.inOut',
        overwrite: 'auto'
      });
    }
  });
});


/* ===== BOTÓN DEL MENÚ QUE SE ILUMINA SEGÚN LA SECCIÓN ===== */
document.querySelectorAll('main section[id], #inicio').forEach(seccion => {
  const enlace = menu.querySelector('a[href="#' + seccion.id + '"]');
  if (!enlace || enlace.classList.contains('boton-menu')) return;
  ScrollTrigger.create({
    trigger: seccion,
    start: 'top 50%',
    end: 'bottom 50%',
    onToggle: self => enlace.classList.toggle('activo', self.isActive)
  });
});


/* ===== AVIÓN Y BARCO QUE SE MUEVEN AL HACER SCROLL =====
   (para quitarlos: bórralos en index.html, los bloques class="carril") */
if (!reducir) {
  document.querySelectorAll('.carril').forEach(carril => {
    const nave = carril.querySelector('.avion, .barco');
    if (!nave) return;

    const esBarco = nave.classList.contains('barco');
    const derecha = carril.dataset.dir !== 'izq';
    const margen  = esBarco ? 40 : 300;

    const inicio = () => derecha ? -margen - nave.offsetWidth : carril.clientWidth + margen;
    const fin    = () => derecha ? carril.clientWidth + margen : -margen - nave.offsetWidth;

    gsap.set(nave, { scaleX: derecha ? 1 : -1 });

    gsap.fromTo(nave,
      { x: inicio },
      {
        x: fin,
        ease: 'none',
        scrollTrigger: {
          trigger: carril,
          start: 'top bottom',
          end: 'top 12%',
          scrub: 0.7,
          invalidateOnRefresh: true
        }
      }
    );

    gsap.to(nave, {
      y: esBarco ? -4 : -3,
      rotation: esBarco ? 1.2 : -1,
      duration: esBarco ? 1.7 : 2.4,
      yoyo: true,
      repeat: -1,
      ease: 'sine.inOut'
    });
  });
}


/* ===== VIDEO personacomprando =====
   - Se reproduce solo cuando lo ves y se pausa cuando sales de él.
   - Clic en el video = pausa / reproducir.
   - Botón de bocina = activar / quitar sonido.
   - Con el mouse encima: brillo dorado y pequeño movimiento 3D.
   CAMBIAR VIDEO: la ruta del archivo está en index.html (videos/personacomprando.mp4) */
(function videoPersona() {
  const caja   = document.getElementById('videoCaja');
  const video  = document.getElementById('videoPersona');
  const btnPlay = document.getElementById('videoPlay');
  const btnSon  = document.getElementById('videoSonido');
  if (!caja || !video) return;

  let pausaManual = false;   // true si la persona lo pausó ella misma

  function reproducir() {
    const p = video.play();
    if (p && p.catch) p.catch(() => {});
    caja.classList.remove('pausado');
    btnPlay.setAttribute('aria-label', 'Pausar video');
  }
  function pausar() {
    video.pause();
    caja.classList.add('pausado');
    btnPlay.setAttribute('aria-label', 'Reproducir video');
  }

  /* Reproducir solo cuando está a la vista */
  if ('IntersectionObserver' in window) {
    new IntersectionObserver(entradas => {
      entradas.forEach(e => {
        if (e.isIntersecting && !pausaManual && !reducir) reproducir();
        else if (!e.isIntersecting) { video.pause(); }
      });
    }, { threshold: 0.35 }).observe(caja);
  } else if (!reducir) {
    reproducir();
  }

  if (reducir) pausar();

  function alternar() {
    if (video.paused) { pausaManual = false; reproducir(); }
    else              { pausaManual = true;  pausar(); }
  }

  caja.addEventListener('click', e => {
    if (e.target.closest('.video-btn')) return;
    alternar();
  });
  btnPlay.addEventListener('click', alternar);

  btnSon.addEventListener('click', () => {
    video.muted = !video.muted;
    btnSon.classList.toggle('sonando', !video.muted);
    btnSon.setAttribute('aria-pressed', String(!video.muted));
    btnSon.setAttribute('aria-label', video.muted ? 'Activar sonido' : 'Quitar sonido');
  });

  /* Brillo y movimiento 3D con el mouse */
  if (conRaton && !reducir) {
    caja.addEventListener('mousemove', e => {
      const r  = caja.getBoundingClientRect();
      const px = (e.clientX - r.left) / r.width;
      const py = (e.clientY - r.top)  / r.height;
      caja.style.setProperty('--mx', (px * 100) + '%');
      caja.style.setProperty('--my', (py * 100) + '%');
      gsap.to(caja, {
        rotationY: (px - 0.5) * 6,
        rotationX: -(py - 0.5) * 6,
        transformPerspective: 900,
        duration: 0.5,
        ease: 'power2.out',
        overwrite: 'auto'
      });
    });
    caja.addEventListener('mouseleave', () => {
      gsap.to(caja, { rotationX: 0, rotationY: 0, duration: 0.9, ease: 'elastic.out(1, 0.5)', overwrite: 'auto' });
    });
  }
})();


/* ===== ANIMACIÓN DE ENTRADA DE LAS TARJETAS DE NORMAS + MOVIMIENTO 3D ===== */
document.querySelectorAll('.norma').forEach(tarjeta => {
  const trazos   = tarjeta.querySelectorAll('.norma-icono path');
  const num      = tarjeta.querySelector('.norma-num');
  const textos   = tarjeta.querySelectorAll('h3, p');
  const linea    = tarjeta.querySelector('.norma-linea');
  const enlace   = tarjeta.querySelector('.norma-enlace');
  const destino  = parseInt(num.dataset.num, 10) || 1;
  const contador = { v: 0 };

  if (!reducir) {
    gsap.set(trazos, { strokeDasharray: 1, strokeDashoffset: 1 });
    num.textContent = '00';

    gsap.timeline({
      scrollTrigger: { trigger: tarjeta, start: 'top 88%', once: true }
    })
      .from(tarjeta, {
        clipPath: 'inset(0 100% 0 0)',
        y: 50,
        opacity: 0,
        duration: 0.9,
        ease: 'power3.out',
        clearProps: 'clipPath'
      })
      .to(trazos, { strokeDashoffset: 0, duration: 0.9, stagger: 0.25, ease: 'power2.inOut' }, '-=0.5')
      .to(contador, {
        v: destino,
        duration: 0.8,
        ease: 'power1.out',
        onUpdate: () => { num.textContent = String(Math.round(contador.v)).padStart(2, '0'); }
      }, '<')
      .from(textos, { y: 18, opacity: 0, duration: 0.6, stagger: 0.12, ease: 'power2.out' }, '-=0.5')
      .from(linea, { scaleX: 0, duration: 0.7, ease: 'power2.inOut' }, '-=0.3')
      .from(enlace, { opacity: 0, x: -14, duration: 0.5, ease: 'power2.out' }, '-=0.3');
  }

  if (conRaton && !reducir) {
    tarjeta.addEventListener('mousemove', e => {
      const r  = tarjeta.getBoundingClientRect();
      const px = (e.clientX - r.left) / r.width  - 0.5;
      const py = (e.clientY - r.top)  / r.height - 0.5;
      gsap.to(tarjeta, {
        rotationY: px * 8,
        rotationX: -py * 8,
        transformPerspective: 800,
        duration: 0.4,
        ease: 'power2.out',
        overwrite: 'auto'
      });
    });
    tarjeta.addEventListener('mouseleave', () => {
      gsap.to(tarjeta, { rotationX: 0, rotationY: 0, duration: 0.9, ease: 'elastic.out(1, 0.4)', overwrite: 'auto' });
    });
  }
});

window.addEventListener('load', () => ScrollTrigger.refresh());


/* ==========================================================================
   ===== NÚMERO DE WHATSAPP =====
   Número que usa el botón verde-dorado dentro de cada norma.
   (52 = clave de México, luego el número a 10 dígitos, sin espacios)
   ========================================================================== */
const WHATSAPP_NUMERO = '525660892702';


/* ==========================================================================
   ===== TEXTO DE CADA NORMA AL ABRIRSE =====
   Está resumido a propósito: 3 cosas cortas para que se lea completo.

   Para cambiar una norma, edita estos campos (la llave es el código
   exacto que sale como título de la tarjeta):

     titulo  -> encabezado dorado del panel
     regula  -> UNA frase: qué regula la norma
     revisa  -> hasta 3 palabras/frases cortas: qué se revisa
     ejemplo -> UNA frase: un producto de ejemplo

   BORRAR: si quitas una línea de revisa, desaparece esa "pastilla".
   Si borras una norma completa de aquí, su tarjeta ya no se abre.
   ========================================================================== */
const detallesNOM = {
  "NOM-004-SCFI-2006": {
    titulo: "Textiles, prendas y ropa de casa",
    regula: "Qué información comercial debe llevar la ropa y los textiles.",
    revisa: ["Composición", "Instrucciones de cuidado", "Datos del responsable"],
    ejemplo: "Una camisa o un juego de sábanas."
  },

  "NOM-015-SCFI-2007": {
    titulo: "Juguetes",
    regula: "Qué información comercial debe llevar el empaque de un juguete.",
    revisa: ["Identificación del producto", "Datos del responsable", "Información en el empaque"],
    ejemplo: "Un juguete que se vende en caja o bolsa."
  },

  "NOM-141-SSA1/SCFI-2012": {
    titulo: "Cosméticos preenvasados",
    regula: "Cómo etiquetar productos cosméticos antes de venderlos.",
    revisa: ["Denominación", "Ingredientes", "Contenido y responsable"],
    ejemplo: "Una crema facial, un champú o una loción."
  },

  "NOM-020-SCFI-1997": {
    titulo: "Cuero, calzado y marroquinería",
    regula: "Cómo declarar el material de cueros, calzado y artículos similares.",
    revisa: ["Material del producto", "Composición", "Datos comerciales"],
    ejemplo: "Zapatos, bolsas, carteras o cinturones."
  },

  "NOM-142-SSA1/SCFI-2014": {
    titulo: "Bebidas alcohólicas",
    regula: "Información sanitaria y comercial de las bebidas alcohólicas.",
    revisa: ["Contenido alcohólico", "Contenido neto", "Leyendas sanitarias"],
    ejemplo: "Una botella de tequila, vino o cerveza."
  },

  "NOM-024-SCFI-2013": {
    titulo: "Electrónicos y electrodomésticos",
    regula: "Información en empaques, instructivos y garantías.",
    revisa: ["Empaque", "Instructivo", "Garantía"],
    ejemplo: "Una licuadora, una pantalla o un cargador."
  },

  "NOM-050-SCFI-2004": {
    titulo: "Reglas generales de información comercial",
    regula: "Reglas generales para productos que no tienen una norma específica.",
    revisa: ["Identificación del producto", "Datos del responsable", "Advertencias aplicables"],
    ejemplo: "Un producto de uso cotidiano."
  },

  "NOM-051-SCFI/SSA1-2010": {
    titulo: "Alimentos y bebidas preenvasados",
    regula: "Cómo etiquetar alimentos y bebidas no alcohólicas empacadas.",
    revisa: ["Ingredientes", "Información nutrimental", "Alérgenos y sellos"],
    ejemplo: "Un refresco, unas galletas o un jugo."
  },

  "NOM-189-SSA1/SCFI-2002": {
    titulo: "Productos de aseo doméstico",
    regula: "Etiquetado y envasado de productos de limpieza del hogar.",
    revisa: ["Instrucciones de uso", "Precauciones", "Datos del responsable"],
    ejemplo: "Un limpiador, un detergente o un cloro."
  }
};


/* ===== PANEL QUE SE DESPLIEGA EN CADA NORMA (con animación) =====
   Al abrir: el panel crece suavemente, las filas entran una por una,
   las "pastillas" aparecen con rebote y el escudo da un pulso.
   Solo puede haber una norma abierta a la vez (para no saturar). */
const cerrarFns = [];

document.querySelectorAll(".norma").forEach((tarjeta) => {
  const titulo = tarjeta.querySelector("h3");
  const enlace = tarjeta.querySelector(".norma-enlace");
  const icono  = tarjeta.querySelector(".norma-icono");

  if (!titulo || !enlace) return;

  const codigo  = titulo.textContent.trim();
  const detalle = detallesNOM[codigo];

  if (!detalle) return;

  const idPanel = "detalle-" + codigo.toLowerCase().replace(/[^a-z0-9]+/g, "-");

  /* Mensaje que llega prellenado a WhatsApp */
  const mensaje = encodeURIComponent("Hola, quiero información sobre la " + codigo);
  const linkWA  = "https://wa.me/" + WHATSAPP_NUMERO + "?text=" + mensaje;

  const chips = detalle.revisa.map(t => "<li>" + t + "</li>").join("");

  const panel = document.createElement("div");
  panel.className = "norma-detalle";
  panel.id = idPanel;
  panel.hidden = true;
  panel.innerHTML =
    '<h4 class="nd-titulo">' + detalle.titulo + "</h4>" +
    '<div class="nd-fila"><span class="nd-etq">Qué regula</span><p>' + detalle.regula + "</p></div>" +
    '<div class="nd-fila"><span class="nd-etq">Qué se revisa</span><ul class="nd-chips">' + chips + "</ul></div>" +
    '<div class="nd-fila"><span class="nd-etq">Ejemplo</span><p>' + detalle.ejemplo + "</p></div>" +
    '<a class="nd-cta" href="' + linkWA + '" target="_blank" rel="noopener">Consultar por WhatsApp <span aria-hidden="true">→</span></a>';

  tarjeta.appendChild(panel);

  enlace.href = "#" + idPanel;
  enlace.setAttribute("aria-controls", idPanel);
  enlace.setAttribute("aria-expanded", "false");

  let abierto = false;

  function poner(abrir) {
    if (abrir === abierto) return;
    abierto = abrir;

    enlace.setAttribute("aria-expanded", String(abrir));
    enlace.innerHTML = abrir
      ? 'Ocultar detalle <span aria-hidden="true">↑</span>'
      : 'Ver detalle <span aria-hidden="true">→</span>';
    tarjeta.classList.toggle("norma-expandida", abrir);

    const filas = panel.querySelectorAll(".nd-titulo, .nd-fila, .nd-cta");
    const pastillas = panel.querySelectorAll(".nd-chips li");

    /* Sin animaciones si la persona prefiere menos movimiento */
    if (reducir || !window.gsap) {
      panel.hidden = !abrir;
      return;
    }

    gsap.killTweensOf([panel, filas, pastillas]);

    if (abrir) {
      panel.hidden = false;
      gsap.set(filas, { opacity: 0, x: -20 });
      gsap.set(pastillas, { opacity: 0, scale: 0.6 });

      gsap.fromTo(panel,
        { height: 0, opacity: 0 },
        {
          height: "auto",
          opacity: 1,
          duration: 0.55,
          ease: "power3.out",
          onComplete: () => { gsap.set(panel, { clearProps: "height" }); ScrollTrigger.refresh(); }
        }
      );
      gsap.to(filas, { opacity: 1, x: 0, duration: 0.5, stagger: 0.12, delay: 0.15, ease: "power2.out" });
      gsap.to(pastillas, { opacity: 1, scale: 1, duration: 0.45, stagger: 0.08, delay: 0.5, ease: "back.out(2.2)" });

      /* pulso del escudo */
      if (icono) {
        gsap.fromTo(icono, { scale: 1, rotation: 0 }, { scale: 1.25, rotation: -8, duration: 0.25, yoyo: true, repeat: 1, ease: "power2.inOut" });
      }
    } else {
      gsap.to(panel, {
        height: 0,
        opacity: 0,
        duration: 0.35,
        ease: "power2.in",
        onComplete: () => {
          panel.hidden = true;
          gsap.set(panel, { clearProps: "height,opacity" });
          ScrollTrigger.refresh();
        }
      });
    }
  }

  cerrarFns.push(() => poner(false));

  enlace.addEventListener("click", (evento) => {
    evento.preventDefault();
    const abrir = !abierto;

    /* cerrar las demás normas abiertas */
    if (abrir) cerrarFns.forEach(fn => { if (fn !== cerrarEsta) fn(); });

    poner(abrir);
  });

  const cerrarEsta = cerrarFns[cerrarFns.length - 1];
});


/* ===== CURSOR DORADO CON FÍSICA (solo en computadora con mouse) =====
   Para quitarlo: borra todo desde aquí hasta el final del archivo. */
(function cursorFisico() {
  if (!conRaton || reducir) return;

  const lienzo = document.createElement('canvas');
  lienzo.id = 'cursor-fisico';
  document.body.appendChild(lienzo);
  const ctx = lienzo.getContext('2d');

  let W = 0, H = 0;
  function ajustar() {
    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    W = window.innerWidth;
    H = window.innerHeight;
    lienzo.width  = W * dpr;
    lienzo.height = H * dpr;
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
  }
  ajustar();
  window.addEventListener('resize', ajustar);

  const DORADO     = '#c9b66b';
  const DORADO_OSC = '#9b8a45';
  const SOMBRA     = 'rgba(15, 23, 51, 0.55)';

  const raton  = { x: -100, y: -100, visible: false, presionado: false };
  const anillo = { x: -100, y: -100, vx: 0, vy: 0, r: 16, rv: 0, rObjetivo: 16 };
  const COLA   = 10;
  const cola   = Array.from({ length: COLA }, () => ({ x: -100, y: -100, vx: 0, vy: 0 }));
  let particulas = [];
  let imantado = null;

  const OBJETIVOS = 'a, button, summary, .norma';

  function chispas(x, y) {
    for (let i = 0; i < 14; i++) {
      const ang = Math.random() * Math.PI * 2;
      const vel = 2 + Math.random() * 4.5;
      particulas.push({
        x, y,
        vx: Math.cos(ang) * vel,
        vy: Math.sin(ang) * vel - 2,
        tam: 2 + Math.random() * 2.5,
        vida: 1,
        color: Math.random() > 0.5 ? DORADO : DORADO_OSC
      });
    }
  }

  window.addEventListener('mousemove', e => {
    if (!raton.visible) {
      anillo.x = raton.x = e.clientX;
      anillo.y = raton.y = e.clientY;
      cola.forEach(p => { p.x = e.clientX; p.y = e.clientY; p.vx = p.vy = 0; });
      raton.visible = true;
      document.documentElement.classList.add('cursor-fisico');
    }
    raton.x = e.clientX;
    raton.y = e.clientY;

    const el = e.target.closest ? e.target.closest(OBJETIVOS) : null;
    imantado = el && el.matches('a, button, summary') ? el : null;
    anillo.rObjetivo = el ? 30 : 16;
  });

  window.addEventListener('mousedown', () => {
    raton.presionado = true;
    anillo.rObjetivo = 10;
    chispas(raton.x, raton.y);
  });
  window.addEventListener('mouseup', () => { raton.presionado = false; });
  document.addEventListener('mouseleave', () => { raton.visible = false; });
  document.addEventListener('mouseenter', () => { raton.visible = true; });

  function bucle() {
    ctx.clearRect(0, 0, W, H);

    if (raton.visible) {
      let tx = raton.x, ty = raton.y;
      if (imantado) {
        const b = imantado.getBoundingClientRect();
        tx += (b.left + b.width  / 2 - raton.x) * 0.25;
        ty += (b.top  + b.height / 2 - raton.y) * 0.25;
      }
      const K = 0.14;
      const C = 0.78;
      anillo.vx = (anillo.vx + (tx - anillo.x) * K) * C;
      anillo.vy = (anillo.vy + (ty - anillo.y) * K) * C;
      anillo.x += anillo.vx;
      anillo.y += anillo.vy;

      anillo.rv = (anillo.rv + (anillo.rObjetivo - anillo.r) * 0.2) * 0.68;
      anillo.r += anillo.rv;

      const vel     = Math.hypot(anillo.vx, anillo.vy);
      const estirar = Math.min(vel / 18, 0.65);
      const angulo  = Math.atan2(anillo.vy, anillo.vx);

      ctx.save();
      ctx.shadowColor = SOMBRA;
      ctx.shadowBlur = 4;
      ctx.beginPath();
      ctx.ellipse(anillo.x, anillo.y,
        Math.max(anillo.r * (1 + estirar), 1),
        Math.max(anillo.r * (1 - estirar * 0.45), 1),
        angulo, 0, Math.PI * 2);
      if (imantado) {
        ctx.fillStyle = 'rgba(201, 182, 107, 0.18)';
        ctx.fill();
      }
      ctx.lineWidth = 2;
      ctx.strokeStyle = DORADO;
      ctx.stroke();
      ctx.restore();

      for (let i = 0; i < COLA; i++) {
        const p    = cola[i];
        const prev = i === 0 ? raton : cola[i - 1];
        p.vx = (p.vx + (prev.x - p.x) * 0.35) * 0.55;
        p.vy = (p.vy + (prev.y - p.y) * 0.35) * 0.55;
        p.x += p.vx;
        p.y += p.vy;
      }
      for (let i = COLA - 1; i >= 0; i--) {
        const t = 1 - i / COLA;
        ctx.beginPath();
        ctx.arc(cola[i].x, cola[i].y, 0.8 + 3.4 * t, 0, Math.PI * 2);
        ctx.fillStyle = 'rgba(201, 182, 107, ' + (0.55 * t) + ')';
        ctx.fill();
      }

      ctx.beginPath();
      ctx.arc(raton.x, raton.y, raton.presionado ? 3 : 4.5, 0, Math.PI * 2);
      ctx.fillStyle = DORADO;
      ctx.fill();
      ctx.lineWidth = 1.2;
      ctx.strokeStyle = SOMBRA;
      ctx.stroke();
    }

    for (let i = particulas.length - 1; i >= 0; i--) {
      const p = particulas[i];
      p.vy += 0.22;
      p.vx *= 0.98;
      p.x += p.vx;
      p.y += p.vy;
      p.vida -= 0.026;
      if (p.vida <= 0) { particulas.splice(i, 1); continue; }
      ctx.globalAlpha = p.vida;
      ctx.beginPath();
      ctx.arc(p.x, p.y, p.tam * p.vida + 0.5, 0, Math.PI * 2);
      ctx.fillStyle = p.color;
      ctx.fill();
      ctx.globalAlpha = 1;
    }

    requestAnimationFrame(bucle);
  }
  requestAnimationFrame(bucle);
})();