HEX
Server: LiteSpeed
System: Linux c7.my-control-panel.com 4.18.0-553.141.2.lve.el8.x86_64 #1 SMP Wed Jul 8 16:10:02 UTC 2026 x86_64
User: bigfreeodds (5956)
PHP: 7.4.33
Disabled: NONE
Upload Files
File: /home/bigfreeodds/public_html/wp-content/public/scores/assets/js/app.js
/* =========================================================
   Football Live Scores — vanilla JS app
   Single-file logic for all pages. Designed to be easy
   to swap to a real football API later (see DATA section).
   ========================================================= */

/* ============ TEAMS ============ */
const TEAMS = {
  MNC:  { name: "Manchester City", short: "MNC",  cls: "t-mnc"  },
  ARS:  { name: "Arsenal",         short: "ARS",  cls: "t-ars"  },
  RMA:  { name: "Real Madrid",     short: "RMA",  cls: "t-rma"  },
  BAR:  { name: "Barcelona",       short: "BAR",  cls: "t-bar"  },
  LBA:  { name: "Las Palmas",      short: "LBA",  cls: "t-lba"  },
  ARG:  { name: "Argentinos",      short: "ARG",  cls: "t-arg"  },
  USB:  { name: "Union Berlin",    short: "USB",  cls: "t-usb"  },
  HBS:  { name: "Hannover",        short: "HBS",  cls: "t-hbs"  },
  SMLH: { name: "St Mirren",       short: "SMLH", cls: "t-smlh" },
  VSC:  { name: "Vasco",           short: "VSC",  cls: "t-vsc"  },
};

/* ============ DATES ============
   Day codes match the date strip on Home: MO TU WE(LIVE) TH FR SA SU.
   This makes data easy to filter without a real calendar. Swap for ISO
   date strings when wiring a real API. */
const DAY_CODES = ["MO","TU","WE","TH","FR","SA","SU"];

/* ============ MATCHES (canonical, with IDs) ============ */
const MATCHES = [
  { id:"m1",  league:"Premier League", day:"WE", home:"MNC", away:"ARS", scoreH:2, scoreA:1, minute:"72'", live:true,  status:"LIVE", redCards:true,  venue:"Etihad",         referee:"M. Oliver", weather:"Clear 14°" },
  { id:"m2",  league:"Premier League", day:"MO", home:"MNC", away:"ARG", scoreH:2, scoreA:1, minute:"FT",  live:false, status:"FT",   redCards:false, venue:"Etihad",         referee:"A. Taylor", weather:"Cloudy 11°" },
  { id:"m3",  league:"Premier League", day:"TU", home:"RMA", away:"BAR", scoreH:3, scoreA:0, minute:"FT",  live:false, status:"FT",   redCards:false, venue:"Bernabeu",       referee:"P. Tierney",weather:"Clear 18°" },
  { id:"m4",  league:"La Liga",        day:"WE", home:"LBA", away:"ARS", scoreH:0, scoreA:0, minute:"72'", live:true,  status:"LIVE", redCards:false, venue:"Gran Canaria",   referee:"J. Sanchez",weather:"Clear 22°" },
  { id:"m5",  league:"La Liga",        day:"TH", home:"RMA", away:"BAR", scoreH:0, scoreA:0, minute:"21:00",live:false, status:"UP",   redCards:false, venue:"Bernabeu",       referee:"D. Diaz",   weather:"Clear 19°" },
  { id:"m6",  league:"Bundesliga",     day:"WE", home:"USB", away:"HBS", scoreH:1, scoreA:1, minute:"82'", live:true,  status:"LIVE", redCards:false, venue:"Stadion an der Alten Försterei", referee:"F. Brych", weather:"Rain 9°" },
  { id:"m7",  league:"Bundesliga",     day:"FR", home:"HBS", away:"USB", scoreH:0, scoreA:0, minute:"19:30",live:false, status:"UP",   redCards:false, venue:"HDI Arena",      referee:"M. Aytekin",weather:"Clear 12°" },
  { id:"m8",  league:"Champions League",day:"TU",home:"BAR", away:"MNC", scoreH:2, scoreA:2, minute:"FT",  live:false, status:"FT",   redCards:true,  venue:"Camp Nou",       referee:"S. Marciniak",weather:"Clear 17°" },
  { id:"m9",  league:"Champions League",day:"SA",home:"ARS", away:"RMA", scoreH:0, scoreA:0, minute:"21:00",live:false, status:"UP",   redCards:false, venue:"Emirates",       referee:"C. Turpin",  weather:"Cloudy 13°" },
  { id:"m10", league:"Premier League", day:"SU", home:"ARS", away:"MNC", scoreH:0, scoreA:0, minute:"17:30",live:false, status:"UP",   redCards:false, venue:"Emirates",       referee:"A. Madley", weather:"Clear 16°" },
  { id:"m11", league:"La Liga",        day:"SA", home:"BAR", away:"LBA", scoreH:0, scoreA:0, minute:"20:00",live:false, status:"UP",   redCards:false, venue:"Camp Nou",       referee:"J. Munuera", weather:"Clear 21°" },
  { id:"m12", league:"Premier League", day:"WE", home:"SMLH",away:"VSC", scoreH:1, scoreA:0, minute:"58'", live:true,  status:"LIVE", redCards:false, venue:"SMiSA Stadium",  referee:"D. England", weather:"Rain 8°" },
];

const matchById = (id) => MATCHES.find(m => m.id === id);
const API_ROOT = "/wp-json/neon-kick/v1";

/* Group helpers */
const matchesByDay = (day) => MATCHES.filter(m => m.day === day);
const liveMatches  = ()    => MATCHES.filter(m => m.live);
const leagueNames = () => ["Premier League","La Liga","Bundesliga","Serie A","Ligue 1","Champions League"];

function leagueSlug(name) {
  return String(name || "").toLowerCase().replace(/\s+/g, "-");
}

async function apiFetch(path) {
  try {
    const res = await fetch(API_ROOT + path, {
      headers: { "Content-Type": "application/json" },
    });
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return await res.json();
  } catch (err) {
    console.warn("[demo] API fallback:", path, err.message);
    return null;
  }
}

/* ============ STANDINGS / SCORERS / LINEUPS / STATS ============ */
const STANDINGS = {
  "Premier League": [
    { team:"MNC", p:18, w:15, d:0, l:1, gd:"+23", pts:73, top:true  },
    { team:"ARS", p:18, w:13, d:3, l:2, gd:"+3",  pts:59, top:true  },
    { team:"USB", p:18, w:13, d:3, l:0, gd:"+0",  pts:36, top:false },
    { team:"HBS", p:18, w:12, d:3, l:5, gd:"+6",  pts:22, top:false },
    { team:"SMLH",p:18, w:11, d:3, l:4, gd:"-7",  pts:19, top:false },
    { team:"VSC", p:18, w:9,  d:2, l:6, gd:"-10", pts:19, top:false },
  ],
  "La Liga": [
    { team:"RMA", p:18, w:16, d:1, l:1, gd:"+30", pts:49, top:true },
    { team:"BAR", p:18, w:14, d:2, l:2, gd:"+22", pts:44, top:true },
    { team:"LBA", p:18, w:9,  d:4, l:5, gd:"+5",  pts:31, top:false },
  ],
  "Bundesliga": [
    { team:"USB", p:18, w:11, d:4, l:3, gd:"+12", pts:37, top:true },
    { team:"HBS", p:18, w:9,  d:5, l:4, gd:"+4",  pts:32, top:false },
  ],
};

const SCORERS = [
  { name:"Haaland",  goals:15, club:"MNC" },
  { name:"Salah",    goals:6,  club:"ARS" },
  { name:"Maair",    goals:3,  club:"RMA" },
  { name:"Vinicius", goals:3,  club:"RMA" },
];

/* Lineup positions (4-3-3 home, 4-2-3-1 away). Names per match get
   personalised below. The pitch coordinates are relative percentages. */
const LINEUP_HOME = [
  { rating:8.4, x:50, y:92, gk:true }, { rating:7.8, x:18, y:72 },
  { rating:8.1, x:38, y:78 }, { rating:7.9, x:62, y:78 }, { rating:8.0, x:82, y:72 },
  { rating:8.6, x:50, y:58 }, { rating:8.4, x:28, y:44 }, { rating:7.7, x:72, y:44 },
  { rating:8.2, x:22, y:22 }, { rating:9.1, x:50, y:14 }, { rating:7.5, x:78, y:22 },
];
const LINEUP_AWAY = [
  { rating:7.9, x:50, y:92, gk:true }, { rating:7.4, x:18, y:72 },
  { rating:8.2, x:38, y:78 }, { rating:8.0, x:62, y:78 }, { rating:7.3, x:82, y:72 },
  { rating:8.1, x:36, y:56 }, { rating:7.8, x:64, y:56 },
  { rating:8.3, x:22, y:36 }, { rating:7.9, x:50, y:36 }, { rating:7.6, x:78, y:36 },
  { rating:7.4, x:50, y:14 },
];
/* Per-team realistic player names (subset for demo) */
const ROSTERS = {
  MNC:  ["Ederson","Walker","Dias","Akanji","Gvardiol","Rodri","De Bruyne","Bernardo","Foden","Haaland","Grealish","Doku","Stones","Kovacic","Alvarez"],
  ARS:  ["Raya","White","Saliba","Gabriel","Zinchenko","Rice","Partey","Saka","Odegaard","Martinelli","Jesus","Trossard","Havertz","Jorginho"],
  RMA:  ["Courtois","Carvajal","Rudiger","Alaba","Mendy","Kroos","Modric","Valverde","Bellingham","Vinicius","Rodrygo","Camavinga","Tchouameni"],
  BAR:  ["Ter Stegen","Kounde","Araujo","Christensen","Balde","De Jong","Pedri","Gavi","Yamal","Lewandowski","Raphinha","Joao Felix","Gundogan"],
  LBA:  ["Valles","Suarez","Mcburnie","Cardona","Alvaro","Loiodice","Munoz","Moleiro","Sandro","Sory Kaba","Marvin"],
  ARG:  ["Gimenez","Romero","Piedrahita","Castro","Lopez","Vera","Redondo","Cabrera","Ferreyra","Avalos","Ortega"],
  USB:  ["Ronnow","Trimmel","Knoche","Doekhi","Roussillon","Khedira","Tousart","Fofana","Haberer","Volland","Behrens"],
  HBS:  ["Zieler","Halstenberg","Borner","Dehm","Neumann","Leopold","Kunze","Voglsammer","Multhaup","Tresoldi","Nielsen"],
  SMLH: ["Carson","Tanser","Strain","Dunne","McMonagle","Erhahon","Olusanya","Boyd","Reid","Mandron","Ayunga"],
  VSC:  ["Leo","Puma","Joao Victor","Robson","Lucas","Hugo Moura","Andrey","Coutinho","Praxedes","Vegetti","Adson"],
};

const STATS_BASE = [
  { name:"Possession", h:61,   a:39,   hLabel:"61%",  aLabel:"39%" },
  { name:"Shots",      h:12,   a:5,    hLabel:"12",   aLabel:"5"   },
  { name:"xG",         h:1.84, a:0.92, hLabel:"1.84", aLabel:"0.92"},
  { name:"Fouls",      h:7,    a:11,   hLabel:"7",    aLabel:"11"  },
  { name:"Corners",    h:6,    a:3,    hLabel:"6",    aLabel:"3"   },
  { name:"Passes",     h:482,  a:311,  hLabel:"482",  aLabel:"311" },
];

/* Per-match stats derived from base + score so each match feels unique */
function statsFor(m) {
  const swing = (m.scoreH - m.scoreA) * 4;
  return STATS_BASE.map(s => {
    const h = Math.max(1, s.h + swing);
    const a = Math.max(1, s.a - swing);
    return { ...s, h, a,
      hLabel: s.name==="Possession" ? `${Math.min(75,Math.max(25,h))}%` : s.hLabel,
      aLabel: s.name==="Possession" ? `${100-Math.min(75,Math.max(25,h))}%` : s.aLabel,
    };
  });
}

function eventsFor(m) {
  const home = TEAMS[m.home].short, away = TEAMS[m.away].short;
  const evs = [];
  for (let i=0; i<m.scoreH; i++) evs.push({ time:`${10+i*22}'`, ic:"⚽", desc:`Goal — ${ROSTERS[m.home][9+i] || ROSTERS[m.home][0]} (${home})` });
  for (let i=0; i<m.scoreA; i++) evs.push({ time:`${18+i*20}'`, ic:"⚽", desc:`Goal — ${ROSTERS[m.away][7+i] || ROSTERS[m.away][0]} (${away})` });
  evs.push({ time:"27'", ic:"🟨", desc:`Yellow card — ${ROSTERS[m.away][5]} (${away})` });
  if (m.redCards) evs.push({ time:"63'", ic:"🟥", desc:`Red card — ${ROSTERS[m.away][6]} (${away})` });
  evs.push({ time:"68'", ic:"🔁", desc:`Substitution — ${ROSTERS[m.home][10]} ON (${home})` });
  return evs.sort((a,b) => parseInt(a.time) - parseInt(b.time));
}

function h2hFor(m) {
  const a = TEAMS[m.home]?.name || m.home;
  const b = TEAMS[m.away]?.name || m.away;
  const home_short = TEAMS[m.home]?.short || m.home;
  const away_short = TEAMS[m.away]?.short || m.away;
  return [
    { date:"12 Mar 2026", home:a, away:b, home_short, away_short, scoreH:1, scoreA:0, comp:m.league },
    { date:"08 Oct 2025", home:b, away:a, home_short:away_short, away_short:home_short, scoreH:0, scoreA:0, comp:m.league },
    { date:"26 Apr 2025", home:a, away:b, home_short, away_short, scoreH:4, scoreA:1, comp:"Cup" },
    { date:"14 Jan 2025", home:b, away:a, home_short:away_short, away_short:home_short, scoreH:2, scoreA:2, comp:m.league },
  ];
}

function setLeagueListSkeleton(container, rows = 6) {
  if (!container) return;
  container.innerHTML = Array.from({ length: rows }, () => `
    <div class="menu-item skeleton-menu" aria-hidden="true">
      <span class="skeleton skeleton-logo"></span>
      <span style="display:flex;flex-direction:column;gap:5px;flex:1;min-width:0;">
        <span class="skeleton skeleton-text skeleton-text--med"></span>
        <span class="skeleton skeleton-text skeleton-text--tiny" style="width:140px;"></span>
      </span>
      <span class="chev skeleton skeleton-chevron"></span>
    </div>`).join('');
}

