const { useState, useEffect, useRef, useMemo, useCallback } = React;

/* =========================================================
   Constants
   ========================================================= */
const EVENT_DATE = new Date("2026-07-18T09:00:00+02:00");
const PRICE_TIERS = [
  { max: 50,  price: "35 €", priceNum: 35 },
  { max: 120, price: "45 €", priceNum: 45 },
  { max: 150, price: "50 €", priceNum: 50 },
];
const RR_EVENT_ID = 399404;
const FALLBACK_STATS = { count: 0, tierIdx: 0, price: "35 €", priceNum: 35, spotsLeft: 200, total: 200, isFull: false, registrationUrl: `https://my.raceresult.com/${RR_EVENT_ID}/registration` };

function getActiveTier(count) {
  if (count < 50)  return 0;
  if (count < 150) return 1;
  return 2;
}

/* =========================================================
   Live stats hook — fetches /api/stats, falls back to static
   ========================================================= */
function useStats() {
  const [stats, setStats] = useState(FALLBACK_STATS);
  useEffect(() => {
    fetch("/api/stats")
      .then(r => r.ok ? r.json() : null)
      .then(d => { if (d) setStats(d); })
      .catch(() => {});
  }, []);
  return stats;
}

/* =========================================================
   Page-text helper — reads DB content with i18n fallback
   ========================================================= */
function pt(content, lang, section, key, fallback) {
  const entry = content?.texts?.[section]?.[key];
  if (!entry) return fallback;
  return (lang === 'en' ? (entry.en || entry.sk) : entry.sk) || fallback;
}

/* =========================================================
   CMS content hook — fetches /api/content (faq, gallery, program, texts)
   ========================================================= */
function useContent() {
  const CACHE_KEY = 'rct-content-v1';
  const [content, setContent] = useState(() => {
    if (typeof window !== 'undefined' && window.__INITIAL_CONTENT__) return window.__INITIAL_CONTENT__;
    try { return JSON.parse(localStorage.getItem(CACHE_KEY) || 'null'); } catch { return null; }
  });
  useEffect(() => {
    fetch("/api/content")
      .then(r => r.ok ? r.json() : null)
      .then(d => {
        if (d) {
          setContent(d);
          try { localStorage.setItem(CACHE_KEY, JSON.stringify(d)); } catch {}
        }
      })
      .catch(() => {});
  }, []);
  return content;
}

/* =========================================================
   i18n strings — Slovak is FINAL copy from the brief.
   English mirrors the same short, direct tone.
   ========================================================= */
