/* ═══════════════════════════════════════════
   NEXORA ESPORTS — main.js
   ═══════════════════════════════════════════ */
(function () {
  "use strict";

  /* ── Mobile menu (slide-in sidebar) ── */
  const menuToggle = document.querySelector("[data-menu-toggle]");
  const menu = document.querySelector("[data-menu]");
  const navOverlay = document.querySelector("[data-nav-overlay]");
  const sidebarClose = document.querySelector("[data-sidebar-close]");
  if (menuToggle && menu) {
    const icon = menuToggle.querySelector("i");
    const setIcon = () => {
      if (!icon) return;
      const open = menu.classList.contains("open");
      icon.className = open ? "fas fa-xmark" : "fas fa-bars";
      menuToggle.setAttribute("aria-expanded", open ? "true" : "false");
      document.body.classList.toggle("menu-open", open);
      if (!open) document.body.style.overflow = "";
    };
    const openMenu = () => {
      menu.classList.add("open");
      setIcon();
    };
    const closeMenu = () => {
      menu.classList.remove("open");
      setIcon();
    };
    menuToggle.addEventListener("click", () => {
      menu.classList.contains("open") ? closeMenu() : openMenu();
    });
    if (sidebarClose) sidebarClose.addEventListener("click", closeMenu);
    if (navOverlay) navOverlay.addEventListener("click", closeMenu);
    menu.querySelectorAll("a").forEach(a =>
      a.addEventListener("click", closeMenu)
    );
    window.addEventListener("pagehide", closeMenu);
    window.addEventListener("pageshow", e => {
      closeMenu();
    });
    document.addEventListener("click", e => {
      if (menu.classList.contains("open") && !menu.contains(e.target) && !menuToggle.contains(e.target)) {
        closeMenu();
      }
    });
    document.addEventListener("keydown", e => {
      if (e.key === "Escape") closeMenu();
    });
    window.addEventListener("resize", () => {
      if (window.innerWidth > 1024 && menu.classList.contains("open")) {
        closeMenu();
      }
    });
    setIcon();
  }

  /* ── Admin left slide-in drawer (mobile / tablet) ── */
  const adminDrawer = document.querySelector("[data-admin-drawer]");
  const adminBackdrop = document.querySelector("[data-admin-backdrop]");
  const adminOpenBtn = document.querySelector("[data-admin-open]");
  const adminCloseBtn = document.querySelector("[data-admin-close]");

  if (adminDrawer) {
    const openDrawer = () => {
      document.body.classList.add("admin-drawer-open");
      adminDrawer.classList.add("open");
      if (adminBackdrop) adminBackdrop.hidden = false;
      if (adminOpenBtn) adminOpenBtn.setAttribute("aria-expanded", "true");
    };
    const closeDrawer = () => {
      document.body.classList.remove("admin-drawer-open");
      adminDrawer.classList.remove("open");
      if (adminBackdrop) adminBackdrop.hidden = true;
      if (adminOpenBtn) adminOpenBtn.setAttribute("aria-expanded", "false");
    };

    if (adminOpenBtn) adminOpenBtn.addEventListener("click", openDrawer);
    if (adminCloseBtn) adminCloseBtn.addEventListener("click", closeDrawer);
    if (adminBackdrop) adminBackdrop.addEventListener("click", closeDrawer);

    // any nav link closes the drawer
    adminDrawer.querySelectorAll("a").forEach(link =>
      link.addEventListener("click", () => {
        if (window.innerWidth <= 1024) closeDrawer();
      })
    );

    document.addEventListener("keydown", e => {
      if (e.key === "Escape") closeDrawer();
    });

    // going back to desktop width must never leave the page locked
    let resizeTimer = null;
    window.addEventListener("resize", () => {
      clearTimeout(resizeTimer);
      resizeTimer = setTimeout(() => {
        if (window.innerWidth > 1024) closeDrawer();
      }, 150);
    });
  }

  /* ── Navbar shadow on scroll ── */
  const nav = document.querySelector(".nav");
  if (nav) {
    const onScroll = () => nav.classList.toggle("scrolled", window.scrollY > 8);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
  }

  /* ── Hero cover slider ── */
  const slider = document.querySelector("[data-slider]");
  if (slider) {
    const slides = [...slider.querySelectorAll(".hero-slide")];
    const dotsBox = document.querySelector("[data-hero-dots]");
    let index = 0;
    let timer = null;

    const go = i => {
      slides[index].classList.remove("active");
      index = (i + slides.length) % slides.length;
      slides[index].classList.add("active");
      if (dotsBox) {
        [...dotsBox.children].forEach((d, n) => d.classList.toggle("active", n === index));
      }
    };

    if (slides.length > 1) {
      if (dotsBox) {
        slides.forEach((_, i) => {
          const dot = document.createElement("button");
          dot.type = "button";
          dot.setAttribute("aria-label", "Slide " + (i + 1));
          if (i === 0) dot.classList.add("active");
          dot.addEventListener("click", () => {
            go(i);
            restart();
          });
          dotsBox.appendChild(dot);
        });
      }
      const start = () => (timer = setInterval(() => go(index + 1), 5500));
      const restart = () => {
        clearInterval(timer);
        start();
      };
      start();
    }
  }

  /* ── Countdown ── */
  const countdown = document.querySelector("[data-countdown]");
  if (countdown) {
    const raw = (countdown.dataset.countdown || "").trim();
    const target = new Date(raw).getTime();
    const message = document.querySelector("[data-timer-message]");

    const finish = text => {
      ["[data-days]", "[data-hours]", "[data-minutes]", "[data-seconds]"].forEach(sel => {
        const el = countdown.querySelector(sel);
        if (el) el.textContent = "00";
      });
      if (message) {
        message.textContent = text;
        message.style.display = "block";
      }
    };

    if (!raw || !Number.isFinite(target)) {
      finish("Event date coming soon");
    } else {
      const set = (sel, val) => {
        const el = countdown.querySelector(sel);
        if (el) el.textContent = String(val).padStart(2, "0");
      };
      const tick = () => {
        const diff = target - Date.now();
        if (diff <= 0) {
          finish("Time completed");
          clearInterval(ticker);
          return;
        }
        set("[data-days]", Math.floor(diff / 86400000));
        set("[data-hours]", Math.floor((diff % 86400000) / 3600000));
        set("[data-minutes]", Math.floor((diff % 3600000) / 60000));
        set("[data-seconds]", Math.floor((diff % 60000) / 1000));
      };
      tick();
      var ticker = setInterval(tick, 1000);
    }
  }

  /* ── Memories: continuous right-to-left loop ── */
  document.querySelectorAll("[data-step-marquee]").forEach(group => {
    const track = group.querySelector("[data-track]");
    if (!track) return;

    const originals = [...track.children];
    if (!originals.length) return;

    for (let i = 0; i < 3; i++) {
      originals.forEach(node => track.appendChild(node.cloneNode(true)));
    }
    track.classList.add("is-auto-marquee");
    track.style.setProperty("--memory-duration", Math.max(14, originals.length * 2.4) + "s");
  });

  /* ── Sponsor marquee speed matched to content ── */
  document.querySelectorAll("[data-marquee]").forEach(marquee => {
    const track = marquee.querySelector(".sponsor-marquee-track");
    if (!track) return;
    const originals = [...track.children];
    if (!originals.length) return;

    /* Clone enough sets to guarantee seamless infinite loop */
    const marqueeWidth = marquee.offsetWidth;
    let totalWidth = 0;
    originals.forEach(node => {
      const s = window.getComputedStyle(node);
      totalWidth += node.offsetWidth + parseFloat(s.marginLeft || 0) + parseFloat(s.marginRight || 0) + parseFloat(s.marginLeft ? 0 : 0);
    });
    const gap = parseFloat(window.getComputedStyle(track).gap) || 16;
    totalWidth += gap * (originals.length - 1);
    const setsNeeded = Math.max(4, Math.ceil((marqueeWidth * 3) / totalWidth));
    for (let i = 0; i < setsNeeded; i++) {
      originals.forEach(node => track.appendChild(node.cloneNode(true)));
    }
    track.style.setProperty("--marquee-duration", Math.max(18, originals.length * 3) + "s");
    if (marquee.hasAttribute("data-marquee-reverse")) {
      track.classList.add("is-reversed");
    }
  });

  /* ── Team section marquee rows ── */
  document.querySelectorAll("[data-team-marquee]").forEach(marquee => {
    const track = marquee.querySelector(".team-marquee-track");
    if (!track) return;
    const originals = [...track.children];
    if (!originals.length) return;

    const marqueeWidth = marquee.offsetWidth;
    let totalWidth = 0;
    originals.forEach(node => {
      const s = window.getComputedStyle(node);
      totalWidth += node.offsetWidth + parseFloat(s.marginLeft || 0) + parseFloat(s.marginRight || 0);
    });
    const gap = parseFloat(window.getComputedStyle(track).gap) || 20;
    totalWidth += gap * (originals.length - 1);
    const setsNeeded = Math.max(4, Math.ceil((marqueeWidth * 3) / totalWidth));
    for (let i = 0; i < setsNeeded; i++) {
      originals.forEach(node => track.appendChild(node.cloneNode(true)));
    }
    const speed = parseInt(marquee.dataset.speed) || 30;
    track.style.setProperty("--team-marquee-duration", Math.max(12, originals.length * speed / originals.length) + "s");
  });

  const motionSections = document.querySelectorAll("[data-step-marquee], [data-marquee], [data-team-marquee]");
  if (motionSections.length) {
    if ("IntersectionObserver" in window) {
      const motionObserver = new IntersectionObserver(
        entries => {
          entries.forEach(entry => entry.target.classList.toggle("marquee-live", entry.isIntersecting));
        },
        { rootMargin: "160px 0px" }
      );
      motionSections.forEach(section => motionObserver.observe(section));
    } else {
      motionSections.forEach(section => section.classList.add("marquee-live"));
    }
  }

  /* ── Sponsors entrance animation ── */
  const sponsorsSection = document.querySelector("[data-sponsors]");
  if (sponsorsSection) {
    if ("IntersectionObserver" in window) {
      const sponsorsObserver = new IntersectionObserver(
        entries => {
          entries.forEach(entry => {
            if (entry.isIntersecting) {
              entry.target.classList.add("sponsors-entrance");
              sponsorsObserver.unobserve(entry.target);
            }
          });
        },
        { threshold: 0.15 }
      );
      sponsorsObserver.observe(sponsorsSection);
    } else {
      sponsorsSection.classList.add("sponsors-entrance");
    }
  }

  /* ── Team section entrance animation ── */
  document.querySelectorAll("[data-team-section]").forEach(sec => {
    if ("IntersectionObserver" in window) {
      const teamObs = new IntersectionObserver(
        entries => {
          entries.forEach(entry => {
            if (entry.isIntersecting) {
              entry.target.classList.add("team-entrance");
              teamObs.unobserve(entry.target);
            }
          });
        },
        { threshold: 0.12 }
      );
      teamObs.observe(sec);
    } else {
      sec.classList.add("team-entrance");
    }
  });

  /* ── Reveal on scroll ── */
  const revealItems = document.querySelectorAll(".reveal, [data-stagger]");
  if (revealItems.length) {
    if ("IntersectionObserver" in window) {
      const io = new IntersectionObserver(
        entries => {
          entries.forEach(entry => {
            if (entry.isIntersecting) {
              entry.target.classList.add("show");
              io.unobserve(entry.target);
            }
          });
        },
        { threshold: 0.1, rootMargin: "0px 0px -40px 0px" }
      );
      revealItems.forEach(el => io.observe(el));
    } else {
      revealItems.forEach(el => el.classList.add("show"));
    }
  }

  /* ── Animated counters ── */
  const counters = document.querySelectorAll("[data-count-to]");
  if (counters.length && "IntersectionObserver" in window) {
    const co = new IntersectionObserver(
      entries => {
        entries.forEach(entry => {
          if (!entry.isIntersecting) return;
          const el = entry.target;
          co.unobserve(el);
          const end = parseInt(el.dataset.countTo, 10) || 0;
          const suffix = el.dataset.suffix || "";
          const dur = 1100;
          const t0 = performance.now();
          const run = now => {
            const p = Math.min(1, (now - t0) / dur);
            el.textContent = Math.round(end * (1 - Math.pow(1 - p, 3))) + suffix;
            if (p < 1) requestAnimationFrame(run);
          };
          requestAnimationFrame(run);
        });
      },
      { threshold: 0.4 }
    );
    counters.forEach(el => co.observe(el));
  }

  /* ── Flash auto-dismiss ── */
  document.querySelectorAll(".flash").forEach((el, i) => {
    setTimeout(() => {
      el.style.transition = "opacity .4s, transform .4s";
      el.style.opacity = "0";
      el.style.transform = "translateX(24px)";
      setTimeout(() => el.remove(), 420);
    }, 5000 + i * 400);
  });

  /* ── Registration form ── */
  const regForm = document.querySelector("[data-registration-form]");
  if (regForm) {
    const type = regForm.querySelector("[data-entry-type]");
    const teamFields = regForm.querySelector("[data-team-fields]");
    const gameSelect = regForm.querySelector("[data-game-select]");
    const priceOut = regForm.querySelector("[data-price-out]");
    const teamSizeSelect = regForm.querySelector("[data-team-size]");
    const gameLimits = regForm.querySelector("[data-game-limits]");
    const sizeWrap = regForm.querySelector("[data-team-size-wrap]");

    const selectedGameOption = () => {
      if (!gameSelect) return null;
      var idx = gameSelect.selectedIndex;
      if (idx < 0 || idx >= gameSelect.options.length) return null;
      return gameSelect.options[idx];
    };

    const parsePriceMap = opt => {
      if (!opt || !opt.dataset.prices) return null;
      try { return JSON.parse(opt.dataset.prices); } catch (e) { return null; }
    };

    const renderPrice = entry => {
      if (!entry || !entry.current) return "\u2014";
      var html = '<strong class="price-now">' + entry.current + '</strong>';
      if (entry.strike && entry.original) {
        html += ' <del class="price-was">' + entry.original + '</del>';
      }
      return html;
    };

    const syncEntryType = () => {
      if (!type) return;
      var size = parseInt(teamSizeSelect ? teamSizeSelect.value : "1", 10);
      type.value = size > 1 ? "group" : "individual";
    };

    const syncEntryOptions = () => {
      if (!teamSizeSelect) return;
      var opt = selectedGameOption();
      var priceMap = parsePriceMap(opt);
      var minM = parseInt(opt && opt.dataset ? opt.dataset.min : "1", 10) || 1;
      var maxM = parseInt(opt && opt.dataset ? opt.dataset.max : "1", 10) || 1;
      var previous = teamSizeSelect.value;
      var hasPrice = function(s) { return !!(priceMap && priceMap[String(s)]); };
      var entries = [];

      /* Build allowed player-count entries from game config */
      if (minM <= 1 && maxM <= 1 && hasPrice(1)) {
        /* Solo-only game: single option, no dropdown needed */
        entries.push({ value: "1", label: "1 Player" });
      } else {
        for (var i = Math.max(1, minM); i <= maxM; i++) {
          if (hasPrice(i)) {
            entries.push({ value: String(i), label: i === 1 ? "1 Player" : i + " Players" });
          }
        }
      }

      /* Rebuild <select> options */
      teamSizeSelect.innerHTML = "";

      if (entries.length > 1) {
        var placeholder = document.createElement("option");
        placeholder.value = "";
        placeholder.disabled = true;
        placeholder.textContent = "Select number of players";
        placeholder.selected = true;
        teamSizeSelect.appendChild(placeholder);
      }

      entries.forEach(function(entry) {
        var item = document.createElement("option");
        item.value = entry.value;
        item.textContent = entry.label;
        teamSizeSelect.appendChild(item);
      });

      /* Restore previous selection or default to first */
      if (entries.length === 1) {
        teamSizeSelect.value = entries[0].value;
      } else if (previous && entries.some(function(e) { return e.value === previous; })) {
        teamSizeSelect.value = previous;
      } else if (entries.length) {
        teamSizeSelect.value = entries[0].value;
      }

      /* Solo-only game: hide the entire Players control */
      var soloOnly = maxM <= 1 || (entries.length === 1 && entries[0].value === "1" && minM <= 1);
      if (sizeWrap) sizeWrap.style.display = soloOnly ? "none" : "";
      if (soloOnly && teamSizeSelect.value !== "1") teamSizeSelect.value = "1";

      /* Update hint text */
      if (gameLimits) {
        if (!opt || !opt.value) {
          gameLimits.textContent = "";
        } else if (soloOnly) {
          gameLimits.textContent = "";
        } else {
          var minPart = minM > 1 ? "Minimum " + minM + " players required. " : "";
          gameLimits.textContent = minPart + "Maximum " + maxM + " players allowed.";
        }
      }
      syncEntryType();
    };

    const syncTeamFields = () => {
      if (!teamFields) return;
      syncEntryType();
      var isGroup = parseInt(teamSizeSelect ? teamSizeSelect.value : "1", 10) > 1;
      teamFields.style.display = isGroup ? "block" : "none";
      teamFields.querySelectorAll("[data-team-required]").forEach(function(input) {
        input.required = isGroup;
      });
      if (!isGroup) {
        teamFields.querySelectorAll("input").forEach(function(input) { input.value = ""; });
      }
    };

    if (type && teamFields) {
      type.addEventListener("change", syncTeamFields);
    }

    var memberList = regForm.querySelector("[data-member-list]");
    var makeMemberRow = function(number) {
      var row = document.createElement("div");
      row.className = "member-box dynamic-member-row";
      row.innerHTML = '<div class="member-row-head"><strong>Team Member ' + number + '</strong></div><input name="member_name[]" placeholder="Member name" required><input type="email" name="member_email[]" placeholder="Member email (optional)"><input name="member_phone[]" placeholder="Contact number" required>';
      return row;
    };
    var syncMemberRows = () => {
      if (!memberList) return;
      var totalSize = parseInt(teamSizeSelect ? teamSizeSelect.value : "1", 10);
      var requiredRows = Math.max(0, totalSize - 1);
      memberList.innerHTML = "";
      for (var index = 0; index < requiredRows; index++) {
        memberList.appendChild(makeMemberRow(index + 1));
      }
    };

    var updatePrice = () => {
      if (!priceOut) return;
      var opt = selectedGameOption();
      var data = parsePriceMap(opt);
      if (!data) { priceOut.innerHTML = "\u2014"; return; }
      var size = teamSizeSelect ? teamSizeSelect.value : "1";
      if (!size) size = "1";
      var entry = data[size] || data["1"] || null;
      priceOut.innerHTML = renderPrice(entry);
    };

    var syncGameState = () => {
      syncEntryOptions();
      syncTeamFields();
      syncMemberRows();
      updatePrice();
    };

    gameSelect.addEventListener("change", syncGameState);

    teamSizeSelect.addEventListener("change", () => {
      syncEntryType();
      syncTeamFields();
      syncMemberRows();
      updatePrice();
    });

    syncGameState();

    /* ── Submit handler ── */
    regForm.addEventListener("submit", event => {
      if (regForm.dataset.submitting === "true") {
        event.preventDefault();
        return;
      }

      var gameId = gameSelect ? gameSelect.value : "";
      var teamName = regForm.querySelector('[name="team_name"]');
      teamName = teamName ? teamName.value : "";
      var email = regForm.querySelector('[name="email"]');
      email = email ? email.value : "";
      var cnic = regForm.querySelector('[name="cnic"]');
      cnic = cnic ? cnic.value : "";
      var entryType = type ? type.value : "individual";
      var membersText = "";
      if (entryType === "group") {
        var rows = regForm.querySelectorAll(".dynamic-member-row");
        rows.forEach((row, i) => {
          var n = row.querySelector('[name="member_name[]"]');
          var e = row.querySelector('[name="member_email[]"]');
          var p = row.querySelector('[name="member_phone[]"]');
          n = n ? n.value : "";
          e = e ? e.value : "";
          p = p ? p.value : "";
          if (n || e || p) membersText += "Member " + (i + 1) + ": " + n + " | " + e + " | " + p + "\n";
        });
      }

      if (gameId && teamName && email && cnic) {
        event.preventDefault();
        var csrfToken = regForm.querySelector('[name="csrf_token"]');
        csrfToken = csrfToken ? csrfToken.value : "";
        // Don't let a slow/queued server hold the user on this pre-check —
        // fall through to the real submit after 4s and let the server validate.
        var _ac = typeof AbortController !== "undefined" ? new AbortController() : null;
        var _acTimer = _ac ? setTimeout(() => _ac.abort(), 4000) : null;
        fetch("/api/validate-registration", {
          method: "POST",
          headers: { "Content-Type": "application/json", "X-CSRF-Token": csrfToken },
          body: JSON.stringify({ game_id: gameId, team_name: teamName, email, cnic, entry_type: entryType, members_text: membersText }),
          signal: _ac ? _ac.signal : undefined,
        })
          .then(r => { if (_acTimer) clearTimeout(_acTimer); return r.json(); })
          .then(data => {
            if (!data.ok && data.errors && data.errors.length) {
              regForm.dataset.submitting = "false";
              data.errors.forEach(msg => {
                _showInlineFlash(regForm, msg, "danger");
              });
              var btn = regForm.querySelector(".submit-btn");
              if (btn) { btn.classList.remove("loading"); btn.disabled = false; var lbl = btn.querySelector("[data-btn-label]"); if (lbl) lbl.textContent = "Submit Registration"; }
              return;
            }
            _realSubmit(regForm);
          })
          .catch(() => { _realSubmit(regForm); });
        return;
      }
      _realSubmit(regForm);
    });

    function _realSubmit(form) {
      form.dataset.submitting = "true";
      var submissionKey = form.querySelector("[data-submission-key]");
      if (submissionKey && !submissionKey.value) {
        submissionKey.value = Date.now().toString(36) + "-" + Math.random().toString(36).slice(2);
      }
      var overlay = form.querySelector("[data-submit-overlay]");
      if (overlay) {
        overlay.classList.add("show");
        overlay.setAttribute("aria-hidden", "false");
      }
      var button = form.querySelector(".submit-btn");
      if (button) {
        button.classList.add("loading");
        button.disabled = true;
        var label = button.querySelector("[data-btn-label]");
        if (label) label.textContent = "Submitting\u2026";
      }
      form.submit();
    }

    function _showInlineFlash(form, msg, category) {
      var wrap = form.querySelector(".ajax-flash-wrap");
      if (!wrap) {
        wrap = document.createElement("div");
        wrap.className = "ajax-flash-wrap";
        form.insertBefore(wrap, form.firstChild);
      }
      var el = document.createElement("div");
      el.className = "flash " + (category || "danger");
      el.textContent = msg;
      el.style.cursor = "pointer";
      el.addEventListener("click", () => el.remove());
      wrap.appendChild(el);
      setTimeout(() => el.remove(), 8000);
    }
  }

  /* ── Gallery lightbox ── */
  const lightboxItems = [...document.querySelectorAll("[data-lightbox]")];
  if (lightboxItems.length) {
    const box = document.createElement("div");
    box.className = "lightbox";
    box.innerHTML =
      '<button class="lightbox-close" type="button" aria-label="Close"><i class="fas fa-xmark"></i></button>' +
      '<button class="lightbox-prev" type="button" aria-label="Previous"><i class="fas fa-chevron-left"></i></button>' +
      '<button class="lightbox-next" type="button" aria-label="Next"><i class="fas fa-chevron-right"></i></button>' +
      '<div style="display:grid;justify-items:center;">' +
      '<img alt=""><div class="lightbox-caption"></div></div>';
    document.body.appendChild(box);

    const img = box.querySelector("img");
    const caption = box.querySelector(".lightbox-caption");
    let current = 0;

    // unique sources only (memories track is duplicated for the loop)
    const sources = [];
    const seen = new Set();
    lightboxItems.forEach(el => {
      const src = el.dataset.lightbox;
      if (src && !seen.has(src)) {
        seen.add(src);
        sources.push({ src: src, title: el.dataset.title || "", caption: el.dataset.caption || "" });
      }
    });

    const show = i => {
      current = (i + sources.length) % sources.length;
      const item = sources[current];
      img.src = item.src;
      img.alt = item.title;
      caption.innerHTML = item.title
        ? "<strong>" + item.title + "</strong>" + (item.caption ? item.caption : "")
        : item.caption || "";
      caption.style.display = item.title || item.caption ? "block" : "none";
    };

    const open = i => {
      show(i);
      box.classList.add("open");
      document.body.style.overflow = "hidden";
    };

    const close = () => {
      box.classList.remove("open");
      document.body.style.overflow = "";
    };

    document.addEventListener("click", e => {
      const trigger = e.target.closest("[data-lightbox]");
      if (!trigger) return;
      e.preventDefault();
      const src = trigger.dataset.lightbox;
      const idx = sources.findIndex(item => item.src === src);
      open(idx < 0 ? 0 : idx);
    });

    box.querySelector(".lightbox-close").addEventListener("click", close);
    box.querySelector(".lightbox-prev").addEventListener("click", () => show(current - 1));
    box.querySelector(".lightbox-next").addEventListener("click", () => show(current + 1));
    box.addEventListener("click", e => {
      if (e.target === box) close();
    });
    document.addEventListener("keydown", e => {
      if (!box.classList.contains("open")) return;
      if (e.key === "Escape") close();
      if (e.key === "ArrowLeft") show(current - 1);
      if (e.key === "ArrowRight") show(current + 1);
    });
  }

  /* ── Institution type label follows the dropdown ── */
  const instType = document.querySelector("[data-institution-type]");
  const instLabel = document.querySelector("[data-institution-label]");
  const instInput = document.querySelector("[data-institution-name]");
  if (instType && instLabel) {
    const sync = () => {
      const value = instType.value;
      instLabel.textContent = value + " Name";
      if (instInput) instInput.placeholder = "Enter your " + value.toLowerCase() + " name";
    };
    instType.addEventListener("change", sync);
    sync();
  }

  /* ── Compact admin edit cards ── */
  document.querySelectorAll("[data-toggle-edit]").forEach(button => {
    button.addEventListener("click", () => {
      const card = button.closest(".mini-admin-card");
      const form = card ? card.querySelector(".admin-inline-edit") : null;
      if (!form) return;
      const willOpen = form.hidden;
      form.hidden = !willOpen;
      button.classList.toggle("active", willOpen);
      button.innerHTML = willOpen
        ? '<i class="fas fa-xmark"></i> Close'
        : '<i class="fas fa-pen"></i> Edit';
    });
  });

  /* ── Admin game forms: auto-pricing + field visibility ── */
  document.querySelectorAll("[data-game-admin-form]").forEach(form => {
    const maxInput = form.querySelector("[data-max-members]");
    const soloInput = form.querySelector("[data-price='1']");
    const oldSoloInput = form.querySelector("[data-old-price='1']");

    const parseNum = s => {
      const n = String(s).replace(/[^0-9.]/g, "");
      return n ? parseFloat(n) : 0;
    };

    const syncPriceRows = () => {
      const max = parseInt(maxInput?.value || "1", 10);
      for (let i = 2; i <= 4; i++) {
        const row = form.querySelector("[data-price-row='" + i + "']");
        const oldRow = form.querySelector("[data-old-row='" + i + "']");
        if (row) row.style.display = i <= max ? "" : "none";
        if (oldRow) oldRow.style.display = i <= max ? "" : "none";
      }
    };

    const autoCalcPrices = () => {
      const rawSolo = soloInput?.value || "";
      const solo = parseNum(rawSolo);
      if (solo <= 0) return;
      const prefix = rawSolo.replace(/[0-9.,\s]/g, "").trim();
      for (let i = 2; i <= 4; i++) {
        const input = form.querySelector("[data-price='" + i + "']");
        if (input) input.value = (prefix ? prefix + " " : "") + (solo * i).toLocaleString("en-PK");
      }
    };

    const autoCalcOldPrices = () => {
      const rawOldSolo = oldSoloInput?.value || "";
      const oldSolo = parseNum(rawOldSolo);
      if (oldSolo <= 0) return;
      const prefix = rawOldSolo.replace(/[0-9.,\s]/g, "").trim();
      for (let i = 2; i <= 4; i++) {
        const input = form.querySelector("[data-old-price='" + i + "']");
        if (input) input.value = (prefix ? prefix + " " : "") + (oldSolo * i).toLocaleString("en-PK");
      }
    };

    if (maxInput) maxInput.addEventListener("input", syncPriceRows);
    if (soloInput) soloInput.addEventListener("input", autoCalcPrices);
    if (oldSoloInput) oldSoloInput.addEventListener("input", autoCalcOldPrices);
    syncPriceRows();
  });

  /* ── Delete confirmations ── */
  document.querySelectorAll("[data-confirm]").forEach(form => {
    form.addEventListener("submit", e => {
      if (!window.confirm(form.dataset.confirm || "Are you sure?")) e.preventDefault();
    });
  });

  /* ── Prize Pool: synchronized pair showcase ── */
  var prizeCarousel = document.querySelector("[data-prize-carousel]");
  if (prizeCarousel) {
    var cards = Array.from(prizeCarousel.querySelectorAll("template[data-prize-card]"));
    var leftSlot = prizeCarousel.querySelector('[data-prize-slot="left"]');
    var rightSlot = prizeCarousel.querySelector('[data-prize-slot="right"]');
    var dotsWrap = prizeCarousel.querySelector("[data-prize-dots]");
    var awardCenter = prizeCarousel.querySelector("[data-prize-center]");
    var showcase = prizeCarousel.querySelector(".prize-showcase");
    var modalOverlay = prizeCarousel.querySelector("[data-prize-modal]");
    var modalContent = prizeCarousel.querySelector("[data-prize-modal-content]");
    var modalCloseBtn = prizeCarousel.querySelector("[data-prize-modal-close]");
    var currentPair = 0;
    var pairCount = 0;
    var pairs = [];
    var hasAnimated = false;
    var rotationTimer = null;
    var isPaused = false;
    var holdDuration = 5000;
    var fadeDuration = 600;

    var entryDirections = [
      ["from-left", "from-right"],
      ["from-bottom-left", "from-bottom-right"]
    ];

    /* ── Pair generation ── always produces exactly 2 indices per pair ── */
    function buildPairs() {
      var n = cards.length;
      if (n === 0) { pairs = []; pairCount = 0; return; }
      if (n === 1) { pairs = [[0, -1]]; pairCount = 1; return; }
      if (n === 2) { pairs = [[0, 1]]; pairCount = 1; return; }
      if (n === 3) { pairs = [[0, 1], [2, 0], [1, 2]]; pairCount = 3; return; }
      if (n === 4) { pairs = [[0, 1], [2, 3]]; pairCount = 2; return; }
      /* 5+ items: sequential pairs with wrap-around */
      var result = [];
      for (var i = 0; i < n; i += 2) {
        if (i + 1 < n) {
          result.push([i, i + 1]);
        } else {
          result.push([i, 0]);
        }
      }
      pairs = result;
      pairCount = pairs.length;
    }

    function mountCard(slot, cardIndex, direction, immediate) {
      if (cardIndex < 0 || cardIndex >= cards.length) {
        slot.replaceChildren([]);
        slot.removeAttribute("data-entrance");
        slot.classList.remove("prize-entrance-active", "prize-final");
        return;
      }
      slot.replaceChildren(cards[cardIndex].content.cloneNode(true));
      slot.setAttribute("data-entrance", direction);
      slot.classList.add("prize-entrance-active");
      var card = slot.firstElementChild;
      if (card) {
        card.style.opacity = immediate ? "1" : "0";
        card.addEventListener("click", function () {
          handleCardClick(cardIndex);
        });
      }
    }

    function populateAwardText(idx, side) {
      if (idx < 0 || idx >= cards.length) return;
      var tmpl = cards[idx];
      if (!tmpl) return;
      var block = awardCenter.querySelector('[data-prize-text="' + side + '"]');
      if (!block) return;
      block.querySelector(".prize-award-label").textContent = tmpl.dataset.label || "";
      block.querySelector(".prize-award-title").textContent = tmpl.dataset.title || "";
      block.querySelector(".prize-award-amount").textContent = tmpl.dataset.amount || "";
      block.querySelector(".prize-award-note").textContent = tmpl.dataset.note || "";
    }

    function clearAwardText() {
      awardCenter.querySelectorAll(".prize-award-block").forEach(function (b) {
        b.classList.remove("is-visible");
        b.querySelector(".prize-award-label").textContent = "";
        b.querySelector(".prize-award-title").textContent = "";
        b.querySelector(".prize-award-amount").textContent = "";
        b.querySelector(".prize-award-note").textContent = "";
      });
    }

    /* ── Transition helpers ── */
    function fadeSlotsOut(cb) {
      var leftCard = leftSlot.firstElementChild;
      var rightCard = rightSlot.firstElementChild;
      if (leftCard) leftCard.style.transition = "opacity " + fadeDuration + "ms ease";
      if (rightCard) rightCard.style.transition = "opacity " + fadeDuration + "ms ease";
      if (leftCard) leftCard.style.opacity = "0";
      if (rightCard) rightCard.style.opacity = "0";
      setTimeout(cb, fadeDuration);
    }

    function fadeInCards() {
      var leftCard = leftSlot.firstElementChild;
      var rightCard = rightSlot.firstElementChild;
      if (leftCard) leftCard.style.transition = "opacity " + fadeDuration + "ms ease";
      if (rightCard) rightCard.style.transition = "opacity " + fadeDuration + "ms ease";
      requestAnimationFrame(function () {
        requestAnimationFrame(function () {
          if (leftCard) leftCard.style.opacity = "1";
          if (rightCard) rightCard.style.opacity = "1";
        });
      });
    }

    /* ── Core rotation ── */
    function showPair(pairIndex, callback, immediate) {
      currentPair = (pairIndex + pairCount) % pairCount;
      var pair = pairs[currentPair];
      var leftIdx = pair[0];
      var rightIdx = pair[1];
      var dirs = entryDirections[currentPair % entryDirections.length];

      /* Update dots */
      dotsWrap.querySelectorAll("button").forEach(function (dot, i) {
        dot.classList.toggle("active", i === currentPair);
      });

      /* Hide right slot if only 1 item */
      rightSlot.style.display = (leftIdx >= 0 && rightIdx < 0) ? "none" : "";

      /* Mount new cards — immediate on first display, otherwise invisible then fade */
      mountCard(leftSlot, leftIdx, dirs[0], !!immediate);
      mountCard(rightSlot, rightIdx, dirs[1], !!immediate);

      /* Populate award text */
      clearAwardText();
      populateAwardText(leftIdx, "left");
      if (rightIdx >= 0) populateAwardText(rightIdx, "right");

      if (immediate) {
        /* First render: cards are already visible, just show award text */
        awardCenter.querySelectorAll(".prize-award-block").forEach(function (b) {
          b.classList.add("is-visible");
        });
      } else {
        /* Subsequent transitions: fade cards in */
        fadeInCards();
        awardCenter.querySelectorAll(".prize-award-block").forEach(function (b) {
          b.classList.add("is-visible");
        });
      }

      /* Hold then transition to next pair — skip fade-out when only 1 pair (no rotation) */
      if (pairCount <= 1) return;
      setTimeout(function () {
        if (isPaused) return;
        awardCenter.querySelectorAll(".prize-award-block").forEach(function (b) {
          b.classList.remove("is-visible");
        });
        fadeSlotsOut(function () {
          if (callback) callback();
        });
      }, holdDuration);
    }

    function scheduleNext() {
      if (pairCount <= 1) return;
      rotationTimer = setTimeout(function () {
        showPair(currentPair + 1, scheduleNext, false);
      }, 200);
    }

    /* ── Modal ── */
    function handleCardClick(cardIndex) {
      var tmpl = cards[cardIndex];
      if (!tmpl) return;
      isPaused = true;
      clearTimeout(rotationTimer);

      var imgSrc = "";
      var img = tmpl.content.querySelector("img");
      if (img) imgSrc = img.getAttribute("src");

      var leftIdx = pairs[currentPair][0];
      var labelColor = cardIndex === leftIdx ? "#ff6a79" : "#ffc62c";
      var borderColor = cardIndex === leftIdx ? "rgba(255,23,68,.35)" : "rgba(255,193,7,.35)";
      var glowColor = cardIndex === leftIdx ? "rgba(255,23,68,.12)" : "rgba(255,193,7,.12)";

      modalContent.innerHTML =
        (imgSrc ? '<img class="prize-modal-img" src="' + imgSrc + '" alt="' + (tmpl.dataset.title || "") + '">' : "") +
        '<div class="prize-modal-divider"></div>' +
        '<div class="prize-modal-details">' +
        '<span class="prize-modal-label" style="color:' + labelColor + '">' + (tmpl.dataset.label || "Reward") + '</span>' +
        '<h4 class="prize-modal-title">' + (tmpl.dataset.title || "") + '</h4>' +
        (tmpl.dataset.amount ? '<div class="prize-modal-amount">' + tmpl.dataset.amount + '</div>' : "") +
        (tmpl.dataset.note ? '<div class="prize-modal-note">' + tmpl.dataset.note + '</div>' : "") +
        "</div>";

      modalContent.style.borderColor = borderColor;
      modalContent.style.boxShadow = "0 0 60px " + glowColor + ", 0 0 120px " + glowColor;
      modalOverlay.classList.add("is-open");
      document.body.style.overflow = "hidden";
    }

    function closeModal() {
      if (!modalOverlay || !modalOverlay.classList.contains("is-open")) return;
      modalOverlay.classList.remove("is-open");
      document.body.style.overflow = "";
      setTimeout(function () { modalContent.innerHTML = ""; }, 400);
    }

    function resumeAfterClose() {
      isPaused = false;
      if (pairCount > 1) scheduleNext();
    }

    if (modalCloseBtn) {
      modalCloseBtn.addEventListener("click", function () {
        closeModal();
        resumeAfterClose();
      });
    }
    if (modalOverlay) {
      modalOverlay.addEventListener("click", function (e) {
        if (e.target === modalOverlay) { closeModal(); resumeAfterClose(); }
      });
    }
    document.addEventListener("keydown", function (e) {
      if (e.key === "Escape" && modalOverlay && modalOverlay.classList.contains("is-open")) {
        closeModal();
        resumeAfterClose();
      }
    });

    /* ── Initialization ── */
    if (cards.length) {
      buildPairs();

      /* Create dots — one per pair (skip for single-item static) */
      if (pairCount > 1) {
        for (var i = 0; i < pairCount; i++) {
          (function (idx) {
            var dot = document.createElement("button");
            dot.type = "button";
            dot.setAttribute("aria-label", "Show prize cards " + (idx + 1));
            dot.addEventListener("click", function () {
              clearTimeout(rotationTimer);
              isPaused = false;
              showPair(idx, scheduleNext, false);
            });
            dotsWrap.appendChild(dot);
          })(i);
        }
      }

      /* IntersectionObserver triggers the initial display */
      var observer = new IntersectionObserver(function (entries) {
        entries.forEach(function (entry) {
          if (entry.isIntersecting && !hasAnimated) {
            hasAnimated = true;
            /* Show first pair immediately — no blank state on initial load */
            showPair(0, scheduleNext, true);
            observer.unobserve(entry.target);
          }
        });
      }, { threshold: 0.2 });
      observer.observe(prizeCarousel);
    }
  }

  /* ── LEADERSHIP ENTRANCE ANIMATION ── */
  function initLeadershipEntrance() {
    var section = document.querySelector('[data-leadership]');
    if (!section) return;

    var cards = section.querySelectorAll('.leader-card');
    if (!cards.length) return;

    if (!("IntersectionObserver" in window)) {
      cards.forEach(function (c) { c.classList.add('leadership-animate'); });
      return;
    }

    var observer = new IntersectionObserver(function (entries) {
      entries.forEach(function (entry) {
        if (entry.isIntersecting) {
          cards.forEach(function (card, i) {
            setTimeout(function () {
              card.classList.add('leadership-animate');
            }, i * 180);
          });
          observer.unobserve(entry.target);
        }
      });
    }, { threshold: 0.15 });

    observer.observe(section);
  }

  document.addEventListener('DOMContentLoaded', function () {
    setTimeout(initLeadershipEntrance, 350);
  });

  /* ── Team member image lightbox ── */
  (function initTeamLightbox() {
    var lb = document.getElementById("teamLightbox");
    if (!lb) return;
    var lbImg = document.getElementById("teamLightboxImg");
    var lbCaption = document.getElementById("teamLightboxCaption");
    var closeBtn = lb.querySelector(".team-lightbox-close");

    function openLightbox(src, caption) {
      lbImg.src = src;
      lbImg.alt = caption || "";
      lbCaption.textContent = caption || "";
      lb.classList.add("open");
      document.body.style.overflow = "hidden";
    }

    function closeLightbox() {
      lb.classList.remove("open");
      lbImg.src = "";
      document.body.style.overflow = "";
    }

    document.addEventListener("click", function (e) {
      var imgWrap = e.target.closest("[data-lightbox]");
      if (!imgWrap) return;
      e.preventDefault();
      openLightbox(imgWrap.dataset.lightbox, imgWrap.dataset.caption || "");
    });

    lb.addEventListener("click", function (e) {
      if (e.target === lb || e.target === closeBtn || closeBtn.contains(e.target)) {
        closeLightbox();
      }
    });

    document.addEventListener("keydown", function (e) {
      if (e.key === "Escape" && lb.classList.contains("open")) closeLightbox();
    });
  })();

})();