function setLeagueDetailSkeleton(root) {
  if (!root) return;
  root.innerHTML = `
    <section class="profile-hero" aria-hidden="true">
      <span class="skeleton skeleton-logo skeleton-logo--xl"></span>
      <h2><span class="skeleton skeleton-text skeleton-text--med" style="width:180px;display:inline-block;"></span></h2>
      <p><span class="skeleton skeleton-text skeleton-text--tiny" style="width:90px;display:inline-block;"></span></p>
    </section>
    <div class="card"><div class="card-title">TOP TEAMS</div>
      <div class="table-card">
        ${Array.from({ length: 5 }, () => `
          <div class="table-row skeleton-row" aria-hidden="true">
            <span class="skeleton skeleton-text skeleton-text--tiny"></span>
            <span class="skeleton skeleton-text skeleton-text--med"></span>
            <span class="skeleton skeleton-text skeleton-text--tiny"></span>
            <span class="skeleton skeleton-text skeleton-text--tiny"></span>
            <span class="skeleton skeleton-text skeleton-text--tiny"></span>
            <span class="skeleton skeleton-text skeleton-text--tiny"></span>
            <span class="skeleton skeleton-text skeleton-text--tiny"></span>
            <span class="skeleton skeleton-score skeleton-score--sm"></span>
          </div>`).join('')}
      </div>
    </div>`;
}

function setStandingsSkeleton(tableBody, scorersWrap) {
  if (tableBody) {
    tableBody.innerHTML = Array.from({ length: 5 }, () => `
      <div class="table-row skeleton-row" aria-hidden="true">
        <span class="skeleton skeleton-text skeleton-text--tiny"></span>
        <span class="skeleton skeleton-text skeleton-text--med"></span>
        <span class="skeleton skeleton-text skeleton-text--tiny"></span>
        <span class="skeleton skeleton-text skeleton-text--tiny"></span>
        <span class="skeleton skeleton-text skeleton-text--tiny"></span>
        <span class="skeleton skeleton-text skeleton-text--tiny"></span>
        <span class="skeleton skeleton-text skeleton-text--tiny"></span>
        <span class="skeleton skeleton-score skeleton-score--sm"></span>
      </div>`).join('');
  }
  if (scorersWrap) {
    scorersWrap.innerHTML = Array.from({ length: 4 }, () => `
      <div class="scorer-row" aria-hidden="true">
        <div class="scorer-photo skeleton"></div>
        <div class="pname"><span class="skeleton skeleton-text skeleton-text--med" style="display:inline-block;width:120px;"></span><span class="pmeta"><span class="skeleton skeleton-text skeleton-text--tiny" style="display:inline-block;width:90px;"></span></span></div>
        <span class="gnum"><span class="skeleton skeleton-score skeleton-score--sm"></span></span>
      </div>`).join('');
  }
}

function setMatchListSkeleton(container, rows = 3) {
  if (!container) return;
  container.innerHTML = `
    <div class="match-list skeleton-list">
      ${Array.from({ length: rows }, () => `
        <div class="match-row skeleton-row" aria-hidden="true">
          <span class="skeleton skeleton-dot"></span>
          <div class="home"><span class="skeleton skeleton-logo"></span><span class="skeleton skeleton-text skeleton-text--short"></span></div>
          <div class="center"><span class="skeleton skeleton-pill"></span><span class="skeleton skeleton-text skeleton-text--tiny"></span></div>
          <div class="away"><span class="skeleton skeleton-text skeleton-text--short"></span><span class="skeleton skeleton-logo"></span></div>
          <span class="skeleton skeleton-star"></span>
        </div>`).join('')}
    </div>`;
}

const nextFrame = () => new Promise(resolve => requestAnimationFrame(resolve));

/* ============ AUTH (localStorage demo) ============ */
const AUTH_KEY = "lscores_user";
function getUser()   { try { return JSON.parse(localStorage.getItem(AUTH_KEY) || "null"); } catch { return null; } }
function setUser(u)  { localStorage.setItem(AUTH_KEY, JSON.stringify(u)); }
function clearUser() { localStorage.removeItem(AUTH_KEY); }
function requireLogin(returnUrl) {
  const u = getUser();
  if (!u) { window.location.href = `login.html?redirect=${encodeURIComponent(returnUrl || location.pathname.split("/").pop())}`; return false; }
  return true;
}

/* ============ FAVOURITES ============ */
const FAV_KEY = "lscores_favs";
function getFavs() { try { return JSON.parse(localStorage.getItem(FAV_KEY) || "[]"); } catch { return []; } }
function setFavs(a){ localStorage.setItem(FAV_KEY, JSON.stringify(a)); }
function isFav(id) { return getFavs().includes(id); }
function toggleFav(id) {
  const f = getFavs(); const i = f.indexOf(id);
  if (i>=0) f.splice(i,1); else f.push(id);
  setFavs(f); return i<0;
}
/* Sort matches so favourites bubble to the top. */
function sortByFav(arr) {
  return arr.slice().sort((a, b) => (isFav(b.id)?1:0) - (isFav(a.id)?1:0));
}
/* Re-sort an existing .match-list container so favourites move to top instantly. */
function resortContainer(container) {
  if (!container) return;
  const rows = Array.from(container.querySelectorAll(".match-row[data-id]"));
  rows.sort((a, b) => (isFav(b.dataset.id)?1:0) - (isFav(a.dataset.id)?1:0));
  rows.forEach(r => container.appendChild(r));
}
function resortAllFavs() {
  document.querySelectorAll(".match-list").forEach(resortContainer);
}

/* ============ Helpers ============ */
const CODE_TO_FULL_NAME = {
  SBP: "Sporting CP B",
  LUJ: "Club Luján",
  DDC: "Deportivo D.C.",
  EDS: "Elite Development Squad",
  VS2: "Vasco da Gama 2",
  NOB: "Newell's Old Boys",
  MNC: "Manchester City",
  ARS: "Arsenal",
  RMA: "Real Madrid",
  BAR: "Barcelona",
  LBA: "Las Palmas",
  ARG: "Argentinos Juniors",
  USB: "Union Berlin",
  HBS: "Hannover 96",
  SMLH: "St Mirren",
  STM: "St Mirren",
  VSC: "Vasco da Gama"
};

const CODE_TO_EXPECTED_NAME = {
  MNC: "Manchester City",
  ARS: "Arsenal",
  RMA: "Real Madrid",
  BAR: "Barcelona",
  LBA: "Las Palmas",
  USB: "Union Berlin",
  HBS: "Hannover 96",
  STM: "St Mirren",
  SMLH: "St Mirren",
  VSC: "Vasco da Gama",
  SBP: "Sporting CP B",
  NOB: "Newell's Old Boys",
  ARG: "Argentinos Juniors",
  EDS: "Elite Development Squad",
  VS2: "Vasco da Gama 2"
};

const CLUB_CRESTS = {
  MNC: "https://upload.wikimedia.org/wikipedia/en/e/eb/Manchester_City_FC_badge.svg",
  ARS: "https://upload.wikimedia.org/wikipedia/en/5/53/Arsenal_FC.svg",
  RMA: "https://upload.wikimedia.org/wikipedia/en/5/56/Real_Madrid_CF.svg",
  BAR: "https://upload.wikimedia.org/wikipedia/en/4/47/FC_Barcelona_%28crest%29.svg",
  LBA: "https://upload.wikimedia.org/wikipedia/en/0/09/UD_Las_Palmas_logo.svg",
  USB: "https://upload.wikimedia.org/wikipedia/commons/4/44/1._FC_Union_Berlin_Logo.svg",
  HBS: "https://upload.wikimedia.org/wikipedia/commons/c/cd/Hannover_96_Logo.svg",
  STM: "https://upload.wikimedia.org/wikipedia/en/b/b3/St_Mirren_F.C._crest.svg",
  SMLH: "https://upload.wikimedia.org/wikipedia/en/b/b3/St_Mirren_F.C._crest.svg",
  VSC: "https://upload.wikimedia.org/wikipedia/en/a/a2/CRVascoDaGama.svg",
  SBP: "https://upload.wikimedia.org/wikipedia/en/3/3e/Sporting_CP.svg",
  NOB: "https://upload.wikimedia.org/wikipedia/commons/e/e3/Newell%27s_Old_Boys_logo.svg",
  ARG: "https://upload.wikimedia.org/wikipedia/commons/c/c7/Logo_Argentinos_Juniors.svg",
  EDS: "https://upload.wikimedia.org/wikipedia/en/e/eb/Manchester_City_FC_badge.svg",
  VS2: "https://upload.wikimedia.org/wikipedia/en/a/a2/CRVascoDaGama.svg"
};

const COUNTRY_FLAGS = {
  ARGENTINA: 'ar',
  BRAZIL: 'br',
  BELARUS: 'by',
  AUSTRALIA: 'au',
  CAMEROON: 'cm',
  CANADA: 'ca',
  CHILE: 'cl',
  CHINA: 'cn',
  ESTONIA: 'ee',
  ETHIOPIA: 'et',
  "FAROE ISLANDS": 'fo',
  FINLAND: 'fi',
  ICELAND: 'is',
  LATVIA: 'lv',
  LEBANON: 'lb',
  LITHUANIA: 'lt',
  LUXEMBOURG: 'lu',
  MALAWI: 'mw',
  MOLDOVA: 'md',
  MONGOLIA: 'mn',
  MOROCCO: 'ma',
  NORWAY: 'no',
  PARAGUAY: 'py',
  PERU: 'pe',
  RUSSIA: 'ru',
  "SOUTH KOREA": 'kr',
  "KOREA REPUBLIC": 'kr',
  SWEDEN: 'se',
  SYRIA: 'sy',
  TAJIKISTAN: 'tj',
  URUGUAY: 'uy',
  USA: 'us',
  "UNITED STATES": 'us',
  VENEZUELA: 've',
  ZIMBABWE: 'zw',
  ENGLAND: 'gb-eng',
  FRANCE: 'fr',
  GERMANY: 'de',
  SPAIN: 'es',
  ITALY: 'it',
  PORTUGAL: 'pt',
  NETHERLANDS: 'nl',
  BELGIUM: 'be',
  CROATIA: 'hr',
  MEXICO: 'mx',
  JAPAN: 'jp',
  ALGERIA: 'dz',
  SENEGAL: 'sn',
  "SOUTH AFRICA": 'za',
  AUSTRIA: 'at',
  SWITZERLAND: 'ch',
  TURKEY: 'tr',
  SCOTLAND: 'gb-sct',
  WALES: 'gb-wls',
  "NORTHERN IRELAND": 'gb-nir',
  DENMARK: 'dk',
  GREECE: 'gr',
  UKRAINE: 'ua',
  POLAND: 'pl',
  AZERBAIJAN: 'az',
  SLOVAKIA: 'sk',
  SLOVENIA: 'si',
  ARMENIA: 'am',
  BULGARIA: 'bg',
  ROMANIA: 'ro',
  BOSNIA: 'ba',
  "BOSNIA AND HERZEGOVINA": 'ba',
  ALBANIA: 'al',
  SERBIA: 'rs',
  COLOMBIA: 'co',
  GUATEMALA: 'gt',
  KAZAKHSTAN: 'kz',
  KYRGYZSTAN: 'kg',
  BHUTAN: 'bt'
};

const TEAM_TO_COUNTRY = {
  "PREUSSEN MUNSTER 2": "Germany",
  "PREUSSEN MUNSTER": "Germany",
  "SABAH BAKU": "Azerbaijan",
  "MEDZEV": "Slovakia",
  "ALUMINIJ": "Slovenia",
  "NOAH": "Armenia",
  "MLADOST": "Serbia",
  "ONHAYE": "Belgium",
  "OC CHARLEROI": "Belgium",
  "AMERICA DE CALI": "Colombia",
  "NEW YORK COSMOS": "USA",
  "SANTOS LAGUNA": "Mexico",
  "GUATEMALA U20": "Guatemala",
  "SCHWEINFURT": "Germany",
  "BANIK PRIEVIDZA": "Slovakia",
  "UFA": "Russia",
  "FURTH II": "Germany",
  "GORNIK ZABRZE": "Poland",
  "DROCHTERSEN": "Germany",
  "K. LIERSE S.K.": "Belgium",
  "SARPSBORG 08": "Norway",
  "KAISAR KYZYLORDA": "Kazakhstan",
  "ORDABASY": "Kazakhstan",
  "FC ASTANA": "Kazakhstan",
  "ALTAI": "Kazakhstan",
  "TALANT": "Kyrgyzstan",
  "OZGON": "Kyrgyzstan",
  "CSKA 1948 SOFIA": "Bulgaria",
  "CSKA 1948": "Bulgaria",
  "SOFIA": "Bulgaria",
  "PARTIZAN": "Serbia",
  "FC ARGES": "Romania",
  "ARGES": "Romania",
  "VLLAZNIA": "Albania",
  "PARI NN": "Russia",
  "TEKSTILSHTIK": "Russia",
  "ODENSE": "Denmark",
  "KOLDING IF": "Denmark",
  "KOLDING": "Denmark",
  "AKHMAT GROZNY": "Russia",
  "AKHMAT": "Russia",
  "BORAC BANJA LUKA": "Bosnia",
  "BORAC": "Bosnia",
  "BANJA LUKA": "Bosnia",
  "UNIV. CRAIOVA": "Romania",
  "CRAIOVA": "Romania",
  "POLISSYA ZHYTOMYR": "Ukraine",
  "POLISSYA": "Ukraine",
  "ZHYTOMYR": "Ukraine",
  "CRVENA ZVEZDA": "Serbia",
  "SLOVAN BRATISLAVA": "Slovakia",
  "SLOVAN": "Slovakia",
  "BRATISLAVA": "Slovakia",
  "RKDSV": "Netherlands",
  "WILLEM II": "Netherlands",
  "HANDW WELDERS": "Northern Ireland",
  "LARNE": "Northern Ireland"
};

function normalizeTeamName(name) {
  if (!name) return "";
  let n = name.toLowerCase();
  
  // Remove accents
  n = n.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
  
  // Remove punctuation
  n = n.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g, " ");
  
  // Remove common football suffixes/prefixes
  const suffixes = [
    "fc", "f c", "sc", "s c", "ec", "e c", "ac", "a c",
    "club", "atletico", "deportivo", "cd", "c d", "sd", "s d", "ud", "u d", "ad", "a d",
    "u20", "u23", "reserves", "reserve", "ii", "iii", "b team", "junior", "juniors", "youth",
    "academy", "playoffs", "playoff", "sporting", "sportivo", "real", "union", "association",
    "athletic", "clube", "club de futbol", "club de regatas", "social y deportivo",
    "y deportivo", "social", "b", "2", "ii"
  ];
  
  for (let s of suffixes) {
    const regex = new RegExp(`\\b${s}\\b`, 'gi');
    n = n.replace(regex, "");
  }
  
  // Collapse spaces
  n = n.replace(/\s+/g, " ").trim();
  
  return n;
}