const I18N = {
  sk: {
    htmlLang: "sk",
    nav: {
      about: "O simulácii",
      format: "Formát",
      gallery: "Galéria",
      price: "Cena",
      place: "Miesto",
      faq: "FAQ",
      participants: "Účastníci",
      gym: "O nás",
      cta: "Chcem ísť",
    },
    marquee: ["Silní spolu", "V GYMe aj v živote", "18.07.2026 · Kežmarok", "Limit {cap} miest", "Live timing", "8 staníc · 8 km"],
    aftermovie: {
      kicker: "Aftermovie",
      h2: "Pozri sa, aké to bolo.",
      sub: "Zostrih z minulých simulácií v Kežmarku. Sled, ergy, sandbagy. Bez filtrov, bez šminky.",
      tag: "2025 · Kežmarok",
      playLabel: "Pustiť aftermovie",
      duration: "2:14",
    },
    gallery: {
      kicker: "Galéria",
      h2: "Z poslednej simulácie.",
      sub: "Chalk, pot, sústredenie. Toto sa nedá zrežírovať.",
      cta: "Pozrieť všetky fotky",
      counter: "foto",
      close: "Zavrieť",
      next: "Ďalšie",
      prev: "Predošlé",
      captions: [
        "Sled push, druhá vlna",
        "Wall balls do konca",
        "Štart Pro vlny",
        "Farmers carry, posledný úsek",
        "Sandbag lunges",
        "SkiErg, prvá minúta",
        "Burpee broad jumps",
        "Cieľová rovinka",
        "Rowing 1000 m",
      ],
    },
    hero: {
      eyebrow: "18. júl 2026 · Kežmarok",
      eventName: "HYROX Simulation vol. 7",
      headline: "Otestuj sa. Skôr ako to bude ostré.",
      sub: "HYROX simulácia v Kežmarku. 8 staníc, 8 km behu, jeden štartovací čip. Ten istý formát ako oficiálne preteky.",
      ctaPrimary: "Chcem ísť",
      ctaSecondary: "Pozrieť formát",
      indicators: ["Limit {cap} miest", "OPEN · PRO · RELAY", "Live timing"],
      countdownLabels: { d: "Dní", h: "Hod", m: "Min", s: "Sek" },
    },
    about: {
      h2: "Čo je HYROX Simulácia.",
      p1: "HYROX je hybridný závod. Beh a osem funkčných staníc. Ten istý formát po celom svete.",
      p2: "Simulácia v Kežmarku je tvoja generálka. V tom istom formáte, s tým istým timingom, s tou istou disciplínou. Iba bez letenky.",
      p3: "Robíš to pre seba, alebo pre tím. Sám, vo dvojici alebo ako štafeta. Vyberieš si.",
      stats: [
        { n: "8 staníc", c: "funkčných cvičení" },
        { n: "8 × 1 km", c: "bežeckých úsekov" },
        { n: "60–90 min", c: "priemerný čas" },
      ],
    },
    format: {
      h2: "Formát závodu.",
      sub: "Ten istý formát ako oficiálny HYROX. Bez prekvapení.",
      foot: "Double si striedajú stanice, štafeta si rozdelí beh.",
      proNote: "PRO kategória má ťažšie záťaže na silových staniciach.",
      stations: [
        { t: "Beh + SkiErg",            base: "1 km beh + 1000 m SkiErg" },
        { t: "Beh + Sled Push",          base: "1 km beh + Sled Push 50 m",      open: "152 kg M · 102 kg Ž", pro: "202 kg M · 152 kg Ž" },
        { t: "Beh + Sled Pull",          base: "1 km beh + Sled Pull 50 m",      open: "103 kg M · 78 kg Ž",  pro: "153 kg M · 103 kg Ž" },
        { t: "Beh + Burpee Broad Jumps", base: "1 km beh + Burpee Broad Jumps 80 m" },
        { t: "Beh + Rowing",             base: "1 km beh + Rowing 1000 m" },
        { t: "Beh + Farmers Carry",      base: "1 km beh + Farmers Carry 200 m", open: "2×24 kg M · 2×16 kg Ž", pro: "2×32 kg M · 2×24 kg Ž" },
        { t: "Beh + Sandbag Lunges",     base: "1 km beh + Sandbag Lunges 100 m", open: "20 kg M · 10 kg Ž",    pro: "30 kg M · 20 kg Ž" },
        { t: "Beh + Wall Balls",         base: "1 km beh + 100 Wall Balls",       open: "6 kg M · 4 kg Ž",      pro: "9 kg M · 6 kg Ž" },
      ],
    },
    pricing: {
      h2: "Vyber si kategóriu.",
      ribbon: "Najobľúbenejšie",
      ctaCard: "Registrovať",
      note: "Cena je s DPH. Registráciu a platbu zabezpečuje náš partner. Po kliknutí ťa presmerujeme na jeho stránku.",
      tiers: {
        kicker: "Progresívna cena",
        sub: "Cena rastie s počtom prihlásených. Rozhodni sa skôr.",
        t1label: "1 – 50 účastníkov",
        t2label: "51 – 150 účastníkov",
        t3label: "151 – 200 účastníkov",
        registered: "prihlásených",
        spotsLeft: "miest zostáva v tejto cene",
        activeLabel: "Aktuálna cena",
        filledLabel: "Obsadené",
      },
      cards: [
        {
          k: "OPEN",
          price: "od 35 €",
          tag: "Jednotlivci a doubles.",
          bullets: ["Men Individual", "Women Individual", "Doubles M+M", "Doubles Ž+Ž", "Mix Doubles Ž+M"],
        },
        {
          k: "PRO",
          price: "od 45 €",
          tag: "Pre skúsených atlétov.",
          bullets: ["Men Individual", "Women Individual", "Doubles M+M", "Doubles Ž+Ž", "Vyššie záťaže"],
        },
        {
          k: "RELAY",
          price: "od 100 €",
          tag: "Team of 4.",
          bullets: ["4-členný tím", "Každý 2 stanice + 2 km", "Tímové umiestnenie"],
        },
      ],
    },
    place: {
      h2: "Kde a kedy.",
      rows: [
        { l: "Dátum", v: "Sobota, 18. júl 2026" },
        { l: "Čas", v: "9:00 až 17:00 (vlny každých 30 minút)" },
        { l: "Miesto", v: "RCT Kežmarok, Trhovište 2/A, Kežmarok" },
        { l: "Parkovanie", v: "Pri hale, zadarmo" },
        { l: "Šatne", v: "K dispozícii so sprchami" },
      ],
      mapHint: "RCT Kežmarok · Trhovište 2/A",
      timeline: [
        { t: "08:00", l: "Otvorenie a check-in" },
        { t: "09:00", l: "Vlna 1 – OPEN Individual" },
        { t: "10:30", l: "Vlna 2 – OPEN Doubles" },
        { t: "12:00", l: "Vlna 3 – PRO Individual" },
        { t: "13:30", l: "Vlna 4 – PRO Doubles" },
        { t: "15:00", l: "RELAY" },
        { t: "17:30", l: "Vyhlásenie najlepších časov" },
      ],
    },
    faq: {
      h2: "Časté otázky.",
      items: [
        { q: "Pre koho je simulácia vhodná?", a: "Pre teba, ak chceš otestovať HYROX formát naživo. Hobby športovec aj skúsený atlét. Stačí, že vieš bežať a zvládneš základné silové prvky." },
        { q: "Potrebujem nejakú výbavu?", a: "Bežné športové oblečenie a tréningovú obuv. Náradie máme priamo v hale." },
        { q: "Čím sa to líši od oficiálnych HYROX pretekov?", a: "Formát je rovnaký. Atmosféra menšia, lokálnejšia. Cena nižšia. Generálka pred sezónou." },
        { q: "Môžem si vybrať čas vlny?", a: "Áno. Pri registrácii cez partnera vyberieš slot. Plnia sa od rána." },
        { q: "Čo ak sa nemôžem zúčastniť?", a: "Štartovné vieme presunúť na iného účastníka. Refund závisí od dátumu zrušenia, detaily nájdeš pri registrácii." },
        { q: "Bude na mieste občerstvenie a zdravotná služba?", a: "Áno. Voda, ovocie, regeneračné nápoje. Na mieste je certifikovaný zdravotník." },
      ],
    },
    participants: {
      kicker: "Prihlásení",
      h2: "Kto už ide.",
      sub: "Zoznam prihlásených účastníkov. Aktualizuje sa v reálnom čase.",
    },
    finalCta: {
      h: "Pripravený na ostré?",
      sub: "Limit {cap} miest. Vlny sa plnia od rána. Kým váhaš, niekto iný si zoberie tvoj slot.",
      btn: "Registrovať sa",
      micro: "Registrácia a platba prebieha priamo tu cez raceresult.",
    },
    footer: {
      tagline: "Reds Crew Trainings Kežmarok. Silní spolu. V GYMe aj v živote.",
      contactH: "Kontakt",
      linksH: "Linky",
      coachH: "Tréner / partneri",
      links: ["O nás", "Obchodné podmienky", "GDPR", "Reklamačný poriadok"],
      coach: "Head Coach: Dejvo Mikša",
      partners: "Partneri",
      copy: "© 2026 RCT Kežmarok. Reds Crew Trainings.",
    },
    registration: {
      kicker: "Registrácia",
      title: "Rezervuj si miesto.",
      currentTier: "Aktuálna cena",
      spotsLeft: "miest zostáva",
      full: "Kapacita eventu je plná.",
      name: "Celé meno",
      email: "Email",
      phone: "Telefón (voliteľné)",
      category: "Kategória",
      wave: "Preferovaná vlna",
      wavePlaceholder: "Bez preferencie",
      partner: "Meno partnera (Double)",
      team: "Názov tímu (Štafeta)",
      consent: "Súhlasím so spracovaním osobných údajov za účelom registrácie na event. Údaje nebudú poskytnuté tretím stranám.",
      consentRequired: "Súhlas so spracovaním údajov je povinný.",
      submit: "Registrovať sa",
      sending: "Odosielam…",
      successTitle: "Registrácia prijatá.",
      successBody: "Dostaneš potvrdenie emailom. Tešíme sa na teba 18. júla v Kežmarku.",
      close: "Zavrieť",
      errorGeneric: "Nastala chyba. Skús to znova.",
    },
  },

  en: {
    htmlLang: "en",
    nav: {
      about: "About",
      format: "Format",
      gallery: "Gallery",
      price: "Pricing",
      place: "Venue",
      faq: "FAQ",
      participants: "Participants",
      gym: "About us",
      cta: "I'm in",
    },
    marquee: ["Strong together", "In the gym and in life", "18.07.2026 · Kežmarok", "{cap} slots only", "Live timing", "8 stations · 8 km"],
    aftermovie: {
      kicker: "Aftermovie",
      h2: "See how it went.",
      sub: "Cut from past simulations in Kežmarok. Sleds, ergs, sandbags. No filters, no polish.",
      tag: "2025 · Kežmarok",
      playLabel: "Play aftermovie",
      duration: "2:14",
    },
    gallery: {
      kicker: "Gallery",
      h2: "From past simulations.",
      sub: "Chalk, sweat, focus. You can't direct this.",
      cta: "See all photos",
      counter: "photo",
      close: "Close",
      next: "Next",
      prev: "Previous",
      captions: [
        "Sled push, wave two",
        "Wall balls to the end",
        "Pro wave start",
        "Farmers carry, final stretch",
        "Sandbag lunges",
        "SkiErg, first minute",
        "Burpee broad jumps",
        "Finish line",
        "Rowing 1000 m",
      ],
    },
    hero: {
      eyebrow: "July 18, 2026 · Kežmarok",
      eventName: "HYROX Simulation vol. 7",
      headline: "Test yourself. Before it gets real.",
      sub: "HYROX simulation in Kežmarok. 8 stations, 8 km of running, one timing chip. Same format as the official race.",
      ctaPrimary: "I'm in",
      ctaSecondary: "See the format",
      indicators: ["{cap} slots only", "OPEN · PRO · RELAY", "Live timing"],
      countdownLabels: { d: "Days", h: "Hrs", m: "Min", s: "Sec" },
    },
    about: {
      h2: "What HYROX Simulation is.",
      p1: "HYROX is a hybrid race. Running plus eight functional stations. Same format worldwide.",
      p2: "Our Kežmarok simulation is your dress rehearsal. Same format, same timing, same discipline. Without the plane ticket.",
      p3: "Do it for yourself, or for the team. Solo, doubles, or relay. Your call.",
      stats: [
        { n: "8 stations", c: "functional movements" },
        { n: "8 × 1 km", c: "running sections" },
        { n: "60–90 min", c: "average time" },
      ],
    },
    format: {
      h2: "Race format.",
      sub: "Same format as official HYROX. No surprises.",
      foot: "Double swaps stations. Relay splits the run.",
      stations: [
        { t: "Run + SkiErg", d: "1 km run + 1000 m SkiErg" },
        { t: "Run + Sled Push", d: "1 km run + Sled Push 50 m (152 kg M / 102 kg W)" },
        { t: "Run + Sled Pull", d: "1 km run + Sled Pull 50 m (103 kg M / 78 kg W)" },
        { t: "Run + Burpee Broad Jumps", d: "1 km run + Burpee Broad Jumps 80 m" },
        { t: "Run + Rowing", d: "1 km run + Rowing 1000 m" },
        { t: "Run + Farmers Carry", d: "1 km run + Farmers Carry 200 m (2×24 kg M / 2×16 kg W)" },
        { t: "Run + Sandbag Lunges", d: "1 km run + Sandbag Lunges 100 m (20 kg M / 10 kg W)" },
        { t: "Run + Wall Balls", d: "1 km run + 100 Wall Balls (6 kg M / 4 kg W)" },
      ],
    },
    pricing: {
      h2: "Pick your category.",
      ribbon: "Most popular",
      ctaCard: "Register",
      note: "VAT included. Registration and payment handled by our partner. You'll be redirected on click.",
      tiers: {
        kicker: "Progressive pricing",
        sub: "Price increases with registrations. Decide sooner.",
        t1label: "1 – 50 participants",
        t2label: "51 – 150 participants",
        t3label: "151 – 200 participants",
        registered: "registered",
        spotsLeft: "spots left at this price",
        activeLabel: "Current price",
        filledLabel: "Filled",
      },
      cards: [
        {
          k: "OPEN",
          price: "from €35",
          tag: "Individuals and doubles.",
          bullets: ["Men Individual", "Women Individual", "Doubles M+M", "Doubles F+F", "Mix Doubles F+M"],
        },
        {
          k: "PRO",
          price: "from €45",
          tag: "For experienced athletes.",
          bullets: ["Men Individual", "Women Individual", "Doubles M+M", "Doubles F+F", "Heavier loads"],
        },
        {
          k: "RELAY",
          price: "from €100",
          tag: "Team of 4.",
          bullets: ["4-person team", "2 stations + 2 km each", "Team ranking"],
        },
      ],
    },
    place: {
      h2: "Where and when.",
      rows: [
        { l: "Date", v: "Saturday, July 18, 2026" },
        { l: "Time", v: "9:00 to 17:00 (waves every 30 minutes)" },
        { l: "Venue", v: "RCT Kežmarok, Trhovište 2/A, Kežmarok" },
        { l: "Parking", v: "Next to the gym, free" },
        { l: "Changing rooms", v: "Available with showers" },
      ],
      mapHint: "RCT Kežmarok · Trhovište 2/A",
      timeline: [
        { t: "08:00", l: "Doors open and check-in" },
        { t: "09:00", l: "Wave 1 – OPEN Individual" },
        { t: "10:30", l: "Wave 2 – OPEN Doubles" },
        { t: "12:00", l: "Wave 3 – PRO Individual" },
        { t: "13:30", l: "Wave 4 – PRO Doubles" },
        { t: "15:00", l: "RELAY" },
        { t: "17:30", l: "Top times announced" },
      ],
    },
    faq: {
      h2: "Questions.",
      items: [
        { q: "Who is this for?", a: "For you, if you want to test the HYROX format live. Hobby athletes and serious competitors alike. You need to be able to run and handle basic strength movements." },
        { q: "Do I need any gear?", a: "Regular sports clothes and training shoes. We have all equipment in the gym." },
        { q: "How is this different from an official HYROX race?", a: "Same format. Smaller, more local atmosphere. Lower price. A dress rehearsal before the season." },
        { q: "Can I pick my wave time?", a: "Yes. You'll pick a slot at our partner's registration page. Morning waves fill first." },
        { q: "What if I can't make it?", a: "Your slot can be transferred to another athlete. Refund depends on cancellation date, details at registration." },
        { q: "Is there food and medical on site?", a: "Yes. Water, fruit, recovery drinks. A certified medic is present." },
      ],
    },
    participants: {
      kicker: "Registered",
      h2: "Who's in.",
      sub: "Live list of registered participants.",
    },
    finalCta: {
      h: "Ready for the real thing?",
      sub: "{cap} slots only. Morning waves fill first. While you wait, someone else takes your spot.",
      btn: "Register now",
      micro: "Registration and payment handled directly here via raceresult.",
    },
    footer: {
      tagline: "Reds Crew Trainings Kežmarok. Strong together. In the gym and in life.",
      contactH: "Contact",
      linksH: "Links",
      coachH: "Coach / partners",
      links: ["About", "Terms", "Privacy", "Refund policy"],
      coach: "Head Coach: Dejvo Mikša",
      partners: "Partners",
      copy: "© 2026 RCT Kežmarok. Reds Crew Trainings.",
    },
    registration: {
      kicker: "Registration",
      title: "Reserve your spot.",
      currentTier: "Current price",
      spotsLeft: "spots left",
      full: "Event capacity is full.",
      name: "Full name",
      email: "Email",
      phone: "Phone (optional)",
      category: "Category",
      wave: "Preferred wave",
      wavePlaceholder: "No preference",
      partner: "Partner name (Double)",
      team: "Team name (Relay)",
      consent: "I agree to the processing of my personal data for event registration. Data will not be shared with third parties.",
      consentRequired: "Consent to data processing is required.",
      submit: "Register",
      sending: "Sending…",
      successTitle: "Registration received.",
      successBody: "You'll receive a confirmation email. See you on July 18 in Kežmarok.",
      close: "Close",
      errorGeneric: "An error occurred. Please try again.",
    },
  },
};