function resolveTeamAlias(name) {
  if (!name) return "";
  let n = name.toUpperCase().trim();
  
  // Standard expansions
  n = n.replace(/\bDIN\.\b/g, "DINAMO");
  n = n.replace(/\bATL\.\b/g, "ATLETICO");
  n = n.replace(/\bDEP\.\b/g, "DEPORTIVO");
  n = n.replace(/\bSP\.\b/g, "SPORTING");
  
  const aliases = {
    "DIN MINSK 2": "DINAMO MINSK 2",
    "ATLETICO GO": "ATLETICO GOIANIENSE",
    "SPORT RECIFE": "SPORT CLUB DO RECIFE",
    "AVAI": "AVAI FC",
    "CEARA": "CEARA SC",
    "GOIAS": "GOIAS EC",
    "PONTE PRETA": "AA PONTE PRETA",
    "NAUTICO": "CLUBE NAUTICO CAPIBARIBE",
    "BATE 2": "BATE BORISOV 2",
    "NEMAN": "NEMAN GRODNO",
    "DNEPR MOGILEV": "DNEPR MOGILEV"
  };
  
  if (aliases[n]) return aliases[n];
  
  let clean = normalizeTeamName(n);
  
  if (window.TEAM_LOGOS_MAPPING) {
    const keys = Object.keys(window.TEAM_LOGOS_MAPPING);
    for (let k of keys) {
      if (normalizeTeamName(k) === clean) {
        return k;
      }
    }
  }
  
  return name;
}

function isValidLogoImage(url, width, height) {
  if (!url) return false;
  if (url === "NO_IMAGE" || url.trim() === "") return false;
  
  // Reject common non-logo patterns in Wikipedia files
  const rejectedKeywords = /stadiu|stade|estadio|estacio|arena|pitch|field|crowd|fans|supporter|view|panoramic|match|versus|playing|action|jersey|shirt|photo|portrait|player|manager|coach|trainer|referee|lineup|group|building|facade|entrance|ground|aerial|skyline|complex|center|centre|complejo|sportpark|park|infobox_football|file:|wiki\/file/i;
  if (rejectedKeywords.test(url)) return false;
  
  // Reject landscape rectangular photos (logos are roughly square or portrait)
  if (width && height) {
    const ratio = width / height;
    if (ratio > 1.25 || ratio < 0.5) return false;
  }
  
  return true;
}

// Logo cache
const wikiCache = {};
try {
  const saved = localStorage.getItem("NK_WIKI_LOGOS");
  if (saved) Object.assign(wikiCache, JSON.parse(saved));
} catch (e) {}

function saveWikiCache() {
  try {
    localStorage.setItem("NK_WIKI_LOGOS", JSON.stringify(wikiCache));
  } catch (e) {}
}

const pendingFetches = {};
window.UNRESOLVED_TEAMS = window.UNRESOLVED_TEAMS || [];

function logUnresolvedTeam(code, teamName) {
  const key = `${code} - ${teamName}`;
  if (!window.UNRESOLVED_TEAMS.includes(key)) {
    window.UNRESOLVED_TEAMS.push(key);
    console.info("[NK Logo System] Unresolved logo:", key);
  }
}

function fetchLogoFromWikipedia(code, teamName, matchContext = {}) {
  const cacheKey = String(teamName || code || "").toUpperCase();
  if (wikiCache[cacheKey] || pendingFetches[cacheKey]) return;
  
  pendingFetches[cacheKey] = true;
  
  const normalized = normalizeTeamName(teamName || code);
  if (!normalized) {
    wikiCache[cacheKey] = "NO_IMAGE";
    saveWikiCache();
    logUnresolvedTeam(code, teamName || code);
    return;
  }
  
  const queryStr = encodeURIComponent(normalized + " football");
  const url = `https://en.wikipedia.org/w/api.php?action=query&generator=search&gsrsearch=${queryStr}&gsrlimit=1&prop=pageimages&piprop=thumbnail&pithumbsize=120&format=json&origin=*`;
  
  fetch(url)
    .then(res => res.json())
    .then(data => {
      let logoUrl = "NO_IMAGE";
      if (data && data.query && data.query.pages) {
        const pages = data.query.pages;
        const pageId = Object.keys(pages)[0];
        if (pageId && pages[pageId].thumbnail) {
          const thumb = pages[pageId].thumbnail;
          if (isValidLogoImage(thumb.source, thumb.width, thumb.height)) {
            logoUrl = thumb.source;
          }
        }
      }
      
      wikiCache[cacheKey] = logoUrl;
      saveWikiCache();
      delete pendingFetches[cacheKey];
      
      if (logoUrl === "NO_IMAGE") {
        logUnresolvedTeam(code, teamName || code);
      }
      
      updateImagesInDOM(code, teamName, logoUrl);
    })
    .catch(err => {
      console.warn("Wikipedia logo fetch error for", teamName, err);
      delete pendingFetches[cacheKey];
    });
}

function updateImagesInDOM(code, teamName, logoUrl) {
  const upperTeam = String(teamName || "").toUpperCase();
  const upperCode = String(code || "").toUpperCase();
  
  document.querySelectorAll(".logo-loading-placeholder").forEach(el => {
    const elTeam = String(el.dataset.team || "").toUpperCase();
    const elCode = String(el.dataset.code || "").toUpperCase();
    
    if (elTeam === upperTeam || elCode === upperCode || resolveTeamAlias(elTeam) === upperTeam || resolveTeamAlias(elCode) === upperCode) {
      const sizeClass = el.classList.contains("lg") ? "lg" : "";
      const cls = el.className.replace("logo-loading-placeholder", "").trim();
      
      let displayUrl = (logoUrl && logoUrl !== "NO_IMAGE") ? logoUrl : null;
      let leagueText = "";
      const leagueSec = el.closest(".league-section");
      if (leagueSec) {
        const nameEl = leagueSec.querySelector(".league-name");
        if (nameEl) leagueText = nameEl.textContent.trim();
      }
      const dummyMatch = { league_name: leagueText };
      const fallbackFlag = getFlagUrlForFallback(el.dataset.code, el.dataset.team, dummyMatch) || "";
      
      if (!displayUrl) {
        displayUrl = fallbackFlag;
      }
      
      if (displayUrl) {
        const img = document.createElement("img");
        img.className = `logo ${sizeClass} logo-img`;
        img.src = displayUrl;
        img.alt = el.dataset.team || el.dataset.code;
        img.loading = "lazy";
        img.setAttribute("data-fallback-flag", displayUrl === fallbackFlag ? "" : fallbackFlag);
        img.setAttribute("data-initials", el.textContent);
        img.onerror = function() {
          handleLogoError(this);
        };
        el.replaceWith(img);
      } else {
        el.outerHTML = `<span class="logo ${sizeClass} ${cls}">${el.textContent}</span>`;
      }
    }
  });
}

function initLogoDebugTool() {
  if (!location.search.includes("debug=logos") && !location.search.includes("debug=1")) return;
  
  const div = document.createElement("div");
  div.id = "logo-debug-panel";
  div.style.cssText = "position:fixed;bottom:10px;right:10px;z-index:9999;background:#0d1117;border:1px solid #ff4757;padding:12px;border-radius:8px;max-width:300px;max-height:200px;overflow-y:auto;font-family:monospace;font-size:11px;color:#ff4757;box-shadow:0 4px 12px rgba(0,0,0,0.5);";
  div.innerHTML = `<strong>Unresolved Logos</strong><div id="logo-debug-list" style="margin-top:6px;">None yet</div>`;
  document.body.appendChild(div);
  
  setInterval(() => {
    const list = window.UNRESOLVED_TEAMS || [];
    const container = document.getElementById("logo-debug-list");
    if (container) {
      container.innerHTML = list.length ? list.map(item => `<div>• ${item}</div>`).join("") : "None yet";
    }
  }, 1000);
}

if (typeof document !== 'undefined') {
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', () => {
      initLogoDebugTool();
    });
  } else {
    initLogoDebugTool();
  }
}

// Load teamLogos.js dynamically on startup
(function() {
  const script = document.createElement("script");
  const isWP = typeof WP_PLUGIN_URL !== 'undefined';
  script.src = isWP ? WP_PLUGIN_URL + "/assets/js/teamLogos.js" : "assets/js/teamLogos.js";
  script.onload = () => {
    if (window.TEAM_LOGOS_MAPPING) {
      document.querySelectorAll(".logo-loading-placeholder").forEach(el => {
        const elTeam = String(el.dataset.team || "").toUpperCase();
        const elCode = String(el.dataset.code || "").toUpperCase();
        
        const expandedTeam = resolveTeamAlias(elTeam).toUpperCase();
        const expandedCode = resolveTeamAlias(elCode).toUpperCase();
        
        const resolvedUrl = window.TEAM_LOGOS_MAPPING[expandedTeam] || window.TEAM_LOGOS_MAPPING[expandedCode];
        if (resolvedUrl) {
          const sizeClass = el.classList.contains("lg") ? "lg" : "";
          const cls = el.className.replace("logo-loading-placeholder", "").trim();
          
          let leagueText = "";
          const leagueSec = el.closest(".league-section");
          if (leagueSec) {
            const nameEl = leagueSec.querySelector(".league-name");
            if (nameEl) leagueText = nameEl.textContent.trim();
          }
          const dummyMatch = { league_name: leagueText };
          const fallbackFlag = getFlagUrlForFallback(el.dataset.code, el.dataset.team, dummyMatch) || "";
          
          const img = document.createElement("img");
          img.className = `logo ${sizeClass} logo-img`;
          img.src = resolvedUrl;
          img.alt = el.dataset.team || el.dataset.code;
          img.loading = "lazy";
          img.setAttribute("data-fallback-flag", fallbackFlag);
          img.setAttribute("data-initials", el.textContent);
          img.onerror = function() {
            handleLogoError(this);
          };
          el.replaceWith(img);
        }
      });
    }
  };
  document.head.appendChild(script);
})();

function getCountryFlag(countryName) {
  if (!countryName) return null;
  const upper = String(countryName).trim().toUpperCase();
  if (COUNTRY_FLAGS[upper]) {
    return `https://flagcdn.com/w40/${COUNTRY_FLAGS[upper]}.png`;
  }
  const keys = Object.keys(COUNTRY_FLAGS);
  for (let k of keys) {
    if (upper.includes(k) || k.includes(upper)) {
      return `https://flagcdn.com/w40/${COUNTRY_FLAGS[k]}.png`;
    }
  }
  return null;
}

function getFlagUrlForFallback(code, teamName, matchContext = {}) {
  const upperCode = String(code || "").toUpperCase();
  const finalName = teamName || code;
  const upperName = String(finalName || "").toUpperCase();
  
  const teamCountryCode = COUNTRY_FLAGS[upperName] || COUNTRY_FLAGS[upperCode];
  if (teamCountryCode) {
    return `https://flagcdn.com/w40/${teamCountryCode.toLowerCase()}.png`;
  }
  
  const mappedCountry = TEAM_TO_COUNTRY[upperName] || TEAM_TO_COUNTRY[upperCode];
  if (mappedCountry) {
    const lCode = COUNTRY_FLAGS[mappedCountry.toUpperCase()];
    if (lCode) {
      return `https://flagcdn.com/w40/${lCode.toLowerCase()}.png`;
    }
  }
  
  const countriesKeys = Object.keys(COUNTRY_FLAGS);
  for (let countryKey of countriesKeys) {
    if (upperName.includes(countryKey)) {
      return `https://flagcdn.com/w40/${COUNTRY_FLAGS[countryKey].toLowerCase()}.png`;
    }
  }
  
  const leagueName = String(matchContext.league_name || matchContext.league || "");
  if (leagueName.includes(":")) {
    const lCountry = leagueName.split(":")[0].trim().toUpperCase();
    const lCode = COUNTRY_FLAGS[lCountry];
    if (lCode) {
      return `https://flagcdn.com/w40/${lCode.toLowerCase()}.png`;
    }
  }
  
  return null;
}

window.handleLogoError = function(img) {
  if (!img) return;
  const fallbackFlag = img.getAttribute("data-fallback-flag");
  if (fallbackFlag && img.src !== fallbackFlag) {
    img.src = fallbackFlag;
    img.setAttribute("data-fallback-flag", "");
  } else {
    const initials = img.getAttribute("data-initials") || "HOM";
    const sizeClass = img.classList.contains("lg") ? "lg" : "";
    const cls = img.className.replace("logo-img", "").replace("logo", "").replace("lg", "").trim();
    img.outerHTML = `<span class="logo ${sizeClass} ${cls}">${initials}</span>`;
  }
};