/* =========================================================
   Script loader helper
   ========================================================= */
function loadScript(src, id) {
  return new Promise(resolve => {
    if (document.getElementById(id)) { resolve(); return; }
    const s = document.createElement('script');
    s.id = id; s.src = src;
    s.onload = resolve; s.onerror = resolve;
    document.head.appendChild(s);
  });
}

/* =========================================================
   Reveal-on-scroll hook
   ========================================================= */
function useReveal() {
  useEffect(() => {
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) {
            e.target.classList.add("in");
            io.unobserve(e.target);
          }
        });
      },
      { threshold: 0.12 }
    );
    document.querySelectorAll(".reveal, .reveal-clip, .reveal-scale").forEach((el) => io.observe(el));
    return () => io.disconnect();
  });
}

/* =========================================================
   Countdown
   ========================================================= */
function useCountdown(target) {
  const [now, setNow] = useState(() => Date.now());
  useEffect(() => {
    const id = setInterval(() => setNow(Date.now()), 1000);
    return () => clearInterval(id);
  }, []);
  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 };
}

/* =========================================================
   Inline icons (Lucide-style, stroke 2)
   ========================================================= */
const Icon = ({ name, className = "w-5 h-5", stroke = "currentColor" }) => {
  const common = {
    width: 24, height: 24, viewBox: "0 0 24 24", fill: "none",
    stroke, strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round",
    className,
  };
  switch (name) {
    case "check":
      return <svg {...common}><polyline points="4 12 10 18 20 6" /></svg>;
    case "arrow-right":
      return <svg {...common}><line x1="5" y1="12" x2="19" y2="12" /><polyline points="13 6 19 12 13 18" /></svg>;
    case "plus":
      return <svg {...common}><line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" /></svg>;
    case "calendar":
      return <svg {...common}><rect x="3" y="5" width="18" height="16" /><line x1="3" y1="10" x2="21" y2="10" /><line x1="8" y1="3" x2="8" y2="7" /><line x1="16" y1="3" x2="16" y2="7" /></svg>;
    case "clock":
      return <svg {...common}><circle cx="12" cy="12" r="9" /><polyline points="12 7 12 12 16 14" /></svg>;
    case "pin":
      return <svg {...common}><path d="M12 22s7-7.5 7-13a7 7 0 1 0-14 0c0 5.5 7 13 7 13z" /><circle cx="12" cy="9" r="2.5" /></svg>;
    case "car":
      return <svg {...common}><path d="M3 13l2-5h14l2 5" /><rect x="3" y="13" width="18" height="6" /><circle cx="7.5" cy="19" r="1.5" /><circle cx="16.5" cy="19" r="1.5" /></svg>;
    case "shower":
      return <svg {...common}><path d="M5 13V6a4 4 0 0 1 8 0" /><line x1="14" y1="13" x2="22" y2="13" /><line x1="3" y1="13" x2="22" y2="13" /><line x1="7" y1="17" x2="7" y2="20" /><line x1="11" y1="17" x2="11" y2="20" /><line x1="15" y1="17" x2="15" y2="20" /><line x1="19" y1="17" x2="19" y2="20" /></svg>;
    case "instagram":
      return <svg {...common}><rect x="3" y="3" width="18" height="18" /><circle cx="12" cy="12" r="4" /><circle cx="17.5" cy="6.5" r="0.5" fill={stroke} /></svg>;
    case "facebook":
      return <svg {...common}><path d="M14 8h3V4h-3a4 4 0 0 0-4 4v2H7v4h3v8h4v-8h3l1-4h-4V8a1 1 0 0 1 1-1z" /></svg>;
    case "youtube":
      return <svg {...common}><rect x="2" y="6" width="20" height="12" /><polygon points="10 9 16 12 10 15" fill={stroke} stroke="none" /></svg>;
    default:
      return null;
  }
};

/* =========================================================
   Logo — uses real PNGs from the project directory
   ========================================================= */
const Logo = ({ dark = false, className = "h-10" }) => {
  const src = dark ? "white-logo-rct.png" : "logo-rct.png";
  return (
    <img
      src={src}
      alt="RCT Kežmarok"
      className={`w-auto object-contain ${className}`}
    />
  );
};

/* =========================================================
   Nav
   ========================================================= */
function Nav({ lang, setLang, t, onRegister }) {
  const [scrolled, setScrolled] = useState(false);
  const [open, setOpen] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 80);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  const links = [
    { id: "about", l: t.nav.about },
    { id: "format", l: t.nav.format },
    { id: "price", l: t.nav.price },
    { id: "participants", l: t.nav.participants },
    { id: "place", l: t.nav.place },
    { id: "gallery", l: t.nav.gallery },
    { id: "faq", l: t.nav.faq },
    { id: null, href: "/o-nas", l: t.nav.gym },
  ];
  return (
    <header
      className={`fixed top-0 left-0 right-0 z-50 transition-colors duration-300 ${
        scrolled ? "bg-rct-offblack border-b border-white/10" : "bg-transparent"
      }`}
    >
      <div className="max-w-[1440px] mx-auto px-6 lg:px-10 h-16 lg:h-20 flex items-center justify-between">
        <a href="#top" className="focus-ring shrink-0" aria-label="RCT Kežmarok">
          <Logo dark={true} className="h-9 lg:h-11" />
        </a>

        <nav className="hidden lg:flex items-center gap-8">
          {links.map((x) => (
            <a
              key={x.href || x.id}
              href={x.href || `#${x.id}`}
              className={`focus-ring text-[13px] font-semibold uppercase tracking-[0.14em] transition-colors ${
                scrolled ? "text-white/80 hover:text-white" : "text-white/90 hover:text-white"
              }`}
            >
              {x.l}
            </a>
          ))}
        </nav>

        <div className="flex items-center gap-3 lg:gap-5">
          <div className={`flex items-center text-[12px] font-bold uppercase tracking-[0.16em] ${scrolled ? "text-white" : "text-white"}`}>
            <button
              onClick={() => setLang("sk")}
              className={`focus-ring px-2 py-1 ${lang === "sk" ? "text-rct-red" : "text-white/70 hover:text-white"}`}
              aria-pressed={lang === "sk"}
            >SK</button>
            <span className="text-white/30">/</span>
            <button
              onClick={() => setLang("en")}
              className={`focus-ring px-2 py-1 ${lang === "en" ? "text-rct-red" : "text-white/70 hover:text-white"}`}
              aria-pressed={lang === "en"}
            >EN</button>
          </div>

          <button
            type="button"
            onClick={onRegister}
            className="focus-ring hidden sm:inline-flex items-center gap-2 bg-rct-red hover:bg-rct-red-deep text-white font-black uppercase tracking-[0.14em] text-[13px] px-5 py-3 transition-colors"
          >
            {t.nav.cta}
            <Icon name="arrow-right" className="w-4 h-4" />
          </button>

          <button
            className="lg:hidden focus-ring text-white p-2 -mr-2"
            aria-label="Menu"
            onClick={() => setOpen((o) => !o)}
          >
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
              {open ? (
                <><line x1="6" y1="6" x2="18" y2="18" /><line x1="18" y1="6" x2="6" y2="18" /></>
              ) : (
                <><line x1="4" y1="7" x2="20" y2="7" /><line x1="4" y1="12" x2="20" y2="12" /><line x1="4" y1="17" x2="20" y2="17" /></>
              )}
            </svg>
          </button>
        </div>
      </div>

      {open && (
        <div className="lg:hidden bg-rct-offblack border-t border-white/10">
          <div className="px-6 py-5 flex flex-col gap-4">
            {links.map((x) => (
              <a
                key={x.href || x.id}
                href={x.href || `#${x.id}`}
                onClick={() => setOpen(false)}
                className="text-white font-semibold uppercase tracking-[0.14em] text-sm"
              >
                {x.l}
              </a>
            ))}
            <button
              type="button"
              onClick={onRegister}
              className="bg-rct-red text-white font-black uppercase tracking-[0.14em] text-sm px-5 py-3 inline-flex items-center justify-center gap-2 mt-2"
            >
              {t.nav.cta}
              <Icon name="arrow-right" className="w-4 h-4" />
            </button>
          </div>
        </div>
      )}
    </header>
  );
}

/* =========================================================
   Hero
   ========================================================= */
function Hero({ t, stats, onRegister, content, lang }) {
  const eventDate = stats.eventDate ? new Date(stats.eventDate) : EVENT_DATE;
  const { d, h, m, s } = useCountdown(eventDate);
  const pad = (n) => String(n).padStart(2, "0");
  const eyebrow   = pt(content, lang, 'hero', 'eyebrow',    t.hero.eyebrow);
  const eventName = pt(content, lang, 'hero', 'event_name', t.hero.eventName);
  const headline  = pt(content, lang, 'hero', 'headline',   t.hero.headline);
  const heroSub   = pt(content, lang, 'hero', 'sub',        t.hero.sub);
  const bgUrl     = pt(content, lang, 'hero', 'bg_url',
    'https://images.unsplash.com/photo-1534438327276-14e5300c3a48?auto=format&fit=crop&w=2200&q=80');
  return (
    <section id="top" className="relative min-h-[90vh] flex items-center bg-rct-black overflow-hidden">
      {/* Photo background */}
      <div
        className="absolute inset-0 bg-cover bg-center"
        style={{
          backgroundImage: `url('${bgUrl}')`,
        }}
        aria-hidden="true"
      />
      <div className="absolute inset-0 bg-black/65" aria-hidden="true" />
      <div className="absolute inset-0 bg-gradient-to-b from-black/40 via-transparent to-black/80" aria-hidden="true" />

      <div className="relative z-10 w-full max-w-[1440px] mx-auto px-6 lg:px-10 pt-32 lg:pt-36 pb-20">
        <p className="text-rct-red font-black uppercase tracking-[0.32em] text-[12px] lg:text-[13px] reveal">
          {eyebrow}
        </p>

        <p className="reveal mt-4 text-white font-black uppercase tracking-[0.08em] text-[22px] lg:text-[28px]">
          {eventName}
        </p>

        <h1
          className="reveal mt-3 text-white font-black uppercase max-w-[16ch]"
          style={{ fontSize: "clamp(2.75rem, 7vw, 5.75rem)", lineHeight: 0.95, letterSpacing: "-0.01em" }}
        >
          {headline}
        </h1>

        <p className="reveal mt-6 text-white/85 font-semibold text-[18px] lg:text-[21px] leading-[1.45] max-w-[640px]">
          {heroSub}
        </p>

        <div className="reveal mt-10 flex flex-col sm:flex-row gap-4">
          <button
            type="button"
            onClick={onRegister}
            className="focus-ring inline-flex items-center justify-center gap-2 bg-rct-red hover:bg-rct-red-deep text-white font-black uppercase tracking-[0.16em] text-[15px] px-8 py-5 transition-colors"
          >
            {t.hero.ctaPrimary}
            <Icon name="arrow-right" className="w-5 h-5" />
          </button>
          <a
            href="#format"
            className="focus-ring inline-flex items-center justify-center gap-2 border-2 border-white text-white hover:bg-white hover:text-rct-offblack font-black uppercase tracking-[0.16em] text-[15px] px-8 py-5 transition-colors"
          >
            {t.hero.ctaSecondary}
          </a>
        </div>

        <div className="reveal mt-10 flex flex-wrap items-center gap-x-4 gap-y-2 text-white/80 text-[13px] font-medium">
          {t.hero.indicators.map((x, i) => (
            <React.Fragment key={i}>
              <span className="uppercase tracking-[0.14em]">{x.replace('{cap}', stats.total || '')}</span>
              {i < t.hero.indicators.length - 1 && <span className="text-rct-red">·</span>}
            </React.Fragment>
          ))}
        </div>
      </div>

      {/* Desktop countdown */}
      <div className="hidden lg:flex absolute right-10 bottom-10 z-10 flex-col items-end gap-3">
        <span className="text-rct-red font-black uppercase tracking-[0.24em] text-[11px]">
          {eyebrow.split("·")[0].trim()}
        </span>
        <div className="flex gap-3 border-l-4 border-rct-red pl-4">
          {[{n:d,l:t.hero.countdownLabels.d},{n:h,l:t.hero.countdownLabels.h},{n:m,l:t.hero.countdownLabels.m},{n:s,l:t.hero.countdownLabels.s}].map((x, i) => (
            <div key={i} className="flex flex-col items-center min-w-[58px]">
              <span className="text-white font-black text-[34px] num-mono leading-none">{pad(x.n)}</span>
              <span className="text-rct-red text-[10px] font-bold uppercase tracking-[0.2em] mt-1">{x.l}</span>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* =========================================================
   About
   ========================================================= */
function About({ t, content, lang }) {
  const aboutH2 = pt(content, lang, 'about', 'h2', t.about.h2);
  const aboutP1 = pt(content, lang, 'about', 'p1', t.about.p1);
  const aboutP2 = pt(content, lang, 'about', 'p2', t.about.p2);
  const aboutP3 = pt(content, lang, 'about', 'p3', t.about.p3);
  return (
    <section id="about" className="bg-white py-10 lg:py-20">
      <div className="max-w-[1440px] mx-auto px-6 lg:px-10 grid lg:grid-cols-12 gap-10 lg:gap-16">
        <div className="lg:col-span-7 reveal">
          <h2 className="text-rct-offblack font-black uppercase tracking-tight"
              style={{ fontSize: "clamp(2rem, 4.2vw, 3rem)", lineHeight: 1 }}>
            {aboutH2}
          </h2>
          <div className="mt-8 space-y-5 text-rct-charcoal text-[17px] lg:text-[18px] leading-[1.55] font-medium max-w-[58ch]">
            <p>{aboutP1}</p>
            <p>{aboutP2}</p>
            <p>{aboutP3}</p>
          </div>
        </div>

        <div className="lg:col-span-5 flex flex-col gap-5">
          {t.about.stats.map((x, i) => (
            <div
              key={i}
              className="reveal bg-white border-l-[6px] border-rct-red pl-6 pr-5 py-6 shadow-[0_1px_0_0_#eee]"
            >
              <div className="text-rct-offblack font-black text-[38px] sm:text-[44px] lg:text-[52px] leading-none tracking-tight">
                {x.n}
              </div>
              <div className="mt-2 text-rct-charcoal text-[14px] font-semibold uppercase tracking-[0.14em]">
                {x.c}
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* =========================================================
   Format
   ========================================================= */
function Format({ t }) {
  const [cat, setCat] = React.useState("open");
  return (
    <section id="format" className="bg-rct-offblack py-10 lg:py-20 border-y-[6px] border-rct-red">
      <div className="max-w-[1440px] mx-auto px-6 lg:px-10">
        <div className="reveal flex flex-wrap items-end justify-between gap-6">
          <div>
            <h2 className="text-white font-black uppercase tracking-tight"
                style={{ fontSize: "clamp(2rem, 4.2vw, 3rem)", lineHeight: 1 }}>
              {t.format.h2}
            </h2>
            <p className="mt-4 text-rct-red font-medium text-[16px] lg:text-[18px]">{t.format.sub}</p>
          </div>
          <div className="flex border border-white/20 shrink-0">
            {["open", "pro"].map((c) => (
              <button
                key={c}
                onClick={() => setCat(c)}
                className={`px-7 py-3 text-[13px] font-black uppercase tracking-[0.14em] transition-colors
                  ${c === "pro" ? "border-l border-white/20" : ""}
                  ${cat === c ? "bg-rct-red text-white" : "text-white/35 hover:text-white/70"}`}
              >{c}</button>
            ))}
          </div>
        </div>

        <div className="mt-10 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 lg:gap-5">
          {t.format.stations.map((x, i) => {
            const hasDiff = !!(x.open && x.pro);
            const weights = hasDiff ? x[cat] : null;
            return (
              <div
                key={i}
                className="reveal group bg-rct-offblack border border-white/15 hover:border-rct-red transition-colors p-6 flex flex-col gap-4 min-h-[200px]"
              >
                <div className="flex items-start justify-between">
                  <span className="text-rct-red font-black leading-none text-[44px] sm:text-[56px] lg:text-[64px] tracking-tight num-mono">
                    {String(i + 1).padStart(2, "0")}
                  </span>
                  {hasDiff && (
                    <span className={`mt-3 text-[10px] font-black uppercase tracking-[0.14em] px-2 py-1 border
                      ${cat === "pro" ? "border-rct-red/60 text-rct-red" : "border-white/20 text-white/35"}`}>
                      {cat}
                    </span>
                  )}
                </div>
                <div className="flex flex-col gap-2">
                  <h3 className="text-white font-black uppercase text-[17px] lg:text-[18px] tracking-tight">{x.t}</h3>
                  <p className="text-rct-charcoal-light text-[13px] leading-[1.5]">{x.base}</p>
                  {weights && (
                    <p className="text-white font-bold text-[13px] pt-1 border-t border-white/10">{weights}</p>
                  )}
                </div>
              </div>
            );
          })}
        </div>

        <div className="reveal mt-10 flex flex-wrap gap-x-8 gap-y-2">
          <p className="text-white/85 text-[15px] lg:text-[16px] font-medium">{t.format.foot}</p>
          <p className="text-white/40 text-[14px] lg:text-[15px]">{t.format.proNote}</p>
        </div>
      </div>
    </section>
  );
}

/* =========================================================
   Pricing
   ========================================================= */
function Pricing({ t, stats, onRegister }) {
  const count = stats.count;
  const activeTierIdx = stats.tierIdx;
  const tiers = stats.tiers || PRICE_TIERS;
  const total = stats.total || 200;
  const spotsLeft = stats.spotsLeft;
  const progressPct = Math.min(100, (count / total) * 100);
  const tierLabels = tiers.map((tier, i) => {
    const min = i === 0 ? 1 : tiers[i - 1].max + 1;
    return `${min} – ${tier.max} ${t.pricing.tiers.registered}`;
  });

  // Group prices from API, fall back to i18n defaults if not yet configured
  const gp = stats.groupPrices || {};
  const fmtFrom  = p => p > 0 ? `od ${p} €` : null;
  const fmtExact = p => p > 0 ? `${p} €` : null;
  const cards = t.pricing.cards.map((c, i) => {
    if (i === 0) return { ...c, price: fmtFrom(gp.open)  || c.price };
    if (i === 1) return { ...c, price: fmtFrom(gp.pro)   || c.price };
    if (i === 2) return { ...c, price: fmtFrom(gp.relay) || c.price };
    return c;
  });

  return (
    <section id="price" className="bg-white pt-6 pb-10 lg:pt-10 lg:pb-20">
      <div className="max-w-[1440px] mx-auto px-6 lg:px-10">
        <h2 className="reveal text-rct-offblack font-black uppercase tracking-tight"
            style={{ fontSize: "clamp(2rem, 4.2vw, 3rem)", lineHeight: 1 }}>
          {t.pricing.h2}
        </h2>

        {/* ── Tier progress block ── */}
        <div className="reveal mt-10 bg-rct-offblack p-6 lg:p-8">
          <div className="flex flex-wrap items-start justify-between gap-4 mb-6">
            <div>
              <p className="text-rct-red font-black uppercase tracking-[0.28em] text-[11px]">
                {t.pricing.tiers.kicker}
              </p>
              <p className="mt-2 text-white font-black text-[17px] lg:text-[20px] leading-tight max-w-[40ch]">
                {t.pricing.tiers.sub}
              </p>
            </div>
            <div className="text-right shrink-0">
              <span className="text-white font-black text-[28px] sm:text-[36px] lg:text-[44px] num-mono leading-none">{count}</span>
              <span className="block text-white/50 text-[12px] font-semibold uppercase tracking-[0.14em] mt-1">/ {total} {t.pricing.tiers.registered}</span>
            </div>
          </div>

          {/* Three tier columns */}
          <div className="grid grid-cols-1 sm:grid-cols-3 gap-2 lg:gap-3 mt-6">
            {tiers.map((tier, i) => {
              const state = i < activeTierIdx ? "filled" : i === activeTierIdx ? "active" : "upcoming";
              return (
                <div
                  key={i}
                  className={`relative p-4 sm:p-3 lg:p-5 border-2 transition-colors ${
                    state === "active"   ? "border-rct-red bg-rct-red/10" :
                    state === "filled"   ? "border-white/20 bg-white/5"   :
                                          "border-white/10"
                  }`}
                >
                  {state === "active" && (
                    <div className="absolute -top-[13px] left-3 bg-rct-red text-white text-[10px] font-black uppercase tracking-[0.16em] px-2 py-[3px]">
                      {t.pricing.tiers.activeLabel}
                    </div>
                  )}
                  <div className={`font-black text-[18px] sm:text-[26px] lg:text-[34px] leading-none num-mono ${
                    state === "active" ? "text-white" : "text-white/35"
                  }`}>
                    {tier.minPrice > 0 ? `od ${tier.minPrice} €` : tier.label}
                  </div>
                  <div className={`mt-2 text-[11px] font-bold uppercase tracking-[0.12em] ${
                    state === "active" ? "text-rct-red" : "text-white/35"
                  }`}>
                    {tierLabels[i]}
                  </div>
                  {state === "active" && (
                    <div className="mt-3 text-white/75 text-[13px] font-semibold">
                      <span className="text-white font-black">{Math.max(0, tiers[i].max - count)}</span> {t.pricing.tiers.spotsLeft}
                    </div>
                  )}
                  {state === "filled" && (
                    <div className="mt-3 text-white/35 text-[12px] font-bold uppercase tracking-[0.14em]">
                      {t.pricing.tiers.filledLabel}
                    </div>
                  )}
                </div>
              );
            })}
          </div>

          {/* Progress bar */}
          <div className="mt-5 relative h-2 bg-white/10">
            <div
              className="absolute inset-y-0 left-0 bg-rct-red"
              style={{ width: `${progressPct}%` }}
            />
            {/* Tier boundary markers — skip if at/beyond total (would overlap right label) */}
            {tiers.slice(0, -1).map((tier, i) => {
              const pct = (tier.max / total) * 100;
              if (pct >= 99) return null;
              return <div key={i} className="absolute inset-y-0 w-px bg-white/30" style={{ left: `${pct}%` }} />;
            })}
          </div>
          <div className="mt-1.5 relative text-[10px] font-mono text-white/35 uppercase tracking-[0.12em] select-none" style={{ height: "14px" }}>
            <span style={{ position: "absolute", left: 0 }}>0</span>
            {tiers.slice(0, -1).map((tier, i) => {
              const pct = (tier.max / total) * 100;
              if (pct >= 99) return null;
              return <span key={i} style={{ position: "absolute", left: `${pct}%`, transform: "translateX(-50%)" }}>{tier.max}</span>;
            })}
            <span style={{ position: "absolute", right: 0 }}>{total}</span>
          </div>
        </div>

        {/* ── Category cards ── */}
        <div className="mt-8 grid grid-cols-1 md:grid-cols-3 gap-5">
          {cards.map((c, i) => {
            const featured = i === 0;
            return (
              <div
                key={i}
                className="reveal relative bg-white border-2 border-rct-offblack hover:border-rct-red hover:-translate-y-1 transition-all duration-200 flex flex-col"
              >
                {featured && (
                  <div className="absolute top-0 right-0 bg-rct-red text-white font-black uppercase tracking-[0.14em] text-[10px] px-3 py-2">
                    {t.pricing.ribbon}
                  </div>
                )}
                <div className="p-7 flex-1 flex flex-col">
                  <h3 className="text-rct-offblack font-black uppercase text-[28px] lg:text-[32px] tracking-tight">
                    {c.k}
                  </h3>
                  <div className="mt-3 text-rct-red font-black text-[48px] lg:text-[56px] leading-none tracking-tight num-mono">
                    {c.price}
                  </div>
                  {/* Show tier note only on Single card */}
                  {i === 0 && (
                    <p className="mt-1 text-rct-charcoal text-[12px] font-semibold uppercase tracking-[0.12em]">
                      {t.pricing.tiers.activeLabel}
                    </p>
                  )}
                  <p className="mt-3 text-rct-offblack font-semibold text-[15px]">{c.tag}</p>

                  <ul className="mt-6 space-y-3 flex-1">
                    {c.bullets.map((b, bi) => (
                      <li key={bi} className="flex items-start gap-3 text-rct-charcoal text-[14.5px] leading-[1.5]">
                        <Icon name="check" className="w-[18px] h-[18px] mt-[2px] shrink-0" stroke="#C8102E" />
                        <span>{b}</span>
                      </li>
                    ))}
                  </ul>
                </div>
                <button
                  type="button"
                  onClick={onRegister}
                  className="focus-ring bg-rct-red hover:bg-rct-red-deep text-white font-black uppercase tracking-[0.16em] text-[13px] py-4 inline-flex items-center justify-center gap-2 transition-colors"
                >
                  {t.pricing.ctaCard}
                  <Icon name="arrow-right" className="w-4 h-4" />
                </button>
              </div>
            );
          })}
        </div>

        <p className="reveal mt-8 text-rct-charcoal text-[13px] font-medium max-w-[68ch]">
          {t.pricing.note}
        </p>
      </div>
    </section>
  );
}

/* =========================================================
   Place + Timeline
   ========================================================= */
function Place({ t, content, lang }) {
  const placeKeys = ['date_val', 'time_val', 'venue_val', 'parking_val', 'lockers_val'];
  const rows = t.place.rows.map((row, i) => ({
    ...row,
    v: pt(content, lang, 'place', placeKeys[i], row.v),
  }));
  const timeline = content?.program?.length
    ? content.program.map(p => ({ t: p.time_label, l: lang === 'en' ? (p.label_en || p.label_sk) : p.label_sk }))
    : t.place.timeline;
  const rowIcons = ["calendar", "clock", "pin", "car", "shower"];
  return (
    <section id="place" className="bg-rct-offblack py-10 lg:py-20">
      <div className="max-w-[1440px] mx-auto px-6 lg:px-10">
        <h2 className="reveal text-white font-black uppercase tracking-tight"
            style={{ fontSize: "clamp(2rem, 4.2vw, 3rem)", lineHeight: 1 }}>
          {t.place.h2}
        </h2>

        <div className="mt-10 grid lg:grid-cols-2 gap-10 lg:gap-14">
          <div className="space-y-5">
            {rows.map((r, i) => (
              <div key={i} className="reveal flex items-start gap-5 border-b border-white/10 pb-5">
                <div className="shrink-0 w-11 h-11 border border-rct-red flex items-center justify-center">
                  <Icon name={rowIcons[i]} className="w-5 h-5" stroke="#C8102E" />
                </div>
                <div>
                  <div className="text-white font-black uppercase tracking-[0.14em] text-[12px]">{r.l}</div>
                  <div className="mt-1 text-rct-charcoal-light text-[16px] lg:text-[17px] font-medium leading-[1.4]">{r.v}</div>
                </div>
              </div>
            ))}
          </div>

          <div className="reveal">
            <MapPlaceholder hint={t.place.mapHint} />
          </div>
        </div>

      </div>
    </section>
  );
}

function MapPlaceholder({ hint }) {
  return (
    <div className="relative w-full aspect-[4/3] bg-rct-black border border-white/15 overflow-hidden">
      {/* Faux dark map */}
      <svg viewBox="0 0 400 300" className="absolute inset-0 w-full h-full" preserveAspectRatio="xMidYMid slice" aria-hidden="true">
        <rect width="400" height="300" fill="#0e0e0e" />
        {[...Array(8)].map((_, i) => (
          <line key={`h${i}`} x1="0" y1={i * 40 + 20} x2="400" y2={i * 40 + 20} stroke="#1f1f1f" strokeWidth="1" />
        ))}
        {[...Array(10)].map((_, i) => (
          <line key={`v${i}`} x1={i * 40 + 20} y1="0" x2={i * 40 + 20} y2="300" stroke="#1f1f1f" strokeWidth="1" />
        ))}
        {/* "Roads" */}
        <path d="M0 200 L160 200 L200 150 L400 150" stroke="#2a2a2a" strokeWidth="6" fill="none" />
        <path d="M200 0 L200 150" stroke="#2a2a2a" strokeWidth="5" fill="none" />
        <path d="M0 80 L120 80 L160 120 L400 120" stroke="#252525" strokeWidth="4" fill="none" />
      </svg>

      {/* Pin */}
      <div className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-full flex flex-col items-center">
        <div className="bg-white px-3 py-1.5 mb-2 text-[11px] font-bold uppercase tracking-[0.12em] text-rct-offblack whitespace-nowrap">
          {hint}
        </div>
        <div className="w-5 h-5 bg-white flex items-center justify-center">
          <div className="w-2.5 h-2.5 bg-rct-red" />
        </div>
      </div>

      <div className="absolute bottom-3 right-3 text-white/40 text-[10px] font-mono uppercase tracking-[0.14em]">map · placeholder</div>
    </div>
  );
}

/* =========================================================
   FAQ
   ========================================================= */
function FAQ({ t, content, lang }) {
  const [open, setOpen] = useState(0);
  const items = content?.faq?.length
    ? content.faq.map(f => ({
        q: lang === 'en' ? (f.question_en || f.question_sk) : f.question_sk,
        a: lang === 'en' ? (f.answer_en   || f.answer_sk)   : f.answer_sk,
      }))
    : t.faq.items;
  return (
    <section id="faq" className="bg-white py-10 lg:py-20">
      <div className="max-w-[980px] mx-auto px-6 lg:px-10">
        <h2 className="reveal text-rct-offblack font-black uppercase tracking-tight"
            style={{ fontSize: "clamp(2rem, 4.2vw, 3rem)", lineHeight: 1 }}>
          {t.faq.h2}
        </h2>

        <div className="mt-10">
          {items.map((it, i) => {
            const isOpen = open === i;
            return (
              <div key={i} className="reveal border-b-2 border-rct-red">
                <button
                  onClick={() => setOpen(isOpen ? -1 : i)}
                  className="focus-ring w-full flex items-center justify-between gap-6 py-5 lg:py-6 text-left"
                  aria-expanded={isOpen}
                >
                  <span className="text-rct-offblack font-extrabold text-[17px] lg:text-[20px] leading-[1.3]">
                    {it.q}
                  </span>
                  <span className={`shrink-0 transition-transform duration-300 ${isOpen ? "rotate-45" : ""}`}>
                    <Icon name="plus" className="w-6 h-6" stroke="#C8102E" />
                  </span>
                </button>
                <div
                  className="grid transition-all duration-300 ease-out"
                  style={{ gridTemplateRows: isOpen ? "1fr" : "0fr" }}
                >
                  <div className="overflow-hidden">
                    <p className="pb-6 text-rct-charcoal text-[15px] lg:text-[16.5px] leading-[1.55] font-normal max-w-[72ch]">
                      {it.a}
                    </p>
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </section>
  );
}

/* =========================================================
   Final CTA banner
   ========================================================= */
function FinalCTA({ t, onRegister, total, content, lang }) {
  const ctaH   = pt(content, lang, 'finalcta', 'h',   t.finalCta.h);
  const ctaSub = pt(content, lang, 'finalcta', 'sub', t.finalCta.sub).replace('{cap}', total || '');
  const ctaBtn = pt(content, lang, 'finalcta', 'btn', t.finalCta.btn);
  return (
    <section className="bg-rct-red-deep py-12 lg:py-24 text-center relative overflow-hidden">
      <div className="absolute inset-0 opacity-[0.07] pointer-events-none" aria-hidden="true"
           style={{ backgroundImage: "linear-gradient(90deg, #fff 1px, transparent 1px), linear-gradient(0deg, #fff 1px, transparent 1px)", backgroundSize: "80px 80px" }} />
      <div className="relative max-w-[1100px] mx-auto px-6 lg:px-10">
        <h2 className="reveal text-white font-black uppercase tracking-tight"
            style={{ fontSize: "clamp(2.5rem, 6vw, 4.5rem)", lineHeight: 0.95, letterSpacing: "-0.01em" }}>
          {ctaH}
        </h2>
        <p className="reveal mt-6 text-white font-semibold text-[18px] lg:text-[22px] max-w-[680px] mx-auto leading-[1.4]">
          {ctaSub}
        </p>
        <button
          type="button"
          onClick={onRegister}
          className="reveal focus-ring mt-10 inline-flex items-center justify-center gap-3 bg-white text-rct-offblack hover:bg-rct-offblack hover:text-white font-black uppercase tracking-[0.16em] text-[15px] lg:text-[16px] px-10 py-5 transition-colors"
        >
          {ctaBtn}
          <Icon name="arrow-right" className="w-5 h-5" />
        </button>
        <p className="reveal mt-6 text-white/75 text-[13px] font-normal">{t.finalCta.micro}</p>
      </div>
    </section>
  );
}

/* =========================================================
   Footer
   ========================================================= */
function Footer({ t, onRegister }) {
  return (
    <footer className="bg-rct-offblack text-white">
      <div className="max-w-[1440px] mx-auto px-6 lg:px-10 py-14 lg:py-16">
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-10">
          {/* Column 1 */}
          <div>
            <Logo dark className="h-11" />
            <p className="mt-5 text-rct-charcoal-light text-[14px] leading-[1.5] max-w-[36ch]">
              {t.footer.tagline}
            </p>
            <div className="mt-5 flex gap-3">
              {["instagram", "facebook", "youtube"].map((n) => (
                <a key={n} href="#" aria-label={n} className="focus-ring w-9 h-9 border border-rct-red flex items-center justify-center hover:bg-rct-red transition-colors group">
                  <Icon name={n} className="w-4 h-4" stroke="#C8102E" />
                </a>
              ))}
            </div>
          </div>

          {/* Column 2 */}
          <div>
            <h4 className="text-white font-black uppercase tracking-[0.16em] text-[12px]">{t.footer.contactH}</h4>
            <ul className="mt-5 space-y-3 text-rct-charcoal-light text-[14px]">
              <li>info@redscrew.sk</li>
              <li>+421 901 234 567</li>
              <li>Trhovište 2/A, Kežmarok</li>
            </ul>
          </div>

          {/* Column 3 */}
          <div>
            <h4 className="text-white font-black uppercase tracking-[0.16em] text-[12px]">{t.footer.linksH}</h4>
            <ul className="mt-5 space-y-3 text-rct-charcoal-light text-[14px]">
              {t.footer.links.map((l, i) => (
                <li key={i}><a href="#" className="hover:text-white transition-colors focus-ring">{l}</a></li>
              ))}
            </ul>
          </div>

          {/* Column 4 */}
          <div>
            <h4 className="text-white font-black uppercase tracking-[0.16em] text-[12px]">{t.footer.coachH}</h4>
            <p className="mt-5 text-rct-charcoal-light text-[14px]">{t.footer.coach}</p>
            <a href="https://instagram.com/dejvomiksa" target="_blank" rel="noopener noreferrer" className="text-rct-red text-[13px] font-bold uppercase tracking-[0.12em] focus-ring">@dejvomiksa</a>
            <div className="mt-5">
              <div className="text-rct-charcoal-light text-[12px] font-bold uppercase tracking-[0.16em] mb-3">{t.footer.partners}</div>
              <div className="grid grid-cols-3 gap-2">
                {[1,2,3].map((i) => (
                  <div key={i} className="aspect-[2/1] border border-white/15 flex items-center justify-center text-white/30 text-[10px] font-mono uppercase tracking-[0.14em]">logo</div>
                ))}
              </div>
            </div>
          </div>
        </div>
      </div>

      <div className="border-t border-rct-red">
        <div className="max-w-[1440px] mx-auto px-6 lg:px-10 py-5 text-rct-charcoal-light text-[12px]">
          {t.footer.copy}
        </div>
      </div>
    </footer>
  );
}

/* =========================================================
   Marquee — looping ticker between hero & about
   ========================================================= */
function Marquee({ items, total }) {
  const resolved = items.map(x => x.replace('{cap}', total || ''));
  const seq = [...resolved, ...resolved, ...resolved, ...resolved];
  return (
    <div className="bg-rct-red text-white border-y-[3px] border-rct-offblack overflow-hidden select-none">
      <div className="flex whitespace-nowrap rct-marquee-track py-4">
        {seq.map((x, i) => (
          <span key={i} className="inline-flex items-center gap-6 pr-6 font-black uppercase tracking-[0.18em] text-[15px] lg:text-[17px]">
            {x}
            <span className="inline-block w-2 h-2 bg-white" />
          </span>
        ))}
      </div>
    </div>
  );
}

/* =========================================================
   Aftermovie — big clip-path image reveal + play overlay
   ========================================================= */
function extractYtId(url) {
  if (!url) return '';
  const m = url.match(/(?:shorts\/|v=|embed\/|youtu\.be\/)([a-zA-Z0-9_-]{11})/);
  return m ? m[1] : '';
}

function Aftermovie({ t, content, lang }) {
  const [hovered, setHovered]   = useState(null);
  const [modal, setModal]       = useState(null);
  const [ytActive, setYtActive] = useState([false, false, false]);
  const [isMobile, setIsMobile] = React.useState(() =>
    typeof window !== 'undefined' && window.innerWidth < 640
  );
  const carouselRef = React.useRef(null);

  const shortUrls = [
    content?.texts?.aftermovie?.shorts_1?.sk || '',
    content?.texts?.aftermovie?.shorts_2?.sk || '',
    content?.texts?.aftermovie?.shorts_3?.sk || '',
  ];
  const afterH2  = pt(content, lang, 'aftermovie', 'h2',  t.aftermovie.h2);
  const afterSub = pt(content, lang, 'aftermovie', 'sub', t.aftermovie.sub);

  React.useEffect(() => {
    const check = () => setIsMobile(window.innerWidth < 640);
    window.addEventListener('resize', check);
    return () => window.removeEventListener('resize', check);
  }, []);

  React.useEffect(() => {
    if (!isMobile || !carouselRef.current) return;
    requestAnimationFrame(() => {
      const el = carouselRef.current;
      if (!el || el.children.length < 2) return;
      const card0 = el.children[0];
      const card1 = el.children[1];
      const gap = 12;
      el.scrollLeft = card0.offsetWidth + gap - (el.clientWidth - card1.offsetWidth) / 2;
    });
  }, [isMobile]);

  React.useEffect(() => {
    const onKey = e => { if (e.key === 'Escape') setModal(null); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  React.useEffect(() => {
    document.body.style.overflow = modal ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [modal]);

  return (
    <>
      {/* ── Video modal ── */}
      {modal && (
        <div
          className="fixed inset-0 z-[200] flex items-center justify-center"
          style={{ background: 'rgba(0,0,0,0.90)' }}
          onClick={() => setModal(null)}
        >
          <div
            className="relative"
            style={{
              width: 'min(calc(90vh * 9/16), 92vw)',
              aspectRatio: '9/16',
            }}
            onClick={e => e.stopPropagation()}
          >
            <video
              key={modal}
              src={modal}
              className="w-full h-full object-contain bg-black"
              controls
              autoPlay
              playsInline
            />
            <button
              className="absolute top-3 right-3 w-10 h-10 rounded-full bg-black/70 hover:bg-black/95 text-white flex items-center justify-center text-2xl leading-none transition-colors"
              onClick={() => setModal(null)}
              aria-label="Zavrieť"
            >×</button>
          </div>
        </div>
      )}

      <section id="aftermovie" className="bg-rct-offblack py-10 lg:py-20">
        <div className="max-w-[1440px] mx-auto px-6 lg:px-10">
          <div className="flex items-end justify-between gap-6 flex-wrap reveal">
            <div>
              <p className="text-rct-red font-black uppercase tracking-[0.32em] text-[12px]">{t.aftermovie.kicker}</p>
              <h2 className="mt-3 text-white font-black uppercase tracking-tight"
                  style={{ fontSize: "clamp(2rem, 4.2vw, 3rem)", lineHeight: 1 }}>
                {afterH2}
              </h2>
            </div>
            <p className="text-rct-charcoal-light font-medium text-[15px] lg:text-[17px] max-w-[44ch]">{afterSub}</p>
          </div>

          {/* Mobile: scroll-snap carousel — Desktop: 3-column hover carousel */}
          <div
            ref={carouselRef}
            className="mt-10 reveal flex items-center shorts-carousel"
            style={{
              gap: isMobile ? 12 : 0,
              justifyContent: isMobile ? 'flex-start' : 'center',
              overflowX: isMobile ? 'auto' : 'visible',
              scrollSnapType: isMobile ? 'x mandatory' : 'none',
              WebkitOverflowScrolling: 'touch',
              paddingLeft:  isMobile ? 'calc(50vw - 35vw)' : 0,
              paddingRight: isMobile ? 'calc(50vw - 35vw)' : 0,
              scrollbarWidth: 'none',
              msOverflowStyle: 'none',
            }}
          >
            {shortUrls.map((url, i) => {
              const id          = extractYtId(url);
              const isDirect    = url && !id;
              const active      = isMobile ? true : (hovered === null ? i === 1 : hovered === i);
              const origin      = i === 0 ? 'right center' : i === 2 ? 'left center' : 'center center';
              return (
                <div
                  key={i}
                  className="relative overflow-hidden transition-all duration-500 ease-out flex-shrink-0"
                  style={{
                    width: isMobile ? '70vw' : 'clamp(100px, 22vw, 300px)',
                    aspectRatio: '9/16',
                    scrollSnapAlign: 'center',
                    transform: isMobile ? 'none' : `scale(${active ? 1 : 0.84})`,
                    transformOrigin: origin,
                    filter: isMobile ? 'none' : `brightness(${active ? 1 : 0.4})`,
                    zIndex: active ? 10 : 1,
                    cursor: (isDirect || id) ? 'pointer' : 'default',
                  }}
                  onMouseEnter={() => !isMobile && setHovered(i)}
                  onMouseLeave={() => !isMobile && setHovered(null)}
                  onClick={() => {
                    if (isDirect) setModal(url);
                    else if (id) setYtActive(a => { const n = [...a]; n[i] = true; return n; });
                  }}
                >
                  {id ? (
                    ytActive[i] ? (
                      <iframe
                        src={`https://www.youtube.com/embed/${id}?rel=0&modestbranding=1&autoplay=1`}
                        className="w-full h-full"
                        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                        allowFullScreen
                        title={`Short ${i + 1}`}
                      />
                    ) : (
                      <>
                        <img
                          src={`https://img.youtube.com/vi/${id}/hqdefault.jpg`}
                          className="w-full h-full object-cover"
                          alt={`Short ${i + 1}`}
                          loading="lazy"
                        />
                        <div className="absolute inset-0 flex items-center justify-center pointer-events-none">
                          <div className="w-16 h-16 rounded-full flex items-center justify-center"
                               style={{ background: 'rgba(255,255,255,0.18)', backdropFilter: 'blur(4px)', border: '1px solid rgba(255,255,255,0.25)' }}>
                            <svg viewBox="0 0 24 24" fill="white" style={{width:28,height:28,marginLeft:3}}>
                              <path d="M8 5v14l11-7z"/>
                            </svg>
                          </div>
                        </div>
                      </>
                    )
                  ) : url ? (
                    <>
                      <video
                        src={url}
                        className="w-full h-full object-cover"
                        preload="metadata"
                        playsInline
                        muted
                        onLoadedMetadata={e => { e.target.currentTime = 0.001; }}
                      />
                      <div className="absolute inset-0 flex items-center justify-center pointer-events-none">
                        <div className="w-16 h-16 rounded-full flex items-center justify-center"
                             style={{ background: 'rgba(255,255,255,0.18)', backdropFilter: 'blur(4px)', border: '1px solid rgba(255,255,255,0.25)' }}>
                          <svg viewBox="0 0 24 24" fill="white" style={{width:28,height:28,marginLeft:3}}>
                            <path d="M8 5v14l11-7z"/>
                          </svg>
                        </div>
                      </div>
                    </>
                  ) : (
                    <div className="w-full h-full bg-white/5 flex items-center justify-center border border-white/10">
                      <span className="text-white/25 text-[11px] font-bold uppercase tracking-widest">Short {i + 1}</span>
                    </div>
                  )}
                </div>
              );
            })}
          </div>
        </div>
      </section>
    </>
  );
}

/* =========================================================
   Gallery — asymmetric mosaic + lightbox
   ========================================================= */
const GALLERY_IMAGES = [
  { id: "1517836357463-d25dfeac3438", col: 6, row: 2 },
  { id: "1518611012118-696072aa579a", col: 3, row: 1 },
  { id: "1538805060514-97d9cc17730c", col: 3, row: 1 },
  { id: "1574680096145-d05b474e2155", col: 3, row: 1 },
  { id: "1517963879433-6ad2b056d712", col: 3, row: 1 },
  { id: "1583454110551-21f2fa2afe61", col: 4, row: 2 },
  { id: "1599058917765-a780eda07a3e", col: 4, row: 1 },
  { id: "1571019613454-1cb2f99b2d8b", col: 4, row: 1 },
  { id: "1534438327276-14e5300c3a48", col: 12, row: 1 },
];

function Gallery({ t, content, lang }) {
  const [active, setActive] = useState(-1);
  const dbItems = content?.gallery?.length ? content.gallery : null;
  const galleryItems = dbItems
    ? dbItems.map(g => ({ src: g.url, caption: g.caption }))
    : GALLERY_IMAGES.map((g, i) => ({
        src: `https://images.unsplash.com/photo-${g.id}?auto=format&fit=crop&w=1400&q=80`,
        lbSrc: `https://images.unsplash.com/photo-${g.id}?auto=format&fit=crop&w=2000&q=85`,
        caption: t.gallery.captions[i % t.gallery.captions.length],
      }));
  const total = galleryItems.length;
  const displayed = galleryItems.slice(0, 6);
  const displayCount = displayed.length;

  useEffect(() => {
    if (active < 0) return;
    const onKey = (e) => {
      if (e.key === "Escape") setActive(-1);
      else if (e.key === "ArrowRight") setActive((i) => (i + 1) % displayCount);
      else if (e.key === "ArrowLeft") setActive((i) => (i - 1 + displayCount) % displayCount);
    };
    document.addEventListener("keydown", onKey);
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      document.removeEventListener("keydown", onKey);
      document.body.style.overflow = prevOverflow;
    };
  }, [active, displayCount]);

  return (
    <section id="gallery" className="bg-white pt-10 pb-4 lg:pt-20 lg:pb-6 border-t-[6px] border-rct-red">
      <div className="max-w-[1440px] mx-auto px-6 lg:px-10">
        <div className="flex items-end justify-between gap-6 flex-wrap reveal">
          <div>
            <p className="text-rct-red font-black uppercase tracking-[0.32em] text-[12px]">{t.gallery.kicker}</p>
            <h2 className="mt-3 text-rct-offblack font-black uppercase tracking-tight"
                style={{ fontSize: "clamp(2rem, 4.2vw, 3rem)", lineHeight: 1 }}>
              {pt(content, lang, 'gallery', 'h2', t.gallery.h2)}
            </h2>
            <p className="mt-4 text-rct-charcoal text-[16px] lg:text-[18px] font-medium max-w-[52ch]">{pt(content, lang, 'gallery', 'sub', t.gallery.sub)}</p>
          </div>
          {(() => {
            const label = pt(content, lang, 'gallery', 'event_label', 'Hyrox Simulation Vol.6 | 25.04.2026');
            if (!label) return null;
            const parts = label.split('|');
            return (
              <div className="text-rct-offblack font-black uppercase text-[13px] tracking-[0.18em]">
                <span className="text-rct-red">{parts[0].trim()}</span>
                {parts[1] && <><span className="text-rct-charcoal mx-2">|</span>{parts[1].trim()}</>}
              </div>
            );
          })()}
        </div>

        <div className="mt-10 sm:columns-2 lg:columns-3" style={{columnGap:'12px'}}>
          {displayed.map((g, i) => (
            <button
              key={i}
              type="button"
              onClick={() => setActive(i)}
              className="reveal focus-ring relative overflow-hidden bg-rct-black group block w-full mb-3"
              style={{breakInside:'avoid'}}
              aria-label={g.caption || `Foto ${i + 1}`}
            >
              <img
                src={g.src}
                alt={g.caption || ''}
                className="w-full h-auto block group-hover:scale-105 transition-transform duration-700"
                loading="lazy"
              />
              <div className="absolute inset-0 bg-gradient-to-t from-black/65 via-black/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
              {g.caption && (
                <div className="absolute left-4 right-4 bottom-4 flex items-end justify-between gap-3 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
                  <span className="text-white font-black uppercase text-[12px] tracking-[0.14em]">{g.caption}</span>
                  <span className="shrink-0 w-7 h-7 bg-rct-red flex items-center justify-center">
                    <Icon name="arrow-right" className="w-3.5 h-3.5" stroke="#fff" />
                  </span>
                </div>
              )}
            </button>
          ))}
        </div>

        <div className="mt-8 flex flex-wrap items-center justify-end gap-4">
          <a href={pt(content, lang, 'gallery', 'cta_url', 'https://fotosveet.pixieset.com/hyroxsimulation/')} target="_blank" rel="noopener noreferrer" className="focus-ring inline-flex items-center gap-2 text-rct-offblack hover:text-rct-red font-black uppercase tracking-[0.16em] text-[13px] border-b-2 border-rct-red pb-1 transition-colors">
            {t.gallery.cta}
            <Icon name="arrow-right" className="w-4 h-4" />
          </a>
        </div>
      </div>

      {active >= 0 && (
        <Lightbox
          index={active}
          total={displayCount}
          src={displayed[active]?.lbSrc || displayed[active]?.src}
          onClose={() => setActive(-1)}
          onPrev={() => setActive((i) => (i - 1 + displayCount) % displayCount)}
          onNext={() => setActive((i) => (i + 1) % displayCount)}
          caption={displayed[active]?.caption || ''}
          labels={{ close: t.gallery.close, next: t.gallery.next, prev: t.gallery.prev }}
        />
      )}
    </section>
  );
}

function Lightbox({ index, total, src, onClose, onPrev, onNext, caption, labels }) {
  const count = total || GALLERY_IMAGES.length;
  return (
    <div
      className="lb-backdrop fixed inset-0 z-[100] bg-black/95 flex flex-col items-center justify-center p-4 lg:p-10"
      onClick={onClose}
      role="dialog"
      aria-modal="true"
    >
      <div className="absolute top-5 left-5 lg:top-8 lg:left-10 flex items-center gap-3 text-white font-black uppercase tracking-[0.24em] text-[12px]">
        <span className="w-2 h-2 bg-rct-red" />
        <span className="num-mono text-rct-red">{String(index + 1).padStart(2, "0")}</span>
        <span className="text-white/70 num-mono">/ {String(count).padStart(2, "0")}</span>
      </div>
      <button
        type="button"
        onClick={(e) => { e.stopPropagation(); onClose(); }}
        className="focus-ring absolute top-5 right-5 lg:top-8 lg:right-10 w-11 h-11 border-2 border-white text-white hover:bg-rct-red hover:border-rct-red transition-colors flex items-center justify-center"
        aria-label={labels.close}
      >
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><line x1="6" y1="6" x2="18" y2="18" /><line x1="18" y1="6" x2="6" y2="18" /></svg>
      </button>

      <img
        key={index}
        src={src}
        alt={caption}
        className="lb-img max-h-[78vh] max-w-[92vw] object-contain"
        onClick={(e) => e.stopPropagation()}
      />

      <div className="mt-5 flex items-center gap-3 lg:gap-5" onClick={(e) => e.stopPropagation()}>
        <button
          type="button"
          onClick={onPrev}
          className="focus-ring w-12 h-12 border-2 border-white text-white hover:bg-rct-red hover:border-rct-red transition-colors flex items-center justify-center"
          aria-label={labels.prev}
        >
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><polyline points="14 6 8 12 14 18" /></svg>
        </button>
        <div className="text-white font-bold uppercase tracking-[0.16em] text-[13px] text-center flex-1 min-w-0">{caption}</div>
        <button
          type="button"
          onClick={onNext}
          className="focus-ring w-12 h-12 border-2 border-white text-white hover:bg-rct-red hover:border-rct-red transition-colors flex items-center justify-center"
          aria-label={labels.next}
        >
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><polyline points="10 6 16 12 10 18" /></svg>
        </button>
      </div>
    </div>
  );
}

/* =========================================================
   RaceResult Registration Modal
   ========================================================= */
function RaceResultRegModal({ onClose }) {
  const containerRef = useRef(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const div = containerRef.current;
    if (!div) return;
    loadScript('https://my.raceresult.com/RRRegStart/load.js?lang=sk', 'rr-reg-script').then(() => {
      setLoading(false);
      if (div && window.RRRegStart) {
        div.innerHTML = '';
        const rrs = new window.RRRegStart(div, RR_EVENT_ID, 'registration');
        rrs.ShowTimerLogo = false;
        rrs.ShowInfoText  = false;
      }
    });
    return () => { if (div) div.innerHTML = ''; };
  }, []);

  useEffect(() => {
    document.body.style.overflow = 'hidden';
    const fn = e => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', fn);
    return () => { document.removeEventListener('keydown', fn); document.body.style.overflow = ''; };
  }, []);

  return (
    <div className="fixed inset-0 z-[200] bg-black/90 flex items-start justify-center p-4 overflow-y-auto" onClick={onClose}>
      <div className="relative bg-white w-full max-w-[900px] mt-8 mb-8" onClick={e => e.stopPropagation()}>
        <button onClick={onClose} aria-label="Zavrieť"
          className="absolute top-3 right-3 z-10 w-11 h-11 bg-rct-offblack border border-white/20 hover:bg-rct-red flex items-center justify-center text-white transition-colors">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></svg>
        </button>
        {loading && (
          <div className="flex items-center justify-center py-24 text-rct-charcoal">
            <span className="inline-block w-5 h-5 border-2 border-rct-red/30 border-t-rct-red animate-spin mr-3" />
            Načítavam registráciu…
          </div>
        )}
        <div ref={containerRef} className="min-h-[400px]" />
      </div>
    </div>
  );
}

/* =========================================================
   Participants Section
   ========================================================= */
function Participants({ t }) {
  const containerRef = useRef(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const div = containerRef.current;
    if (!div) return;
    loadScript('https://my.raceresult.com/RRPublish/load.js?lang=sk', 'rr-publish-script').then(() => {
      setLoading(false);
      if (div && window.RRPublish) {
        div.innerHTML = '';
        const rrp = new window.RRPublish(div, RR_EVENT_ID, 'participants');
        rrp.ShowTimerLogo = false;
        rrp.ShowInfoText  = false;
      }
    });
  }, []);

  return (
    <section id="participants" className="bg-[#f5f5f5] py-12 lg:py-24">
      <div className="max-w-[1200px] mx-auto px-6">
        <div className="reveal mb-10">
          <p className="text-rct-red font-black uppercase tracking-[0.28em] text-[11px] mb-3">{t.participants.kicker}</p>
          <h2 className="font-black uppercase text-[28px] sm:text-[36px] lg:text-[48px] leading-[0.92] tracking-tight text-rct-offblack">{t.participants.h2}</h2>
          <p className="mt-4 text-rct-charcoal text-[16px] leading-[1.6] max-w-[520px]">{t.participants.sub}</p>
        </div>
        <div className="bg-white border border-black/8 min-h-[300px]">
          {loading && (
            <div className="flex items-center py-12 px-6 text-rct-charcoal">
              <span className="inline-block w-5 h-5 border-2 border-rct-red/30 border-t-rct-red animate-spin mr-3" />
              Načítavam zoznam…
            </div>
          )}
          <div ref={containerRef} />
        </div>
      </div>
    </section>
  );
}

/* =========================================================
   App
   ========================================================= */
function App() {
  const [lang, setLang] = useState(() => {
    try { return localStorage.getItem("rct.lang") || "sk"; } catch { return "sk"; }
  });
  // Auto-reopen modal if raceresult left query params after its internal navigation
  const [showReg, setShowReg] = useState(() => !!window.location.search);
  const stats   = useStats();
  const content = useContent();

  useEffect(() => {
    document.documentElement.lang = I18N[lang].htmlLang;
    try { localStorage.setItem("rct.lang", lang); } catch {}
  }, [lang]);
  const t = I18N[lang];
  useReveal();

  const handleRegister = useCallback(() => setShowReg(true), []);

  return (
    <div className="bg-white">
      <Nav lang={lang} setLang={setLang} t={t} onRegister={handleRegister} />
      <main>
        <Hero t={t} stats={stats} onRegister={handleRegister} content={content} lang={lang} />
        <Marquee items={t.marquee} total={stats.total} />
        <About t={t} content={content} lang={lang} />
        <Aftermovie t={t} content={content} lang={lang} />
        <Format t={t} />
        <Gallery t={t} content={content} lang={lang} />
        <Pricing t={t} stats={stats} onRegister={handleRegister} />
        <Participants t={t} />
        <Place t={t} content={content} lang={lang} />
        <FAQ t={t} content={content} lang={lang} />
        <FinalCTA t={t} onRegister={handleRegister} total={stats.total} content={content} lang={lang} />
      </main>
      <Footer t={t} onRegister={handleRegister} />
      {showReg && <RaceResultRegModal onClose={() => {
        if (window.location.search) window.history.replaceState({}, '', window.location.pathname);
        setShowReg(false);
      }} />}
    </div>
  );
}

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