function resolveTeamVisual(code, teamName, matchContext = {}) {
  const upperCode = String(code || "").toUpperCase();
  const finalName = teamName || code;
  const upperName = String(finalName || "").toUpperCase();
  
  const expandedName = resolveTeamAlias(finalName);
  const expandedCode = resolveTeamAlias(code);
  
  if (window.TEAM_LOGOS_MAPPING) {
    const kName = expandedName.toUpperCase();
    const kCode = expandedCode.toUpperCase();
    if (window.TEAM_LOGOS_MAPPING[kName]) return window.TEAM_LOGOS_MAPPING[kName];
    if (window.TEAM_LOGOS_MAPPING[kCode]) return window.TEAM_LOGOS_MAPPING[kCode];
  }
  
  if (matchContext) {
    const hLogo = matchContext.home_logo || matchContext.homeLogo || 
                  (matchContext.home_team && (typeof matchContext.home_team === 'object' ? (matchContext.home_team.logo || matchContext.home_team.crest) : null)) ||
                  (matchContext.homeTeam && (typeof matchContext.homeTeam === 'object' ? (matchContext.homeTeam.logo || matchContext.homeTeam.crest) : null)) ||
                  matchContext.home_crest || matchContext.homeCrest;
                  
    const aLogo = matchContext.away_logo || matchContext.awayLogo || 
                  (matchContext.away_team && (typeof matchContext.away_team === 'object' ? (matchContext.away_team.logo || matchContext.away_team.crest) : null)) ||
                  (matchContext.awayTeam && (typeof matchContext.awayTeam === 'object' ? (matchContext.awayTeam.logo || matchContext.awayTeam.crest) : null)) ||
                  matchContext.away_crest || matchContext.awayCrest;
                  
    const hCode = String(matchContext.home_short || matchContext.home || matchContext.home_code || "").toUpperCase();
    const aCode = String(matchContext.away_short || matchContext.away || matchContext.away_code || "").toUpperCase();
    
    if (upperCode === hCode && hLogo) return hLogo;
    if (upperCode === aCode && aLogo) return aLogo;
    
    const hName = String(typeof matchContext.home_team === 'string' ? matchContext.home_team : (matchContext.homeTeam || matchContext.homeName || "")).toUpperCase();
    const aName = String(typeof matchContext.away_team === 'string' ? matchContext.away_team : (matchContext.awayTeam || matchContext.awayName || "")).toUpperCase();
    
    if (upperName && upperName === hName && hLogo) return hLogo;
    if (upperName && upperName === aName && aLogo) return aLogo;
  }
  
  if (matchContext.logo) return matchContext.logo;
  if (matchContext.crest) return matchContext.crest;
  if (matchContext.logoUrl) return matchContext.logoUrl;
  
  const expected = CODE_TO_EXPECTED_NAME[upperCode];
  if (expected) {
    const normExpected = normalizeTeamName(expected);
    const normActual = normalizeTeamName(finalName);
    if (!normActual || normActual.includes(normExpected) || normExpected.includes(normActual)) {
      return CLUB_CRESTS[upperCode];
    }
  }
  
  const expectedByName = CODE_TO_EXPECTED_NAME[upperName];
  if (expectedByName && CLUB_CRESTS[upperName]) return CLUB_CRESTS[upperName];
  
  const cachedUrl = wikiCache[upperName] || wikiCache[upperCode];
  if (cachedUrl && cachedUrl !== "NO_IMAGE") {
    return cachedUrl;
  }
  
  const teamCountryCode = COUNTRY_FLAGS[upperName] || COUNTRY_FLAGS[upperCode];
  if (teamCountryCode) {
    return `https://flagcdn.com/w40/${teamCountryCode.toLowerCase()}.png`;
  }
  
  const mappedCountry = TEAM_TO_COUNTRY[upperName] || TEAM_TO_COUNTRY[upperCode];
  if (mappedCountry) {
    const lCode = COUNTRY_FLAGS[mappedCountry.toUpperCase()];
    if (lCode) {
      return `https://flagcdn.com/w40/${lCode.toLowerCase()}.png`;
    }
  }
  
  const countriesKeys = Object.keys(COUNTRY_FLAGS);
  for (let countryKey of countriesKeys) {
    if (upperName.includes(countryKey)) {
      return `https://flagcdn.com/w40/${COUNTRY_FLAGS[countryKey].toLowerCase()}.png`;
    }
  }
  
  const leagueName = String(matchContext.league_name || matchContext.league || "").toUpperCase();
  if (leagueName.includes(":")) {
    const lCountry = leagueName.split(":")[0].trim();
    const lCode = COUNTRY_FLAGS[lCountry];
    if (lCode) {
      return `https://flagcdn.com/w40/${lCode.toLowerCase()}.png`;
    }
  }
  
  return null;
}

function getTeamDisplayAsset(code, teamName, matchContext = {}) {
  return resolveTeamVisual(code, teamName, matchContext);
}

function getTeamDisplayName(team) {
  if (!team) return "";
  if (typeof team === 'string') {
    const upperCode = team.toUpperCase();
    if (typeof TEAMS !== 'undefined' && TEAMS[upperCode]) {
      return getTeamDisplayName(TEAMS[upperCode]);
    }
    if (CODE_TO_FULL_NAME[upperCode]) {
      return CODE_TO_FULL_NAME[upperCode];
    }
    return team;
  }
  const name = team.fullName || team.full_name || team['full name'] ||
               team.name ||
               team.displayName || team.display_name || team['display name'] ||
               team.teamName || team.team_name || team['team name'] ||
               team.shortName || team.short_name || team['short name'] || team.short ||
               team.code ||
               team.abbreviation || team.abbr;
  if (name) {
    if (typeof name === 'string') {
      const upperName = name.toUpperCase();
      if (CODE_TO_FULL_NAME[upperName]) {
        return CODE_TO_FULL_NAME[upperName];
      }
    }
    return name;
  }
  return "";
}

function el(html) { const t=document.createElement("template"); t.innerHTML=html.trim(); return t.content.firstChild; }

function logo(code, big=false, teamName="", matchContext={}) {
  const upperCode = String(code || "").toUpperCase();
  const t = (typeof TEAMS !== 'undefined' && TEAMS[upperCode]) || { short: code, name: teamName || code, cls: "" };
  const initials = t.short || upperCode.slice(0, 3);
  const sizeClass = big ? "lg" : "";
  const finalName = t.name || teamName || code;
  
  const imageUrl = resolveTeamVisual(code, finalName, matchContext);
  const fallbackFlag = getFlagUrlForFallback(code, finalName, matchContext) || "";
  
  if (imageUrl) {
    return `<img class="logo ${sizeClass} logo-img" src="${imageUrl}" alt="${finalName}" loading="lazy" data-fallback-flag="${imageUrl === fallbackFlag ? "" : fallbackFlag}" data-initials="${initials}" onerror="handleLogoError(this)">`;
  }
  
  const cacheKey = String(finalName).toUpperCase();
  if (wikiCache[cacheKey] === "NO_IMAGE") {
    logUnresolvedTeam(code, finalName);
    if (fallbackFlag) {
      return `<img class="logo ${sizeClass} logo-img" src="${fallbackFlag}" alt="${finalName}" loading="lazy" data-fallback-flag="" data-initials="${initials}" onerror="handleLogoError(this)">`;
    }
    return `<span class="logo ${sizeClass} ${t.cls}">${initials}</span>`;
  }
  
  if (wikiCache[cacheKey] === undefined) {
    fetchLogoFromWikipedia(code, finalName, matchContext);
    const escapedName = finalName.replace(/'/g, "\\'");
    return `<span class="logo ${sizeClass} logo-loading-placeholder ${t.cls}" data-team="${escapedName}" data-code="${upperCode}">${initials}</span>`;
  }
  
  if (fallbackFlag) {
    return `<img class="logo ${sizeClass} logo-img" src="${fallbackFlag}" alt="${finalName}" loading="lazy" data-fallback-flag="" data-initials="${initials}" onerror="handleLogoError(this)">`;
  }
  return `<span class="logo ${sizeClass} ${t.cls}">${initials}</span>`;
}

function qs(name) { return new URLSearchParams(location.search).get(name); }

/* ============ Match row ============ */
function renderMatchRow(m, opts={}) {
  const fav = isFav(m.id);
  const homeRaw = m.home_team || m.homeTeam || m.home || m.homeName || m.home_short || m.homeShort || 'HOM';
  const awayRaw = m.away_team || m.awayTeam || m.away || m.awayName || m.away_short || m.awayShort || 'AWY';
  const homeName = getTeamDisplayName(homeRaw);
  const awayName = getTeamDisplayName(awayRaw);
  const homeShort = m.home_short || m.homeShort || m.home || (typeof homeRaw === 'string' ? homeRaw.slice(0, 3) : 'HOM');
  const awayShort = m.away_short || m.awayShort || m.away || (typeof awayRaw === 'string' ? awayRaw.slice(0, 3) : 'AWY');
  
  const node = el(`
    <a class="match-row" href="match-detail.html?id=${m.id}" data-id="${m.id}" data-live="${m.live}">
      <span class="live-dot ${m.live?"":"off"}"></span>
      <div class="home">${logo(homeShort, false, homeName, m)}<span class="name">${homeName}${m.redCards?'<span class="red-card"></span>':''}</span></div>
      <div class="center">
        <span class="score-pill">${m.live || m.status==="FT" ? `${m.scoreH ?? m.home_score ?? 0} - ${m.scoreA ?? m.away_score ?? 0}` : m.minute}</span>
        ${m.live ? `<span class="minute">${m.minute}</span>` : `<small class="meta-time">${m.status==="FT"?"FT":m.minute}</small>`}
      </div>
      <div class="away"><span class="name">${awayName}</span>${logo(awayShort, false, awayName, m)}</div>
      <button class="star ${fav?"active":""}" aria-label="favourite">${fav?"★":"☆"}</button>
    </a>`);

  node.querySelector(".star").addEventListener("click", (e) => {
    e.preventDefault(); e.stopPropagation();
    if (!getUser()) {
      // Gate favourites behind login
      window.location.href = `login.html?redirect=${encodeURIComponent(location.pathname.split("/").pop()+location.search)}`;
      return;
    }
    const active = toggleFav(m.id);
    e.currentTarget.classList.toggle("active", active);
    e.currentTarget.textContent = active ? "★" : "☆";
    // Move favourite rows to the top across all match lists on the page.
    resortAllFavs();
  });
  return node;
}

/* =========================================================
   HOME PAGE
   ========================================================= */
function renderHome() {
  /* Hot matches (live + interesting) — clickable, with carousel */
  const hot = document.getElementById("hot-row");
  if (hot) {
    const hotList = liveMatches().concat(MATCHES.filter(m => !m.live && m.status==="FT")).slice(0, 6);
    hotList.forEach(m => {
      const homeRaw = m.home_team || m.homeTeam || m.home || m.homeName || m.home_short || m.homeShort || 'HOM';
      const awayRaw = m.away_team || m.awayTeam || m.away || m.awayName || m.away_short || m.awayShort || 'AWY';
      const homeName = getTeamDisplayName(homeRaw);
      const awayName = getTeamDisplayName(awayRaw);
      const homeShort = m.home_short || m.homeShort || m.home || (typeof homeRaw === 'string' ? homeRaw.slice(0, 3) : 'HOM');
      const awayShort = m.away_short || m.awayShort || m.away || (typeof awayRaw === 'string' ? awayRaw.slice(0, 3) : 'AWY');
      const card = el(`
        <a class="hot-card" href="match-detail.html?id=${m.id}">
          <div class="team">${logo(homeShort, false, homeName, m)}<div><div class="name">${homeName}</div></div></div>
          <div class="score">${m.scoreH ?? m.home_score ?? 0} - ${m.scoreA ?? m.away_score ?? 0}<small>${m.live ? m.minute : m.status}</small></div>
          <div class="team right"><div><div class="name" style="text-align:right;">${awayName}</div></div>${logo(awayShort, false, awayName, m)}</div>
        </a>`);
      hot.appendChild(card);
    });
    setupHotCarousel(hot);
  }

  /* Initial league sections render — relies on filterByDay() */
  const STATE = { day: "WE", liveOnly: false };
  window._homeState = STATE;
  renderLeagueSections(STATE);

  /* Date strip */
  document.querySelectorAll(".date-chip").forEach(chip => {
    chip.addEventListener("click", () => {
      document.querySelectorAll(".date-chip").forEach(c => c.classList.remove("live"));
      chip.classList.add("live");
      STATE.day = chip.dataset.day || "WE";
      STATE.liveOnly = chip.dataset.day === "LIVE";
      renderLeagueSections(STATE);
    });
  });

  /* ALL LIVE toggle (simple live filter) */
  const allLive = document.getElementById("all-live");
  if (allLive) {
    let on = false;
    allLive.classList.toggle("off", !on);
    allLive.addEventListener("click", () => {
      on = !on; allLive.classList.toggle("off", !on);
      STATE.liveOnly = on; renderLeagueSections(STATE);
    });
  }

  setupLiveRefresh();
}

function renderLeagueSections(state) {
  const list = document.getElementById("leagues-list");
  if (!list) return;
  list.innerHTML = "";

  let pool = state.liveOnly ? liveMatches() : matchesByDay(state.day);
  if (!pool.length) {
    list.appendChild(el(`
      <div class="empty"><div class="ic">📅</div>
        <p>No matches available for this day.<br><small>Try another day from the strip above.</small></p>
      </div>`));
    return;
  }
  /* Group by league, then sort favourites to the top within each league. */
  const byLeague = {};
  pool.forEach(m => { (byLeague[m.league] = byLeague[m.league] || []).push(m); });
  Object.entries(byLeague).forEach(([league, matches]) => {
    const sec = el(`
      <div class="league-section">
        <div class="section-title">
          <div class="league-name"><span class="league-badge"></span>${league}</div>
          <a class="meta" href="standings.html" style="color:var(--accent);">SEE TABLE ›</a>
        </div>
        <div class="match-list" data-league="${league}"></div>
      </div>`);
    const ml = sec.querySelector(".match-list");
    sortByFav(matches).forEach(m => ml.appendChild(renderMatchRow(m)));
    list.appendChild(sec);
  });
}

/* ============ Hot carousel (arrow + dots, swipeable) ============ */
function setupHotCarousel(track) {
  const arrow = document.getElementById("hot-next");
  const dotsWrap = document.getElementById("hot-dots");
  const cards = track.querySelectorAll(".hot-card");
  if (dotsWrap) {
    dotsWrap.innerHTML = "";
    cards.forEach((_, i) => {
      const d = el(`<span class="dot ${i===0?"active":""}"></span>`);
      d.addEventListener("click", () => scrollToCard(i));
      dotsWrap.appendChild(d);
    });
  }
  function scrollToCard(i) {
    const card = cards[i]; if (!card) return;
    track.scrollTo({ left: card.offsetLeft - track.offsetLeft, behavior: "smooth" });
  }
  function activeIndex() {
    const x = track.scrollLeft;
    let best = 0, bestDist = Infinity;
    cards.forEach((c, i) => {
      const d = Math.abs(c.offsetLeft - track.offsetLeft - x);
      if (d < bestDist) { best = i; bestDist = d; }
    });
    return best;
  }
  function syncDots() {
    if (!dotsWrap) return;
    const idx = activeIndex();
    dotsWrap.querySelectorAll(".dot").forEach((d,i) => d.classList.toggle("active", i===idx));
  }
  track.addEventListener("scroll", syncDots, { passive:true });
  if (arrow) arrow.addEventListener("click", () => {
    const next = (activeIndex() + 1) % cards.length;
    scrollToCard(next);
  });
}

/* ============ Live refresh (dummy ticker) ============ */
const REFRESH_INTERVAL_MS = 15000;
let refreshTimer = null;
function tickLive() {
  liveMatches().forEach(m => {
    const cur = parseInt(m.minute, 10) || 0;
    m.minute = Math.min(cur + 1 + Math.floor(Math.random()*2), 90) + "'";
    if (Math.random() < 0.12) (Math.random()<0.5 ? m.scoreH++ : m.scoreA++);
  });
}
function refreshHome() {
  if (window._homeState) renderLeagueSections(window._homeState);
  const status = document.getElementById("refresh-status");
  if (status) status.textContent = "LIVE · " + new Date().toTimeString().slice(0,5);
}
function setupLiveRefresh() {
  const btn = document.getElementById("refresh-btn");
  const doRefresh = (manual=false) => {
    tickLive(); refreshHome();
    if (manual && btn) {
      const svg = btn.querySelector("svg");
      svg && svg.classList.add("spinning");
      setTimeout(() => svg && svg.classList.remove("spinning"), 700);
    }
  };
  if (btn) btn.addEventListener("click", () => doRefresh(true));
  const start = () => { if (!refreshTimer) refreshTimer = setInterval(() => doRefresh(false), REFRESH_INTERVAL_MS); };
  const stop  = () => { if (refreshTimer) { clearInterval(refreshTimer); refreshTimer = null; } };
  start();
  document.addEventListener("visibilitychange", () => document.hidden ? stop() : start());
  refreshHome();
}

/* =========================================================
   FAVOURITES PAGE
   ========================================================= */
function renderFavourites() {
  const wrap = document.getElementById("fav-list");
  if (!wrap) return;
  if (!getUser()) {
    wrap.appendChild(el(`<div class="empty"><div class="ic">🔒</div><p>Please log in to see favourites.<br><a href="login.html" class="btn btn-primary" style="display:inline-block;margin-top:12px;">Log in</a></p></div>`));
    return;
  }
  const favs = getFavs();
  const matches = MATCHES.filter(m => favs.includes(m.id));
  if (!matches.length) {
    wrap.appendChild(el(`<div class="empty"><div class="ic">★</div><p>No favourites yet. Tap a star on any match to add it.</p></div>`));
    return;
  }
  const list = el(`<div class="match-list"></div>`);
  sortByFav(matches).forEach(m => list.appendChild(renderMatchRow(m)));
  wrap.appendChild(list);
}

/* =========================================================
   LEAGUES INDEX
   ========================================================= */
function getAllLeaguesFromMatches(matches) {
  const leaguesMap = {};
  matches.forEach(m => {
    const leagueName = m.league || m.league_name || "Unknown League";
    let country = m.country || "Unknown Country";
    let displayName = leagueName;
    if (leagueName.includes(":")) {
      const parts = leagueName.split(":");
      country = parts[0].trim();
      displayName = parts.slice(1).join(":").trim();
    }
    const leagueId = m.league_id || m.leagueId || `${country}_${displayName}`;
    if (!leaguesMap[leagueId]) {
      leaguesMap[leagueId] = {
        id: leagueId,
        name: displayName,
        fullName: leagueName,
        country: country,
        match_count: 0,
        matches: [],
        hasLiveMatches: false,
        logo: m.league_logo || m.leagueLogo || null,
        flag: m.league_flag || m.leagueFlag || null
      };
    }
    leaguesMap[leagueId].match_count++;
    leaguesMap[leagueId].matches.push(m);
    if (m.live || m.status === "LIVE") {
      leaguesMap[leagueId].hasLiveMatches = true;
    }
  });
  return Object.values(leaguesMap).sort((a, b) => {
    if (a.hasLiveMatches && !b.hasLiveMatches) return -1;
    if (!a.hasLiveMatches && b.hasLiveMatches) return 1;
    const countryCompare = a.country.localeCompare(b.country);
    if (countryCompare !== 0) return countryCompare;
    return a.name.localeCompare(b.name);
  });
}

function groupLeaguesByCountry(leagues) {
  const grouped = {};
  leagues.forEach(l => {
    const c = l.country || "Unknown Country";
    if (!grouped[c]) grouped[c] = [];
    grouped[c].push(l);
  });
  return grouped;
}

function filterLeaguesBySearch(leagues, searchText) {
  if (!searchText) return leagues;
  const query = searchText.toLowerCase().trim();
  return leagues.filter(l => 
    l.name.toLowerCase().includes(query) || 
    l.country.toLowerCase().includes(query) ||
    l.fullName.toLowerCase().includes(query)
  );
}

function getMatchesByLeague(matches, selectedLeague) {
  if (!selectedLeague) return matches;
  return matches.filter(m => {
    const leagueName = m.league || m.league_name || "Unknown League";
    let country = m.country || "Unknown Country";
    let displayName = leagueName;
    if (leagueName.includes(":")) {
      const parts = leagueName.split(":");
      country = parts[0].trim();
      displayName = parts.slice(1).join(":").trim();
    }
    const leagueId = m.league_id || m.leagueId || `${country}_${displayName}`;
    return leagueId === selectedLeague.id;
  });
}

async function renderLeaguesIndex() {
  const wrap = document.getElementById("leagues-index");
  if (!wrap) return;

  // 1. Loading state (Skeleton layout)
  wrap.innerHTML = `
    <div class="leagues-page-layout">
      <div class="leagues-sidebar-col">
        <div class="leagues-search-box">
          <div class="skeleton" style="height:36px; border-radius:18px;"></div>
        </div>
        <div class="leagues-scroll-area">
          <div class="skeleton" style="height:48px; border-radius:8px; margin-bottom:12px;"></div>
          <div class="skeleton" style="height:20px; width:80px; margin-bottom:12px;"></div>
          <div class="skeleton" style="height:40px; border-radius:8px; margin-bottom:8px;"></div>
          <div class="skeleton" style="height:40px; border-radius:8px; margin-bottom:8px;"></div>
        </div>
      </div>
      <div class="leagues-main-col">
        <div class="skeleton" style="height:88px; border-radius:18px; margin-bottom:16px;"></div>
        <div class="skeleton" style="height:72px; border-radius:12px; margin-bottom:8px;"></div>
        <div class="skeleton" style="height:72px; border-radius:12px; margin-bottom:8px;"></div>
      </div>
    </div>`;

  await nextFrame();

  // 2. Fetch matches
  let allMatches = [];
  try {
    const matchesData = await apiFetch("/matches");
    allMatches = matchesData?.matches || MATCHES;
  } catch (err) {
    console.error("Failed to load matches:", err);
    allMatches = MATCHES;
  }

  // Local state for day filtering and searching
  const filterState = {
    day: "WE",
    liveOnly: false,
    searchText: "",
    selectedLeague: null
  };

  function updateView() {
    // A. Filter match pool by day / live status
    let pool = filterState.liveOnly
      ? allMatches.filter(m => m.live || m.status === "LIVE")
      : allMatches.filter(m => m.day === filterState.day);

    // B. Extract leagues from the filtered match pool
    const rawLeagues = getAllLeaguesFromMatches(pool);
    const filteredLeagues = filterLeaguesBySearch(rawLeagues, filterState.searchText);
    const grouped = groupLeaguesByCountry(filteredLeagues);

    // Make sure selected league is still in the pool, otherwise fallback to null (All Leagues)
    if (filterState.selectedLeague) {
      const exists = rawLeagues.find(l => l.id === filterState.selectedLeague.id);
      if (!exists) filterState.selectedLeague = null;
    }

    // C. Render full layout container
    wrap.innerHTML = `
      <div class="leagues-page-layout">
        <!-- Sidebar Column (Desktop/Tablet) -->
        <div class="leagues-sidebar-col">
          <div class="leagues-search-box">
            <input type="text" id="leagues-search-input" placeholder="Search leagues or countries..." value="${filterState.searchText}" />
          </div>
          <div class="leagues-scroll-area">
            <button class="league-row-btn ${!filterState.selectedLeague ? "active" : ""}" id="all-leagues-btn">
              <span class="league-badge" style="font-size: 14px;">🌍</span>
              <span class="league-label-wrap">
                <strong>All Leagues</strong>
                <small>${pool.length} matches available</small>
              </span>
            </button>
            <div id="leagues-list-container"></div>
          </div>
        </div>

        <!-- Mobile Filter Selector -->
        <div class="leagues-mobile-filter-bar">
          <select id="leagues-mobile-dropdown" class="leagues-mobile-select">
            <option value="all" ${!filterState.selectedLeague ? "selected" : ""}>🌍 All Leagues (${pool.length})</option>
            ${rawLeagues.map(l => `
              <option value="${l.id}" ${filterState.selectedLeague && filterState.selectedLeague.id === l.id ? "selected" : ""}>
                ${l.country}: ${l.name} (${l.match_count})
              </option>`).join("")}
          </select>
        </div>

        <!-- Main Content Area -->
        <div class="leagues-main-col">
          <!-- Date filter chips -->
          <div class="leagues-date-strip">
            ${["WE", "MO", "TU", "TH", "FR", "SA", "SU"].map(d => {
              const label = d === "WE" ? "Today" : d;
              return `<button class="date-chip ${filterState.day === d && !filterState.liveOnly ? "active" : ""}" data-day="${d}">${label}</button>`;
            }).join("")}
            <button class="date-chip ${filterState.liveOnly ? "active" : ""}" data-day="LIVE">🔴 Live Now</button>
          </div>

          <!-- Selected League Card -->
          <div class="selected-league-header-card">
            <div class="selected-league-title" id="current-league-title">
              ${filterState.selectedLeague ? `${filterState.selectedLeague.country}: ${filterState.selectedLeague.name}` : "ALL LEAGUES"}
            </div>
            <div class="selected-league-meta" id="current-league-meta">
              ${filterState.selectedLeague ? `${filterState.selectedLeague.match_count} matches available` : `Showing all ${pool.length} matches`}
            </div>
          </div>

          <!-- Matches List -->
          <div class="match-list" id="leagues-matches-container"></div>
        </div>
      </div>`;

    // D. Render Grouped Leagues into Sidebar
    const listContainer = document.getElementById("leagues-list-container");
    if (listContainer) {
      if (Object.keys(grouped).length === 0) {
        listContainer.innerHTML = `<div style="padding: 20px; text-align: center; color: var(--profile-muted, #a3a3a3); font-size: 13px;">No leagues found.</div>`;
      } else {
        Object.entries(grouped).forEach(([country, leagues]) => {
          // Add country header
          const head = document.createElement("div");
          head.className = "leagues-country-header";
          head.textContent = country;
          listContainer.appendChild(head);

          // Add league rows
          leagues.forEach(l => {
            const btn = document.createElement("button");
            btn.className = `league-row-btn ${filterState.selectedLeague && filterState.selectedLeague.id === l.id ? "active" : ""}`;
            
            // Get proper flag image
            const flagUrl = getCountryFlag(l.country) || getCountryFlag(country);
            let badgeHTML = `<span class="league-badge" style="font-size: 12px;">🏆</span>`;
            if (flagUrl) {
              badgeHTML = `<img class="league-badge" src="${flagUrl}" alt="${l.country}" />`;
            }
            
            btn.innerHTML = `
              ${badgeHTML}
              <span class="league-label-wrap">
                <strong>${l.name}</strong>
                <small>${l.match_count} match${l.match_count > 1 ? "es" : ""}</small>
              </span>`;
            
            btn.addEventListener("click", () => {
              filterState.selectedLeague = l;
              updateView();
            });
            listContainer.appendChild(btn);
          });
        });
      }
    }

    // E. Render Selected Matches
    const matchesContainer = document.getElementById("leagues-matches-container");
    if (matchesContainer) {
      const activeMatches = getMatchesByLeague(pool, filterState.selectedLeague);
      if (activeMatches.length === 0) {
        matchesContainer.innerHTML = `
          <div class="empty" style="padding: 40px;">
            <div class="ic">🏆</div>
            <p>No matches available for this selection.</p>
          </div>`;
      } else {
        sortByFav(activeMatches).forEach(m => {
          matchesContainer.appendChild(renderMatchRow(m));
        });
      }
    }

    // F. Setup Event Listeners
    // Search input listener
    const searchInput = document.getElementById("leagues-search-input");
    if (searchInput) {
      searchInput.addEventListener("input", e => {
        filterState.searchText = e.target.value;
        const rawL = getAllLeaguesFromMatches(pool);
        const filteredL = filterLeaguesBySearch(rawL, filterState.searchText);
        const newGrouped = groupLeaguesByCountry(filteredL);
        
        if (listContainer) {
          listContainer.innerHTML = "";
          if (Object.keys(newGrouped).length === 0) {
            listContainer.innerHTML = `<div style="padding: 20px; text-align: center; color: var(--profile-muted, #a3a3a3); font-size: 13px;">No leagues found.</div>`;
          } else {
            Object.entries(newGrouped).forEach(([country, leagues]) => {
              const head = document.createElement("div");
              head.className = "leagues-country-header";
              head.textContent = country;
              listContainer.appendChild(head);

              leagues.forEach(l => {
                const btn = document.createElement("button");
                btn.className = `league-row-btn ${filterState.selectedLeague && filterState.selectedLeague.id === l.id ? "active" : ""}`;
                const flagUrl = getCountryFlag(l.country) || getCountryFlag(country);
                let badgeHTML = `<span class="league-badge" style="font-size: 12px;">🏆</span>`;
                if (flagUrl) {
                  badgeHTML = `<img class="league-badge" src="${flagUrl}" alt="${l.country}" />`;
                }
                btn.innerHTML = `
                  ${badgeHTML}
                  <span class="league-label-wrap">
                    <strong>${l.name}</strong>
                    <small>${l.match_count} match${l.match_count > 1 ? "es" : ""}</small>
                  </span>`;
                btn.addEventListener("click", () => {
                  filterState.selectedLeague = l;
                  updateView();
                });
                listContainer.appendChild(btn);
              });
            });
          }
        }
      });
    }

    // "All Leagues" button listener
    const allLeaguesBtn = document.getElementById("all-leagues-btn");
    if (allLeaguesBtn) {
      allLeaguesBtn.addEventListener("click", () => {
        filterState.selectedLeague = null;
        updateView();
      });
    }

    // Mobile dropdown selection change listener
    const mobileDropdown = document.getElementById("leagues-mobile-dropdown");
    if (mobileDropdown) {
      mobileDropdown.addEventListener("change", e => {
        const val = e.target.value;
        if (val === "all") {
          filterState.selectedLeague = null;
        } else {
          const found = rawLeagues.find(l => l.id === val);
          if (found) filterState.selectedLeague = found;
        }
        updateView();
      });
    }

    // Date/live chips click listeners
    document.querySelectorAll(".leagues-date-strip .date-chip").forEach(btn => {
      btn.addEventListener("click", () => {
        const day = btn.getAttribute("data-day");
        if (day === "LIVE") {
          filterState.liveOnly = true;
        } else {
          filterState.liveOnly = false;
          filterState.day = day;
        }
        updateView();
      });
    });
  }

  // Initial draw
  updateView();
}

/* =========================================================
   MATCH DETAIL — fully dynamic from ?id=
   ========================================================= */
function renderMatchDetail() {
  const id = qs("id") || "m1";
  const m = matchById(id) || MATCHES[0];
  const homeName = getTeamDisplayName(TEAMS[m.home]?.name || m.home);
  const awayName = getTeamDisplayName(TEAMS[m.away]?.name || m.away);

  /* Hero */
  const hero = document.getElementById("match-hero");
  if (hero) {
    hero.innerHTML = `
      <div class="team-block">${logo(m.home, true, homeName, m)}<span class="name">${homeName.toUpperCase()}</span></div>
      <div class="big-score">${m.scoreH}-${m.scoreA}<div style="font-size:11px;color:var(--accent);font-weight:700;letter-spacing:1.5px;margin-top:4px;">${m.live?m.minute:m.status}</div></div>
      <div class="team-block">${logo(m.away, true, awayName, m)}<span class="name">${awayName.toUpperCase()}</span></div>`;
  }
  const title = document.getElementById("match-title");
  if (title) title.textContent = `${m.league.toUpperCase()} | ${homeName} vs ${awayName}`;
  document.title = `${homeName} vs ${awayName} — Live Scores`;

  /* Stats */
  const stats = document.getElementById("stats-list");
  if (stats) {
    statsFor(m).forEach(s => {
      const total = s.h + s.a || 1;
      stats.appendChild(el(`
        <div class="stat-row">
          <div class="label"><span>${s.hLabel}</span><span class="name">${s.name}</span><span>${s.aLabel}</span></div>
          <div class="bar"><div class="fill-h" style="width:${s.h/total*100}%"></div><div class="fill-a" style="width:${s.a/total*100}%"></div></div>
        </div>`));
    });
  }

  /* H2H */
  const h2hList = document.getElementById("h2h-list");
  if (h2hList) {
    h2hFor(m).forEach(g => {
      const homeShort = g.home_short || g.homeShort || g.home || 'HOM';
      const awayShort = g.away_short || g.awayShort || g.away || 'AWY';
      const hName = getTeamDisplayName(g.home_team || g.homeTeam || g.home || g.home_short);
      const aName = getTeamDisplayName(g.away_team || g.awayTeam || g.away || g.away_short);
      const dummyMatch = {
        ...g,
        league_name: g.comp || g.league_name || g.league || m?.league || ''
      };
      h2hList.appendChild(el(`
        <div class="match-row" style="cursor:default;">
          <span class="live-dot off"></span>
          <div class="home">${logo(homeShort, false, hName, dummyMatch)}<span class="name">${hName}</span></div>
          <div class="center"><span class="score-pill">${g.scoreH ?? g.home_score ?? 0} - ${g.scoreA ?? g.away_score ?? 0}</span><small class="meta-time">${g.date}</small></div>
          <div class="away"><span class="name">${aName}</span>${logo(awayShort, false, aName, dummyMatch)}</div><span></span>
        </div>`));
    });
  }

  /* Events */
  const evWrap = document.getElementById("events-list");
  if (evWrap) eventsFor(m).forEach(ev => evWrap.appendChild(el(`
    <div class="event-row"><span class="time">${ev.time}</span><span class="ic">${ev.ic}</span><span class="desc">${ev.desc}</span></div>`)));

  /* Lineups inside detail tab */
  const linePanel = document.getElementById("panel-lineups");
  if (linePanel) {
    linePanel.innerHTML = `
      <div class="card"><div class="card-title">FORMATIONS — 4-3-3 vs 4-2-3-1</div>
        <div class="formations">
          <div><div class="formation-label">${homeName}</div><div class="mini-pitch" id="pitch-home-d"></div></div>
          <div><div class="formation-label">${awayName}</div><div class="mini-pitch" id="pitch-away-d"></div></div>
        </div>
        <div style="text-align:center;margin-top:14px;"><a class="btn btn-secondary" href="lineups.html">FULL LINEUPS PAGE ›</a></div>
      </div>`;
    paintLineup(document.getElementById("pitch-home-d"), LINEUP_HOME, ROSTERS[m.home], false);
    paintLineup(document.getElementById("pitch-away-d"), LINEUP_AWAY, ROSTERS[m.away], true);
  }

  /* Match info: venue/referee/weather */
  const info = document.getElementById("match-info");
  if (info) info.innerHTML = `
    <div class="col"><small>VENUE</small><strong>${m.venue}</strong></div>
    <div class="col"><small>REFEREE</small><strong>${m.referee}</strong></div>
    <div class="col"><small>WEATHER</small><strong>${m.weather}</strong></div>`;

  /* Predictions panel content (no betting) */
  const pred = document.getElementById("panel-predictions");
  if (pred) pred.innerHTML = `
    <div class="card"><div class="card-title">PREDICTION (ANALYTICAL)</div>
      <div class="analysis-block"><h4>Form</h4><p>${homeName} unbeaten in last 5; ${awayName} mixed form away.</p></div>
      <div class="analysis-block"><h4>Tactical edge</h4><p>Home press creates xG advantage in middle third.</p></div>
      <div class="analysis-block"><h4>Likely outcome</h4><p>Tight contest with narrow home win projection. <em>Informational, not betting.</em></p></div>
    </div>`;

  /* Odds panel — placeholder only, no real odds, no gambling */
  const odds = document.getElementById("panel-odds");
  if (odds) odds.innerHTML = `
    <div class="card"><div class="card-title">MARKET INSIGHT (PLACEHOLDER)</div>
      <p style="color:var(--muted);font-size:13px;margin-bottom:10px;">Indicative model probabilities — no betting markets shown.</p>
      <div class="odds-info">
        <div class="col"><small>HOME WIN</small><strong>48%</strong></div>
        <div class="col"><small>DRAW</small><strong>27%</strong></div>
        <div class="col"><small>AWAY WIN</small><strong>25%</strong></div>
      </div>
    </div>`;

  /* Standings tab — league table for this match's competition.
     Easy to swap for `GET /standings?league=...` later. */
  const standPanel = document.getElementById("panel-standings");
  if (standPanel) {
    const rows = STANDINGS[m.league] || STANDINGS["Premier League"] || [];
    standPanel.innerHTML = `
      <div class="card"><div class="card-title">${m.league.toUpperCase()} — TABLE</div>
        <div class="table-card">
          <div class="table-head">
            <span>POS</span><span class="team">TEAM</span><span>P</span><span>W</span><span>D</span><span>L</span><span>GD</span><span>PTS</span>
          </div>
          ${rows.map((row, i) => {
            const rowTeamName = getTeamDisplayName(TEAMS[row.team]?.name || row.team);
            const isActive = row.team === m.home || row.team === m.away || rowTeamName === homeName || rowTeamName === awayName;
            return `
              <div class="table-row ${row.top?"top":""} ${isActive?"active":""}">
                <span class="num">${i+1}</span>
                <span class="team">${logo(row.team, false, rowTeamName, m)}<span>${rowTeamName}</span></span>
                <span class="num">${row.p}</span><span class="num">${row.w}</span>
                <span class="num">${row.d}</span><span class="num">${row.l}</span>
                <span class="num">${row.gd}</span><span class="pts">${row.pts}</span>
              </div>`;
          }).join("")}
        </div>
        <div style="text-align:center;margin-top:14px;"><a class="btn btn-secondary" href="standings.html">FULL STANDINGS ›</a></div>
      </div>`;
  }

  /* Fixtures tab — upcoming matches in this league.
     Easy to swap for `GET /fixtures?league=...&status=UP`. */
  const fxPanel = document.getElementById("panel-fixtures");
  if (fxPanel) {
    const upcoming = MATCHES.filter(x => x.league === m.league && x.status === "UP");
    fxPanel.innerHTML = `<div class="card"><div class="card-title">${m.league.toUpperCase()} — UPCOMING</div><div class="match-list" id="mfx-list" style="padding:0;"></div></div>`;
    const c = fxPanel.querySelector("#mfx-list");
    if (upcoming.length) sortByFav(upcoming).forEach(x => c.appendChild(renderMatchRow(x)));
    else c.innerHTML = `<div class="empty" style="padding:24px;"><p>No upcoming fixtures in ${m.league}.</p></div>`;
  }

  /* Results tab — finished matches in this league.
     Easy to swap for `GET /fixtures?league=...&status=FT`. */
  const rsPanel = document.getElementById("panel-results");
  if (rsPanel) {
    const done = MATCHES.filter(x => x.league === m.league && x.status === "FT");
    rsPanel.innerHTML = `<div class="card"><div class="card-title">${m.league.toUpperCase()} — RESULTS</div><div class="match-list" id="mrs-list" style="padding:0;"></div></div>`;
    const c = rsPanel.querySelector("#mrs-list");
    if (done.length) sortByFav(done).forEach(x => c.appendChild(renderMatchRow(x)));
    else c.innerHTML = `<div class="empty" style="padding:24px;"><p>No recent results in ${m.league}.</p></div>`;
  }

  /* Tabs */
  document.querySelectorAll(".tab").forEach(t => {
    t.addEventListener("click", () => {
      const target = t.dataset.tab;
      document.querySelectorAll(".tab").forEach(x => x.classList.toggle("active", x===t));
      document.querySelectorAll(".tab-panel").forEach(p => p.classList.toggle("active", p.id === `panel-${target}`));
    });
  });
}

function paintLineup(pitch, lineup, roster, away) {
  if (!pitch) return;
  lineup.forEach((p, i) => {
    pitch.appendChild(el(`
      <div class="player ${away?'away':''} ${p.gk?'gk':''}" style="left:${p.x}%; top:${away ? 100 - p.y : p.y}%;">
        <div class="shirt"></div><div class="pname">${roster[i] || "Player"}</div><div class="prating">${p.rating}</div>
      </div>`));
  });
}

/* =========================================================
   LINEUPS standalone page
   ========================================================= */
function renderLineups() {
  const id = qs("id") || "m1";
  const m = matchById(id) || MATCHES[0];
  const home = document.getElementById("pitch-home");
  const away = document.getElementById("pitch-away");
  paintLineup(home, LINEUP_HOME, ROSTERS[m.home], false);
  paintLineup(away, LINEUP_AWAY, ROSTERS[m.away], true);

  const subsH = document.getElementById("subs-home");
  const subsA = document.getElementById("subs-away");
  if (subsH) ROSTERS[m.home].slice(11).forEach(n => subsH.appendChild(el(`<div class="sub-row">${logo(m.home, false, TEAMS[m.home]?.name || m.home, m)}<span class="pname">${n}</span></div>`)));
  if (subsA) ROSTERS[m.away].slice(11).forEach(n => subsA.appendChild(el(`<div class="sub-row">${logo(m.away, false, TEAMS[m.away]?.name || m.away, m)}<span class="pname">${n}</span></div>`)));

  const openBtn = document.getElementById("open-predictions");
  const modal = document.getElementById("predictions-modal");
  const closeBtn = document.getElementById("close-predictions");
  if (openBtn && modal) {
    openBtn.addEventListener("click", () => modal.classList.add("open"));
    closeBtn && closeBtn.addEventListener("click", () => modal.classList.remove("open"));
    modal.addEventListener("click", e => { if (e.target===modal) modal.classList.remove("open"); });
  }
}

/* =========================================================
   STANDINGS
   ========================================================= */
async function renderStandings() {
  const dropdown = document.getElementById("comp-dropdown");
  const dropdownList = document.getElementById("comp-list");
  const tableBody = document.getElementById("standings-body");
  const scorersWrap = document.getElementById("scorers-list");
  setStandingsSkeleton(tableBody, scorersWrap);
  const data = await apiFetch("/standings?league=all");
  const standings = data?.standings || STANDINGS;
  const keys = Object.keys(standings);
  let current = keys[0] || "Premier League";

  function paint() {
    document.getElementById("comp-current").textContent = current.toUpperCase();
    tableBody.innerHTML = "";
    (standings[current] || []).forEach((row, i) => {
      tableBody.appendChild(el(`
        <div class="table-row ${row.top?"top":""}">
          <span class="num">${i+1}</span>
          <span class="team">${logo(row.team)}<span>${row.team_name || row.team}</span></span>
          <span class="num">${row.p}</span><span class="num">${row.w}</span>
          <span class="num">${row.d}</span><span class="num">${row.l}</span>
          <span class="num">${row.gd}</span><span class="pts">${row.pts}</span>
        </div>`));
    });
  }
  if (dropdown && dropdownList) {
    dropdownList.innerHTML = "";
    keys.forEach(name => {
      const b = el(`<button>${name}</button>`);
      b.addEventListener("click", () => { current = name; paint(); dropdown.classList.remove("open"); });
      dropdownList.appendChild(b);
    });
    dropdown.addEventListener("click", () => dropdown.classList.toggle("open"));
  }
  if (tableBody) paint();
  if (scorersWrap) {
    scorersWrap.innerHTML = "";
    SCORERS.forEach(s => scorersWrap.appendChild(el(`
      <div class="scorer-row"><div class="scorer-photo" style="background:transparent;border:none;">${logo(s.club, false, getTeamDisplayName(s.club))}</div>
        <div class="pname">${s.name}<span class="pmeta">${TEAMS[s.club]?.name||""} · goals</span></div>
        <span class="gnum">${s.goals}</span></div>`)));
  }
}

/* =========================================================
   DESKTOP SHELL — sidebar + right rail
   ========================================================= */
const NAV_ITEMS = [
  { href:"index.html",         ic:"⌂",  label:"Home",          page:"home" },
  { href:"live.html",          ic:"▶",  label:"Live",          page:"live" },
  { href:"favourites.html",    ic:"★",  label:"Favourites",    page:"favourites" },
  { href:"leagues.html",       ic:"🏆", label:"Leagues",       page:"leagues" },
  { href:"search.html",        ic:"🔎", label:"Search",        page:"search" },
  { href:"notifications.html", ic:"🔔", label:"Notifications", page:"notifications" },
  { href:"profile.html",       ic:"◉",  label:"Profile",       page:"profile" },
];
const SECONDARY_NAV = [
  { href:"dashboard.html", ic:"▦", label:"Dashboard", page:"dashboard" },
  { href:"settings.html",  ic:"⚙",  label:"Settings",  page:"settings" },
  { href:"about.html",     ic:"🛈", label:"About",     page:"about" },
  { href:"contact.html",   ic:"✉",  label:"Contact",   page:"contact" },
];
function isDesktop() { return window.matchMedia("(min-width: 700px)").matches; }

function buildSidebar(activePage) {
  const u = getUser();
  const items = NAV_ITEMS.map(n => `<a class="nav-item ${n.page===activePage?"active":""}" href="${n.href}"><span class="ic">${n.ic}</span><span>${n.label}</span></a>`).join("");
  const sec = SECONDARY_NAV.map(n => `<a class="nav-item ${n.page===activePage?"active":""}" href="${n.href}"><span class="ic">${n.ic}</span><span>${n.label}</span></a>`).join("");
  const authBlock = u
    ? `<a class="nav-item" href="dashboard.html"><span class="ic">👤</span><span>${u.name}</span></a>
       <button class="nav-item" id="side-logout" type="button"><span class="ic">⎋</span><span>Logout</span></button>`
    : `<a class="nav-item" href="login.html"><span class="ic">→</span><span>Log in</span></a>
       <a class="nav-item" href="register.html"><span class="ic">+</span><span>Sign up</span></a>`;
  return `<aside class="side-nav">
    <div class="brand"><span class="logo-mark">⚽</span><span>LIVE SCORES</span></div>
    ${items}
    <div class="nav-section">More</div>
    ${sec}
    <div class="nav-section">Account</div>
    ${authBlock}
    <button class="theme-toggle" id="theme-toggle"><span>🌓</span><span>Toggle theme</span></button>
  </aside>`;
}
function buildRightRail() {
  const trending = liveMatches().slice(0,4).map(m => {
    const homeShort = m.home_short || m.homeShort || m.home || 'HOM';
    const awayShort = m.away_short || m.awayShort || m.away || 'AWY';
    const homeName = getTeamDisplayName(m.home_team || m.homeTeam || m.home || m.home_short);
    const awayName = getTeamDisplayName(m.away_team || m.awayTeam || m.away || m.away_short);
    return `
      <a class="rail-item" href="match-detail.html?id=${m.id}">${logo(homeShort, false, homeName, m)}
        <div class="meta">${homeName} vs ${awayName}<small>${m.minute} · LIVE</small></div>
        <span class="val">${m.scoreH ?? m.home_score ?? 0}-${m.scoreA ?? m.away_score ?? 0}</span></a>`;
  }).join("");
  const upcoming = MATCHES.filter(m => m.status==="UP").slice(0,4).map(m => {
    const homeShort = m.home_short || m.homeShort || m.home || 'HOM';
    const awayShort = m.away_short || m.awayShort || m.away || 'AWY';
    const homeName = getTeamDisplayName(m.home_team || m.homeTeam || m.home || m.home_short);
    const awayName = getTeamDisplayName(m.away_team || m.awayTeam || m.away || m.away_short);
    return `
      <a class="rail-item" href="match-detail.html?id=${m.id}">${logo(homeShort, false, homeName, m)}
        <div class="meta">${homeName} vs ${awayName}<small>${m.league_name || m.league}</small></div>
        <span class="val" style="color:var(--text);font-size:11px;">${m.minute}</span></a>`;
  }).join("");
  const scorers = SCORERS.map(s => {
    const clubName = getTeamDisplayName(s.club);
    return `
      <a class="rail-item" href="player-detail.html"><div class="scorer-photo" style="background:transparent;border:none;">${logo(s.club, false, getTeamDisplayName(s.club))}</div>
        <div class="meta">${s.name}<small>${clubName}</small></div>
        <span class="val">${s.goals}</span></a>`;
  }).join("");
  return `<aside class="side-rail">
    <div class="rail-card"><h3>Trending Live <a class="more" href="live.html">SEE ALL</a></h3>
      <div class="rail-list">${trending || '<div class="empty" style="padding:14px;"><p>No live matches</p></div>'}</div></div>
    <div class="rail-card"><h3>Upcoming <a class="more" href="fixtures.html">SEE ALL</a></h3><div class="rail-list">${upcoming}</div></div>
    <div class="rail-card"><h3>Top Scorers <a class="more" href="standings.html">SEE ALL</a></h3><div class="rail-list">${scorers}</div></div>
  </aside>`;
}
function buildHeader() {
  const u = getUser();
  const profileHref = u ? "dashboard.html" : "login.html";
  const profileLabel = u ? (u.name || "Account") : "Log in";
  const initials = u ? (u.name||"U").split(/\s+/).map(s=>s[0]).join("").slice(0,2).toUpperCase() : "?";
  return `<header class="site-header" role="banner">
    <a class="site-brand" href="index.html" aria-label="Live Scores home">
      <span class="logo-mark">⚽</span><span class="brand-text">LIVE SCORES</span>
    </a>
    <form class="site-search" role="search" id="header-search-form" action="search.html" method="get">
      <span class="search-ic" aria-hidden="true">🔎</span>
      <input id="header-search-input" name="q" type="search" autocomplete="off"
             placeholder="Search teams, leagues, matches…" aria-label="Search" />
    </form>
    <a class="site-account" href="${profileHref}" id="header-account" aria-label="${profileLabel}">
      <span class="avatar-sm">${initials}</span>
      <span class="account-label">${profileLabel}</span>
    </a>
  </header>`;
}
function buildLayout() {
  const page = document.body.dataset.page;
  const app = document.querySelector(".app"); if (!app) return;
  const railPages = ["home","live","favourites","fixtures","results","leagues","notifications","dashboard"];
  // Desktop header (logo / search / account) — only injected on desktop layout.
  const headerHTML = buildHeader();
  const layout = document.createElement("div");
  layout.className = "layout";
  layout.innerHTML = buildSidebar(page);
  app.parentNode.insertBefore(layout, app);
  // Insert the header above the layout so it spans full width.
  layout.insertAdjacentHTML("beforebegin", `<div class="site-header-wrap">${headerHTML}</div>`);
  layout.appendChild(app);
  if (railPages.includes(page)) layout.insertAdjacentHTML("beforeend", buildRightRail());
  const tog = document.getElementById("theme-toggle");
  if (tog) tog.addEventListener("click", toggleTheme);
  const lo = document.getElementById("side-logout");
  if (lo) lo.addEventListener("click", () => { clearUser(); window.location.href = "index.html"; });
  // Header search: submit redirects to search.html?q=...; renderSearch will pick it up.
  const sf = document.getElementById("header-search-form");
  const si = document.getElementById("header-search-input");
  if (sf && si) {
    // Prefill if already on search page with a query.
    const q = qs("q"); if (q) si.value = q;
    sf.addEventListener("submit", (e) => {
      const term = (si.value || "").trim();
      if (!term) { e.preventDefault(); si.focus(); }
    });
  }
}

/* ============ Theme ============ */
function applyTheme() {
  const saved = localStorage.getItem("lscores_theme") || "dark";
  document.body.classList.toggle("light", saved === "light");
}
function toggleTheme() {
  const cur = localStorage.getItem("lscores_theme") || "dark";
  localStorage.setItem("lscores_theme", cur==="dark"?"light":"dark");
  applyTheme();
}

/* =========================================================
   LIVE / FIXTURES / RESULTS pages
   ========================================================= */
function renderLive() {
  const wrap = document.getElementById("live-list"); if (!wrap) return;
  const live = liveMatches();
  if (!live.length) { wrap.appendChild(el(`<div class="empty"><div class="ic">⚽</div><p>No live matches right now.</p></div>`)); return; }
  const list = el(`<div class="match-list"></div>`);
  sortByFav(live).forEach(m => list.appendChild(renderMatchRow(m)));
  wrap.appendChild(list);
}
async function renderFixtures() {
  const wrap = document.getElementById("fixtures-list"); if (!wrap) return;
  setMatchListSkeleton(wrap, 4);
  const data = await apiFetch("/fixtures");
  const upcoming = data?.matches?.length ? data.matches : MATCHES.filter(m => m.status==="UP");
  if (!upcoming.length) { wrap.innerHTML = ""; wrap.appendChild(el(`<div class="empty"><div class="ic">📅</div><p>No upcoming fixtures.</p></div>`)); return; }
  wrap.innerHTML = "";
  const groups = {};
  upcoming.forEach(m => { (groups[m.league_name || m.league]=groups[m.league_name || m.league]||[]).push(m); });
  Object.entries(groups).forEach(([league, arr]) => {
    const sec = el(`<div class="league-section"><div class="section-title"><div class="league-name"><span class="league-badge"></span>${league}</div></div><div class="match-list"></div></div>`);
    const ml = sec.querySelector(".match-list");
    sortByFav(arr).forEach(m => ml.appendChild(renderMatchRow(m)));
    wrap.appendChild(sec);
  });
}
async function renderResults() {
  const wrap = document.getElementById("results-list"); if (!wrap) return;
  setMatchListSkeleton(wrap, 4);
  const data = await apiFetch("/results");
  const finished = data?.matches?.length ? data.matches : MATCHES.filter(m => m.status==="FT");
  if (!finished.length) { wrap.innerHTML = ""; wrap.appendChild(el(`<div class="empty"><div class="ic">📊</div><p>No results to show.</p></div>`)); return; }
  wrap.innerHTML = "";
  const groups = {};
  finished.forEach(m => { (groups[m.league_name || m.league]=groups[m.league_name || m.league]||[]).push(m); });
  Object.entries(groups).forEach(([league, arr]) => {
    const sec = el(`<div class="league-section"><div class="section-title"><div class="league-name"><span class="league-badge"></span>${league}</div></div><div class="match-list"></div></div>`);
    const ml = sec.querySelector(".match-list");
    sortByFav(arr).forEach(m => ml.appendChild(renderMatchRow(m)));
    wrap.appendChild(sec);
  });
}

/* =========================================================
   SEARCH
   ========================================================= */
async function renderSearch() {
  const input = document.getElementById("search-input");
  const out = document.getElementById("search-results");
  if (!input || !out) return;
  const teamItems = Object.entries(TEAMS).map(([code,t]) => ({ type:"Team", label:t.name, href:`team-detail.html?team=${code}` }));
  const leagueItems = leagueNames().map(n => ({ type:"League", label:n, href:`league-detail.html?name=${encodeURIComponent(n)}` }));
  const matchItems = MATCHES.map(m => ({ type:"Match", label:`${TEAMS[m.home].name} vs ${TEAMS[m.away].name}`, href:`match-detail.html?id=${m.id}` }));
  const all = [...teamItems, ...leagueItems, ...matchItems];
  async function paint(q) {
    const term = q.trim().toLowerCase();
    out.innerHTML = "";
    if (!term) {
      setLeagueListSkeleton(out, 4);
    } else {
      setLeagueListSkeleton(out, 4);
    }
    const data = await apiFetch("/search?q=" + encodeURIComponent(term));
    const matches = data?.results?.length ? data.results : (term ? all.filter(i => i.label.toLowerCase().includes(term)) : all.slice(0, 12));
    out.innerHTML = "";
    if (!matches.length) { out.appendChild(el(`<div class="empty"><div class="ic">🔎</div><p>No results for "${q}"</p></div>`)); return; }
    matches.slice(0, 40).forEach(i => {
      const kind = String(i.type || "").toLowerCase();
      const href = i.href || (kind === "match" ? `match-detail.html?id=${i.id}` : kind === "league" ? `league-detail.html?name=${encodeURIComponent(i.label || i.name || i.id)}` : `team-detail.html?team=${encodeURIComponent(i.id || i.label || "")}`);
      out.appendChild(el(`
        <a class="menu-item" href="${href}"><span class="ic">${kind==="team"?"👥":kind==="league"?"🏆":"⚽"}</span>
          <span>${i.label || i.name || i.title}<small style="display:block;color:var(--muted);font-size:11px;">${i.meta || i.type || kind}</small></span>
          <span class="chev">›</span></a>`));
    });
  }
  input.addEventListener("input", e => paint(e.target.value));
  const initial = qs("q") || "";
  if (initial) input.value = initial;
  await paint(initial);
}

/* =========================================================
   NOTIFICATIONS
   ========================================================= */
async function renderNotifications() {
  const wrap = document.getElementById("notif-list"); if (!wrap) return;
  const shell = document.getElementById("notif-content");
  const skeleton = document.getElementById("notif-skeleton");
  if (shell || skeleton) await nextFrame();
  const items = [
    { ic:"⚽", title:"Goal! Haaland scores for Manchester City", time:"2 min ago" },
    { ic:"🟥", title:"Red card for Partey (Arsenal)", time:"12 min ago" },
    { ic:"🏆", title:"La Liga standings updated", time:"1 hr ago" },
    { ic:"📅", title:"Real Madrid vs Barcelona starts in 1 hour", time:"1 hr ago" },
    { ic:"★",  title:"Match you favourited is now live", time:"3 hr ago" },
  ];
  items.forEach(n => wrap.appendChild(el(`
    <div class="menu-item"><span class="ic">${n.ic}</span>
      <span>${n.title}<small style="display:block;color:var(--muted);font-size:11px;margin-top:2px;">${n.time}</small></span></div>`)));
  if (shell) shell.hidden = false;
  skeleton?.remove();
}

/* =========================================================
   TEAM / PLAYER / LEAGUE-DETAIL
   ========================================================= */
function renderTeamDetail() {
  const code = qs("team") || "MNC"; const t = TEAMS[code] || TEAMS.MNC;
  const root = document.getElementById("team-root"); if (!root) return;
  const recent = MATCHES.filter(m => m.home===code || m.away===code).slice(0,6);
  root.innerHTML = `
    <section class="profile-hero"><span class="logo lg ${t.cls}">${t.short}</span><h2>${t.name}</h2><p>Club profile · Squad · Fixtures</p></section>
    <div class="profile-stats">
      <div class="stat"><strong>18</strong><span>PLAYED</span></div>
      <div class="stat"><strong>15</strong><span>WINS</span></div>
      <div class="stat"><strong>73</strong><span>POINTS</span></div>
    </div>
    <div class="card"><div class="card-title">RECENT FORM</div>
      <div style="display:flex;gap:8px;">${["W","W","D","W","W"].map(r => `<span class="badge ${r==="W"?"live":r==="D"?"ht":"ft"}" style="padding:6px 10px;">${r}</span>`).join("")}</div>
    </div>
    <div class="card"><div class="card-title">RECENT MATCHES</div><div id="team-matches" class="match-list" style="padding:0;"></div></div>`;
  const ml = document.getElementById("team-matches");
  sortByFav(recent).forEach(m => ml.appendChild(renderMatchRow(m)));
}
function renderPlayerDetail() {
  const root = document.getElementById("player-root"); if (!root) return;
  root.innerHTML = `
    <section class="profile-hero"><div class="avatar">H</div><h2>Haaland</h2><p>Forward · Manchester City · #9</p></section>
    <div class="profile-stats">
      <div class="stat"><strong>15</strong><span>GOALS</span></div>
      <div class="stat"><strong>4</strong><span>ASSISTS</span></div>
      <div class="stat"><strong>9.1</strong><span>RATING</span></div>
    </div>`;
}
async function renderLeagueDetail() {
  const root = document.getElementById("league-root"); if (!root) return;
  const leagueName = qs("name") || qs("id") || "Premier League";
  setLeagueDetailSkeleton(root);

  const leaguesData = await apiFetch("/leagues");
  const leagues = leaguesData?.leagues?.length ? leaguesData.leagues : leagueNames().map((n, i) => ({
    id: leagueSlug(n),
    name: n,
    country: ["England","Spain","Germany","Italy","France","Europe"][i],
    color: ["6f42c1","ff8c00","d8232a","2bd86b","1f4f8b","ffd400"][i],
  }));

  const selected = leagues.find(l => {
    const key = String(leagueName).toLowerCase();
    const countryName = String((l.country || "") + ":" + (l.name || "")).toLowerCase();
    return String(l.lookup_key || "").toLowerCase() === key
      || String(l.id || "").toLowerCase() === key
      || String(l.sub_id || "").toLowerCase() === key
      || String(l.name || "").toLowerCase() === key
      || String(l.league_name || "").toLowerCase() === key
      || countryName === key;
  }) || leagues.find(l => String(l.name || "").toLowerCase() === String(leagueName).toLowerCase());

  const displayName = selected?.league_name || selected?.name || leagueName;
  const displayLabel = selected ? (selected.league_name || selected.name || displayName) : displayName;
  const standData = await apiFetch(`/standings?league=${encodeURIComponent(displayName)}`);
  const standings = standData?.standings || STANDINGS;
  const rows = standings[displayName] || standings["Premier League"] || STANDINGS[displayName] || STANDINGS["Premier League"] || [];
  const matchesData = await apiFetch(`/league/${encodeURIComponent(selected?.lookup_key || selected?.id || selected?.sub_id || selected?.name || displayName)}`);
  const matches = selected?.matches?.length
    ? selected.matches
    : matchesData?.matches?.length
      ? matchesData.matches
    : MATCHES.filter(m => String(m.league).toLowerCase() === String(displayName).toLowerCase());

  if (!selected && !rows.length && !matches.length) {
    root.innerHTML = `<div class="empty"><div class="ic">🏆</div><p>No league data available.</p></div>`;
    return;
  }

  root.innerHTML = `
    <section class="profile-hero">
      <span class="league-badge" style="width:64px;height:64px;border-radius:50%;background:linear-gradient(135deg,#6f42c1,#2bd86b);"></span>
      <h2>${displayLabel}</h2><p>${selected?.country || "Top division"}</p>
    </section>
    <div class="card"><div class="card-title">TOP TEAMS</div>
      ${rows.slice(0,5).length ? rows.slice(0,5).map((row, i) => `
        <div class="table-row ${row.top?"top":""}">
          <span class="num">${i+1}</span><span class="team">${logo(row.team, false, row.team_name || TEAMS[row.team]?.name || row.team)}<span>${row.team_name || TEAMS[row.team]?.name || row.team}</span></span>
          <span class="num">${row.p}</span><span class="num">${row.w}</span><span class="num">${row.d}</span>
          <span class="num">${row.l}</span><span class="num">${row.gd}</span><span class="pts">${row.pts}</span>
        </div>`).join("") : `<div class="empty" style="padding:24px;"><p>No standings available for this league.</p></div>`}
    </div>
    <div class="card"><div class="card-title">RECENT MATCHES</div><div class="match-list" id="league-detail-matches" style="padding:0;"></div></div>`;

  const list = document.getElementById("league-detail-matches");
  if (list) {
    if (!matches.length) list.innerHTML = `<div class="empty" style="padding:24px;"><p>No matches available for this league.</p></div>`;
    else sortByFav(matches.slice(0, 6)).forEach(m => list.appendChild(renderMatchRow(m)));
  }
}

/* =========================================================
   AUTH PAGES (Login / Register / Forgot / Dashboard)
   ========================================================= */
async function renderLogin() {
  const form = document.getElementById("login-form"); if (!form) return;
  const shell = document.getElementById("login-content");
  const skeleton = document.getElementById("login-skeleton");
  if (shell || skeleton) await nextFrame();
  if (shell) shell.hidden = false;
  skeleton?.remove();
  form.addEventListener("submit", e => {
    e.preventDefault();
    const fd = new FormData(form);
    const email = (fd.get("email")||"").toString().trim();
    if (!email) return;
    const name = email.split("@")[0].replace(/\W/g," ").replace(/\b\w/g, c => c.toUpperCase()) || "User";
    setUser({ email, name, joined: new Date().toISOString() });
    const redirect = qs("redirect") || "dashboard.html";
    window.location.href = redirect;
  });
}
async function renderRegister() {
  const form = document.getElementById("register-form"); if (!form) return;
  const shell = document.getElementById("register-content");
  const skeleton = document.getElementById("register-skeleton");
  if (shell || skeleton) await nextFrame();
  if (shell) shell.hidden = false;
  skeleton?.remove();
  form.addEventListener("submit", e => {
    e.preventDefault();
    const fd = new FormData(form);
    const name = (fd.get("name")||"").toString().trim();
    const email = (fd.get("email")||"").toString().trim();
    const pass = fd.get("password"); const confirm = fd.get("confirm");
    const err = document.getElementById("reg-error");
    if (!name || !email || !pass) { err.textContent = "Please complete all fields."; return; }
    if (pass !== confirm)         { err.textContent = "Passwords do not match.";      return; }
    setUser({ name, email, joined: new Date().toISOString() });
    window.location.href = "dashboard.html";
  });
}
async function renderForgot() {
  const form = document.getElementById("forgot-form"); if (!form) return;
  const shell = document.getElementById("forgot-content");
  const skeleton = document.getElementById("forgot-skeleton");
  if (shell || skeleton) await nextFrame();
  if (shell) shell.hidden = false;
  skeleton?.remove();
  form.addEventListener("submit", e => {
    e.preventDefault();
    document.getElementById("forgot-msg").textContent = "If an account exists, we've sent reset instructions.";
  });
}
async function renderDashboard() {
  if (!requireLogin("dashboard.html")) return;
  const u = getUser();
  const root = document.getElementById("dash-root"); if (!root) return;
  const shell = document.getElementById("dashboard-content");
  const skeleton = document.getElementById("dashboard-skeleton");
  if (shell || skeleton) await nextFrame();
  const initials = (u.name || "U").split(/\s+/).map(s=>s[0]).join("").slice(0,2).toUpperCase();
  const favs = getFavs();
  const favMatches = MATCHES.filter(m => favs.includes(m.id)).slice(0,4);
  root.innerHTML = `
    <section class="profile-hero">
      <div class="avatar">${initials}</div>
      <h2>${u.name}</h2><p>${u.email} · Joined ${new Date(u.joined).toLocaleDateString()}</p>
    </section>
    <div class="profile-stats">
      <div class="stat"><strong>${favs.length}</strong><span>FAVOURITES</span></div>
      <div class="stat"><strong>3</strong><span>LEAGUES</span></div>
      <div class="stat"><strong>${liveMatches().length}</strong><span>LIVE NOW</span></div>
    </div>
    <div class="card"><div class="card-title">YOUR FAVOURITE MATCHES</div>
      <div id="dash-favs" class="match-list" style="padding:0;"></div>
    </div>
    <div class="menu-list">
      <a class="menu-item" href="edit-profile.html"><span class="ic">✎</span><span>Edit profile</span><span class="chev">›</span></a>
      <a class="menu-item" href="favourites.html"><span class="ic">★</span><span>My favourites</span><span class="chev">›</span></a>
      <a class="menu-item" href="followed-leagues.html"><span class="ic">🏆</span><span>Followed leagues</span><span class="chev">›</span></a>
      <a class="menu-item" href="notification-settings.html"><span class="ic">🔔</span><span>Notification settings</span><span class="chev">›</span></a>
      <a class="menu-item" href="account-settings.html"><span class="ic">⚙</span><span>Account settings</span><span class="chev">›</span></a>
      <button class="menu-item" id="logout-btn" type="button" style="width:100%;text-align:left;"><span class="ic">⎋</span><span>Logout</span><span class="chev">›</span></button>
    </div>`;
  const dashFavs = document.getElementById("dash-favs");
  if (favMatches.length) favMatches.forEach(m => dashFavs.appendChild(renderMatchRow(m)));
  else dashFavs.innerHTML = `<div class="empty" style="padding:24px;"><p>No favourites yet. Star matches from <a href="index.html" style="color:var(--accent);">Home</a>.</p></div>`;
  document.getElementById("logout-btn").addEventListener("click", () => { clearUser(); window.location.href = "index.html"; });
  if (shell) shell.hidden = false;
  skeleton?.remove();
}

async function renderEditProfile() {
  if (!requireLogin("edit-profile.html")) return;
  const shell = document.getElementById("edit-profile-content");
  const skeleton = document.getElementById("edit-profile-skeleton");
  if (shell || skeleton) await nextFrame();
  if (shell) shell.hidden = false;
  skeleton?.remove();
  const u = getUser();
  const form = document.getElementById("edit-form"); if (!form) return;
  form.querySelector('[name="name"]').value = u.name;
  form.querySelector('[name="email"]').value = u.email;
  form.addEventListener("submit", e => {
    e.preventDefault();
    const fd = new FormData(form);
    setUser({ ...u, name: fd.get("name").toString(), email: fd.get("email").toString() });
    document.getElementById("edit-msg").textContent = "Profile saved.";
  });
}
async function renderFollowedLeagues() {
  if (!requireLogin("followed-leagues.html")) return;
  const wrap = document.getElementById("followed-list"); if (!wrap) return;
  const shell = document.getElementById("followed-content");
  const skeleton = document.getElementById("followed-skeleton");
  if (shell || skeleton) await nextFrame();
  const KEY = "lscores_followed_leagues";
  const followed = JSON.parse(localStorage.getItem(KEY) || "[]");
  ["Premier League","La Liga","Bundesliga","Serie A","Ligue 1","Champions League"].forEach(name => {
    const isOn = followed.includes(name);
    const row = el(`
      <div class="menu-item">
        <span class="league-badge"></span><span>${name}</span>
        <button class="btn ${isOn?"btn-secondary":"btn-primary"}" style="margin-left:auto;padding:6px 12px;font-size:12px;">${isOn?"FOLLOWING":"FOLLOW"}</button>
      </div>`);
    row.querySelector("button").addEventListener("click", e => {
      const list = JSON.parse(localStorage.getItem(KEY) || "[]");
      const i = list.indexOf(name);
      if (i>=0) list.splice(i,1); else list.push(name);
      localStorage.setItem(KEY, JSON.stringify(list));
      const on = i<0;
      e.currentTarget.textContent = on ? "FOLLOWING" : "FOLLOW";
      e.currentTarget.className = `btn ${on?"btn-secondary":"btn-primary"}`;
      e.currentTarget.style.cssText = "margin-left:auto;padding:6px 12px;font-size:12px;";
    });
    wrap.appendChild(row);
  });
  if (shell) shell.hidden = false;
  skeleton?.remove();
}
async function renderNotificationSettings() {
  if (!requireLogin("notification-settings.html")) return;
  const wrap = document.getElementById("notif-settings"); if (!wrap) return;
  const shell = document.getElementById("notif-settings-content");
  const skeleton = document.getElementById("notif-settings-skeleton");
  if (shell || skeleton) await nextFrame();
  const KEY = "lscores_notif_prefs";
  const prefs = JSON.parse(localStorage.getItem(KEY) || '{"goals":true,"redCards":true,"kickoff":true,"results":false}');
  Object.entries({ goals:"Goals", redCards:"Red cards", kickoff:"Kick-off", results:"Final results" }).forEach(([k,label]) => {
    const row = el(`
      <label class="menu-item" style="cursor:pointer;">
        <span class="ic">🔔</span><span>${label}</span>
        <input type="checkbox" ${prefs[k]?"checked":""} style="margin-left:auto;width:18px;height:18px;accent-color:var(--accent);">
      </label>`);
    row.querySelector("input").addEventListener("change", e => {
      prefs[k] = e.target.checked; localStorage.setItem(KEY, JSON.stringify(prefs));
    });
    wrap.appendChild(row);
  });
  if (shell) shell.hidden = false;
  skeleton?.remove();
}
async function renderAccountSettings() {
  if (!requireLogin("account-settings.html")) return;
  const wrap = document.getElementById("account-settings"); if (!wrap) return;
  const shell = document.getElementById("account-settings-content");
  const skeleton = document.getElementById("account-settings-skeleton");
  if (shell || skeleton) await nextFrame();
  const u = getUser();
  wrap.innerHTML = `
    <div class="card"><div class="card-title">EMAIL</div><p style="color:var(--text);">${u.email}</p></div>
    <div class="card"><div class="card-title">PASSWORD</div>
      <p style="color:var(--muted);font-size:13px;">Change is disabled in demo mode.</p>
      <button class="btn btn-secondary" style="margin-top:10px;" disabled>Change password</button></div>
    <div class="card"><div class="card-title" style="color:#ff6b6b;">DANGER ZONE</div>
      <button class="btn btn-secondary" id="delete-acct" style="border-color:rgba(255,107,107,0.4);color:#ff6b6b;">Delete account</button></div>`;
  document.getElementById("delete-acct").addEventListener("click", () => {
    if (confirm("Delete your account? This clears local data only.")) {
      clearUser(); localStorage.removeItem(FAV_KEY); window.location.href = "index.html";
    }
  });
  if (shell) shell.hidden = false;
  skeleton?.remove();
}

async function renderProfile() {
  /* Public profile page — show user OR sign-in prompt */
  const u = getUser();
  const shell = document.getElementById("profile-content");
  const skeleton = document.getElementById("profile-skeleton");
  if (shell || skeleton) await nextFrame();
  const heroAvatar = document.getElementById("profile-avatar");
  const heroName = document.getElementById("profile-name");
  const heroSub = document.getElementById("profile-sub");
  const cta = document.getElementById("profile-cta");
  if (heroAvatar) heroAvatar.textContent = u ? u.name.split(" ").map(s=>s[0]).join("").slice(0,2).toUpperCase() : "?";
  if (heroName)   heroName.textContent   = u ? u.name : "Guest";
  if (heroSub)    heroSub.textContent    = u ? `${u.email}` : "Sign in to save favourites and follow leagues";
  if (cta) cta.innerHTML = u
    ? `<a class="btn btn-primary" href="dashboard.html">Open Dashboard</a> <button class="btn btn-secondary" id="profile-logout">Logout</button>`
    : `<a class="btn btn-primary" href="login.html">Log in</a> <a class="btn btn-secondary" href="register.html">Sign up</a>`;
  const lo = document.getElementById("profile-logout");
  if (lo) lo.addEventListener("click", () => { clearUser(); window.location.reload(); });
  if (shell) shell.hidden = false;
  skeleton?.remove();
}

async function renderSettings() {
  const shell = document.getElementById("settings-content");
  const skeleton = document.getElementById("settings-skeleton");
  if (!shell) return;
  if (shell || skeleton) await nextFrame();
  shell.hidden = false;
  skeleton?.remove();
  const sel = document.getElementById("theme-select");
  if (sel) sel.value = localStorage.getItem("lscores_theme") || "dark";
}

/* =========================================================
   BOOT
   ========================================================= */
document.addEventListener("DOMContentLoaded", async () => {
  if (window.neonkickPage && !document.body.dataset.page) {
    document.body.setAttribute('data-page', window.neonkickPage);
  }
  applyTheme();
  if (isDesktop()) buildLayout();

  const page = document.body.dataset.page;
  const map = {
    home: renderHome, match: renderMatchDetail, lineups: renderLineups,
    standings: renderStandings, favourites: renderFavourites, leagues: renderLeaguesIndex,
    live: renderLive, fixtures: renderFixtures, results: renderResults,
    search: renderSearch, notifications: renderNotifications,
    team: renderTeamDetail, player: renderPlayerDetail, "league-detail": renderLeagueDetail,
    profile: renderProfile,
    login: renderLogin, register: renderRegister, forgot: renderForgot,
  dashboard: renderDashboard, settings: renderSettings, "edit-profile": renderEditProfile,
  "followed-leagues": renderFollowedLeagues,
  "notification-settings": renderNotificationSettings,
  "account-settings": renderAccountSettings,
  };
  if (map[page]) await map[page]();
});