{"id":6,"date":"2025-10-25T20:58:22","date_gmt":"2025-10-25T20:58:22","guid":{"rendered":"https:\/\/jafyou.com\/?page_id=6"},"modified":"2025-10-25T20:58:22","modified_gmt":"2025-10-25T20:58:22","slug":"quickscore","status":"publish","type":"page","link":"https:\/\/jafyou.com\/?page_id=6","title":{"rendered":"QuickScore"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<!DOCTYPE html>\n<html lang=\"fr\">\n<head>\n  <meta charset=\"utf-8\" \/>\n  <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" \/>\n  <title>QuickScore \u2014 Football<\/title>\n  <style>\n    \/* ----------------\n       Reset & fonts\n       ---------------- *\/\n    :root{\n      --bg: #f5f7fb;\n      --card: #ffffff;\n      --muted: #6b7280;\n      --accent: #e11d48;\n      --glass: rgba(13,20,38,0.02);\n      --shadow: 0 6px 18px rgba(12,20,38,0.08);\n      --glass-2: rgba(255,255,255,0.6);\n      --radius: 14px;\n      --gap: 12px;\n    }\n    *{box-sizing:border-box}\n    html,body{height:100%}\n    body{\n      margin:0;\n      background:linear-gradient(180deg,var(--bg),#eef2f7);\n      font-family: Inter, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial;\n      color:#0b1220;\n      -webkit-font-smoothing:antialiased;\n      -moz-osx-font-smoothing:grayscale;\n      display:flex;\n      flex-direction:column;\n      min-height:100vh;\n    }\n\n    \/* ----------------\n       Header\n       ---------------- *\/\n    header.appbar{\n      display:flex;\n      align-items:center;\n      justify-content:space-between;\n      padding:14px 16px;\n      background:linear-gradient(90deg,#07102a,#0d1830);\n      color:#fff;\n      gap:12px;\n    }\n    .brand{\n      display:flex;\n      gap:10px;\n      align-items:center;\n      font-weight:700;\n      font-size:18px;\n      letter-spacing:0.3px;\n    }\n    .logo{\n      width:36px;height:36px;border-radius:9px;background:linear-gradient(180deg,#ff2d6f,#e11d48);\n      display:grid;place-items:center;color:white;font-weight:800;font-size:18px;box-shadow:0 6px 18px rgba(225,29,72,0.25)\n    }\n    .header-actions{display:flex;gap:12px;align-items:center}\n    .icon-btn{background:transparent;border:0;color:inherit;font-size:18px;cursor:pointer;padding:6px;border-radius:8px}\n    .search-input{\n      display:none;\n      width:100%;\n      max-width:420px;\n      margin-left:12px;\n    }\n    .search-input input{\n      width:100%;\n      padding:8px 12px;border-radius:12px;border:0;outline:none;background:rgba(255,255,255,0.06);color:#fff\n    }\n\n    \/* ----------------\n       Dates strip\n       ---------------- *\/\n    .dates-strip{\n      display:flex;\n      gap:8px;\n      overflow:auto;\n      padding:10px 12px;\n    }\n    .date-pill{\n      min-width:68px;\n      background:var(--card);\n      border-radius:12px;\n      padding:8px 10px;\n      text-align:center;\n      font-size:12px;\n      box-shadow:var(--shadow);\n      cursor:pointer;\n      color:var(--muted);\n      flex-shrink:0;\n    }\n    .date-pill.active{\n      border:2px solid var(--accent);\n      color:var(--accent);\n      font-weight:600;\n      transform:translateY(-2px);\n    }\n\n    \/* ----------------\n       Main area\n       ---------------- *\/\n    main.container{\n      padding:12px;\n      flex:1 1 auto;\n      max-width:1100px;\n      margin:0 auto;\n      width:100%;\n    }\n\n    .card{\n      background:var(--card);\n      border-radius:12px;\n      padding:10px;\n      box-shadow:var(--shadow);\n      margin-bottom:12px;\n    }\n\n    .allgames-row{display:flex;justify-content:space-between;align-items:center;padding:6px 4px}\n    .allgames-row .title{font-weight:700}\n    .counter{\n      display:inline-flex;align-items:center;gap:8px;\n      font-size:13px;color:var(--muted)\n    }\n    .badge{\n      background:var(--accent);color:#fff;padding:6px 8px;border-radius:10px;font-weight:700;font-size:13px;\n      box-shadow:0 6px 12px rgba(225,29,72,0.18)\n    }\n\n    .section-title{\n      display:flex;justify-content:space-between;align-items:center;padding:8px 6px;font-size:13px;color:var(--muted);\n      margin-bottom:6px;\n    }\n\n    \/* competition lines *\/\n    .competition-list{display:flex;flex-direction:column;gap:8px}\n    .competition-item{\n      display:flex;align-items:center;justify-content:space-between;padding:10px;border-radius:10px;\n      background:linear-gradient(180deg, rgba(13,20,38,0.02), rgba(255,255,255,0.6));\n      cursor:pointer;\n    }\n    .left{\n      display:flex;align-items:center;gap:12px;\n    }\n    .flag{\n      width:36px;height:24px;border-radius:4px;background:#ddd;display:inline-block;flex-shrink:0;overflow:hidden;\n    }\n    .competition-name{font-weight:600}\n    .competition-meta{font-size:12px;color:var(--muted)}\n\n    \/* Matches list *\/\n    .matches-grid{display:flex;flex-direction:column;gap:8px;margin-top:8px}\n    .match{\n      display:flex;align-items:center;justify-content:space-between;padding:10px;border-radius:10px;background:var(--card);box-shadow:0 4px 10px rgba(2,6,23,0.03)\n    }\n    .teams{display:flex;gap:12px;align-items:center}\n    .team{display:flex;flex-direction:column;align-items:flex-start}\n    .score{font-weight:800;font-size:18px;min-width:58px;text-align:center}\n    .match-time{font-size:12px;color:var(--muted)}\n\n    \/* favorites star *\/\n    .star{font-size:18px;cursor:pointer;opacity:0.9}\n\n    \/* skeleton *\/\n    .skeleton{height:12px;background:linear-gradient(90deg,#eee,#f6f6f6);border-radius:6px;overflow:hidden}\n\n    \/* bottom nav *\/\n    .bottom-nav{\n      position:fixed;left:12px;right:12px;bottom:12px;border-radius:24px;background:linear-gradient(180deg,#ffffff, #f8f9fb);\n      display:flex;justify-content:space-around;padding:8px 10px;box-shadow:0 12px 32px rgba(2,6,23,0.08);z-index:50;\n      max-width:1100px;margin:0 auto; width:calc(100% - 24px)\n    }\n    .nav-item{display:flex;flex-direction:column;align-items:center;font-size:12px;color:var(--muted);cursor:pointer}\n    .nav-item.active{color:var(--accent);font-weight:700}\n\n    \/* responsive *\/\n    @media(min-width:880px){\n      .dates-strip{padding:14px 20px}\n      .date-pill{min-width:86px}\n      main.container{padding:20px}\n      header.appbar{padding:18px 36px}\n      .search-input{display:block}\n    }\n  <\/style>\n<\/head>\n<body>\n  <header class=\"appbar\">\n    <div class=\"brand\">\n      <div class=\"logo\">QS<\/div>\n      <div>\n        <div style=\"font-size:14px;opacity:0.95\">QuickScore<\/div>\n        <div style=\"font-size:11px;color:rgba(255,255,255,0.8)\">Football \u2022 Live scores<\/div>\n      <\/div>\n    <\/div>\n\n    <div class=\"header-actions\">\n      <button class=\"icon-btn\" id=\"btn-refresh\" title=\"Refresh (now)\">\u2b6e<\/button>\n      <button class=\"icon-btn\" id=\"btn-search\" title=\"Search\">\ud83d\udd0d<\/button>\n    <\/div>\n\n    <div class=\"search-input\" id=\"searchWrap\" aria-hidden=\"true\">\n      <input id=\"search\" placeholder=\"Rechercher \u00e9quipe, comp\u00e9tition...\" \/>\n    <\/div>\n  <\/header>\n\n  <!-- Dates -->\n  <div class=\"dates-strip\" id=\"dates\">\n    <!-- generated by JS -->\n  <\/div>\n\n  <main class=\"container\">\n    <!-- All Games header -->\n    <div class=\"card\">\n      <div class=\"allgames-row\">\n        <div class=\"title\">All games<\/div>\n        <div class=\"counter\"><span class=\"badge\" id=\"todayCount\">&#8212;<\/span><span style=\"opacity:0.6;margin-left:8px\" id=\"allCount\">&#8212;<\/span><\/div>\n      <\/div>\n    <\/div>\n\n    <!-- favourite competitions -->\n    <div class=\"card\">\n      <div class=\"section-title\">\n        <div>FAVOURITE COMPETITIONS<\/div>\n        <div style=\"font-size:13px;color:var(--muted)\"><small>Football<\/small><\/div>\n      <\/div>\n\n      <div class=\"competition-list\" id=\"competitions\">\n        <!-- competitions inserted here -->\n      <\/div>\n    <\/div>\n\n    <!-- matches -->\n    <div class=\"card\" id=\"matchesCard\">\n      <div class=\"section-title\">\n        <div id=\"matchesHeader\">Matches for Today<\/div>\n        <div class=\"match-time\" id=\"lastUpdated\">\u2014<\/div>\n      <\/div>\n\n      <div id=\"matches\" class=\"matches-grid\">\n        <!-- matches inserted here -->\n      <\/div>\n    <\/div>\n\n    <!-- leagues \/ news placeholders -->\n    <div class=\"card\" id=\"leaguesCard\" style=\"display:none\">\n      <div class=\"section-title\">Leagues<\/div>\n      <div style=\"padding:10px;color:var(--muted)\">Chargement des ligues&#8230;<\/div>\n    <\/div>\n\n  <\/main>\n\n  <!-- bottom nav -->\n  <nav class=\"bottom-nav\" id=\"nav\">\n    <div class=\"nav-item active\" data-page=\"all\">\ud83c\udfdf<span>All<\/span><\/div>\n    <div class=\"nav-item\" data-page=\"live\">\ud83d\udd34<span>Live<\/span><\/div>\n    <div class=\"nav-item\" data-page=\"fav\">\u2b50<span>Fav<\/span><\/div>\n    <div class=\"nav-item\" data-page=\"news\">\ud83d\udcf0<span>News<\/span><\/div>\n    <div class=\"nav-item\" data-page=\"leagues\">\ud83c\udfc6<span>Leagues<\/span><\/div>\n  <\/nav>\n\n  <script>\n    \/**************************************************************************\n     * QUICK INSTRUCTIONS:\n     * - Set API_KEY to your AllSportsAPI key (already filled from your message)\n     * - If endpoints differ, update endpoints.{fixtures,livescore,leagues}\n     * - The script auto-refreshes live scores every REFRESH_INTERVAL ms.\n     **************************************************************************\/\n\n    \/\/ API configuration\n    const API_KEY = 'cdfe21e4a45a25d4932f7db00cb21ac8e862924df30a3a3cf9bf0a1558a50180';\n    const API_BASE = 'https:\/\/apiv3.apifootball.com';\n    \n    \/\/ Endpoints format pour apifootball.com\n    const endpoints = {\n      fixtures: (dateStr) => `${API_BASE}\/?action=get_events&from=${dateStr}&to=${dateStr}&APIkey=${API_KEY}`,\n      livescore: () => `${API_BASE}\/?action=get_events&match_live=1&APIkey=${API_KEY}`,\n      leagues: () => `${API_BASE}\/?action=get_leagues&APIkey=${API_KEY}`,\n      countries: () => `${API_BASE}\/?action=get_countries&APIkey=${API_KEY}`\n    };\n\n    \/\/ refresh interval (ms)\n    const REFRESH_INTERVAL = 30000; \/\/ 30 seconds\n    let autoRefreshTimer = null;\n\n    \/\/ ui nodes\n    const datesEl = document.getElementById('dates');\n    const compsEl = document.getElementById('competitions');\n    const matchesEl = document.getElementById('matches');\n    const matchesHeader = document.getElementById('matchesHeader');\n    const lastUpdated = document.getElementById('lastUpdated');\n    const todayCountEl = document.getElementById('todayCount');\n    const allCountEl = document.getElementById('allCount');\n    const btnRefresh = document.getElementById('btn-refresh');\n\n    \/\/ store state\n    let selectedDate = new Date();\n    let savedFavorites = JSON.parse(localStorage.getItem('qs_favs') || '[]');\n\n    \/\/ create date pills for -2..+2 days\n    function renderDatePills(centerDate = new Date()){\n      datesEl.innerHTML = '';\n      for(let i=-3;i<=3;i++){\n        const d = new Date(centerDate);\n        d.setDate(centerDate.getDate() + i);\n        const pill = document.createElement('div');\n        pill.className = 'date-pill' + (i===0 ? ' active' : '');\n        pill.dataset.offset = i;\n        const dayName = d.toLocaleDateString('fr-FR', {weekday:'short'}).toUpperCase();\n        const short = `${d.getDate()}.${String(d.getMonth()+1).padStart(2,'0')}`;\n        pill.innerHTML = `<div style=\"font-weight:700\">${dayName}<\/div><div style=\"font-size:12px;color:var(--muted)\">${short}<\/div>`;\n        pill.addEventListener('click', ()=>{\n          document.querySelectorAll('.date-pill').forEach(p=>p.classList.remove('active'));\n          pill.classList.add('active');\n          selectedDate = d;\n          loadFixturesForDate(d);\n        });\n        datesEl.appendChild(pill);\n      }\n    }\n\n    \/\/ format date to YYYY-MM-DD\n    function ymd(d){\n      const y = d.getFullYear();\n      const m = String(d.getMonth()+1).padStart(2,'0');\n      const day = String(d.getDate()).padStart(2,'0');\n      return `${y}-${m}-${day}`;\n    }\n\n    \/\/ show skeleton placeholders\n    function showSkeleton(){\n      matchesEl.innerHTML = '';\n      for(let i=0;i<6;i++){\n        const s = document.createElement('div');\n        s.className = 'match';\n        s.innerHTML = `\n          <div class=\"teams\" style=\"flex:1\">\n            <div style=\"width:100%;display:flex;flex-direction:column;gap:8px\">\n              <div class=\"skeleton\" style=\"width:60%\"><\/div>\n              <div class=\"skeleton\" style=\"width:45%\"><\/div>\n            <\/div>\n          <\/div>\n          <div style=\"width:80px;text-align:center\">\n            <div class=\"skeleton\" style=\"width:60px;height:26px;margin:0 auto\"><\/div>\n          <\/div>\n        `;\n        matchesEl.appendChild(s);\n      }\n    }\n\n    \/\/ fetch fixtures for date\n    async function fetchFixtures(date){\n      const dateStr = ymd(date);\n      const url = endpoints.fixtures(dateStr);\n      try{\n        const res = await fetch(url);\n        if(!res.ok) throw new Error('HTTP ' + res.status);\n        const data = await res.json();\n        return data;\n      }catch(err){\n        console.error('fetchFixtures error', err);\n        throw err;\n      }\n    }\n\n    \/\/ fetch live matches\n    async function fetchLives(){\n      const url = endpoints.livescore();\n      try{\n        const res = await fetch(url);\n        if(!res.ok) throw new Error('HTTP ' + res.status);\n        const data = await res.json();\n        return data;\n      }catch(err){\n        console.error('fetchLives error', err);\n        throw err;\n      }\n    }\n\n    \/\/ build competition list (simple top picks)\n    function renderCompetitionList(items){\n      compsEl.innerHTML = '';\n      \/\/ items: an array of league objects\n      items.slice(0,8).forEach(league=>{\n        const row = document.createElement('div');\n        row.className = 'competition-item';\n        row.innerHTML = `\n          <div class=\"left\">\n            <div class=\"flag\"><img decoding=\"async\" style=\"width:100%;height:100%;object-fit:cover\" src=\"${league.logo || ''}\" onerror=\"this.style.display='none'\"><\/div>\n            <div>\n              <div class=\"competition-name\">${league.name || league.title || 'League'}<\/div>\n              <div class=\"competition-meta\">${league.country || ''}<\/div>\n            <\/div>\n          <\/div>\n          <div style=\"display:flex;align-items:center;gap:10px\">\n            <div class=\"competition-meta\">${league.matchesCount ?? ''}<\/div>\n            <div class=\"star\" data-league=\"${league.id || league.league_id || ''}\">\u2606<\/div>\n          <\/div>\n        `;\n        const star = row.querySelector('.star');\n        if(savedFavorites.includes(star.dataset.league)) star.textContent = '\u2605';\n        star.addEventListener('click', (e)=>{\n          e.stopPropagation();\n          toggleFavorite(star.dataset.league);\n          star.textContent = savedFavorites.includes(star.dataset.league) ? '\u2605' : '\u2606';\n        });\n        compsEl.appendChild(row);\n      });\n    }\n\n    \/\/ toggle favorite (league id)\n    function toggleFavorite(id){\n      if(!id) return;\n      const idx = savedFavorites.indexOf(id);\n      if(idx === -1) savedFavorites.push(id);\n      else savedFavorites.splice(idx,1);\n      localStorage.setItem('qs_favs', JSON.stringify(savedFavorites));\n    }\n\n    \/\/ render matches\n    function renderMatches(list){\n      matchesEl.innerHTML = '';\n      if(!list || list.length===0){\n        matchesEl.innerHTML = `<div style=\"padding:16px;color:var(--muted)\">Aucun match trouv\u00e9 pour cette date.<\/div>`;\n        todayCountEl.textContent = '0';\n        return;\n      }\n      todayCountEl.textContent = list.length;\n      list.forEach(m=>{\n        \/\/ Structure APIFootball\n        const team1 = m.match_hometeam_name || 'Home';\n        const team2 = m.match_awayteam_name || 'Away';\n        const score1 = m.match_hometeam_score || '';\n        const score2 = m.match_awayteam_score || '';\n        const status = m.match_status || '';\n        const time = m.match_time || '';\n        const leagueName = m.league_name || '';\n\n        const div = document.createElement('div');\n        div.className = 'match';\n        div.innerHTML = `\n          <div style=\"flex:1\">\n            <div style=\"font-size:12px;color:var(--muted);margin-bottom:6px\">${leagueName}<\/div>\n            <div class=\"teams\">\n              <div class=\"team\"><div style=\"font-weight:600\">${team1 || 'Home'}<\/div><\/div>\n              <div class=\"score\">${(score1!==''||score2!=='') ? `${score1} - ${score2}` : '<span class=\"match-time\">'+(time||status||'TBD')+'<\/span>'}<\/div>\n              <div class=\"team\" style=\"text-align:right\"><div style=\"font-weight:600\">${team2 || 'Away'}<\/div><\/div>\n            <\/div>\n          <\/div>\n          <div style=\"display:flex;flex-direction:column;align-items:flex-end;gap:8px\">\n            <div class=\"match-time\">${status || time || ''}<\/div>\n            <div style=\"font-size:12px;color:var(--muted)\">${new Date(m.event_date || m.match_date || Date.now()).toLocaleString()}<\/div>\n          <\/div>\n        `;\n        matchesEl.appendChild(div);\n      });\n    }\n\n    \/\/ load fixtures for a specific date\n    async function loadFixturesForDate(date){\n      showSkeleton();\n      matchesHeader.textContent = `Matches for ${ymd(date)}`;\n      try{\n        const data = await fetchFixtures(date);\n        \/\/ APIFootball renvoie directement un tableau ou un objet avec error\n        let matches = [];\n        if(!data) throw new Error('No data');\n        if(Array.isArray(data)) {\n          matches = data;\n        } else if(data.error) {\n          console.warn('API error:', data.error, data.message);\n          throw new Error(data.message || 'API error');\n        }\n\n        renderMatches(matches);\n        lastUpdated.textContent = `Updated: ${new Date().toLocaleTimeString()}`;\n      }catch(err){\n        console.error(err);\n        matchesEl.innerHTML = `<div style=\"padding:16px;color:#b91c1c\">Impossible de charger les matches \u2014 v\u00e9rifie la cl\u00e9 API \/ endpoint.<\/div>`;\n        todayCountEl.textContent = '--';\n      }\n    }\n\n    \/\/ load live matches\n    async function loadLiveMatches(){\n      try{\n        const data = await fetchLives();\n        let matches = Array.isArray(data) ? data : [];\n        \/\/ Si on a des matchs en direct, on les affiche\n        if(matches.length > 0){\n          renderMatches(matches);\n          matchesHeader.textContent = 'Live Matches';\n          lastUpdated.textContent = `Live updated: ${new Date().toLocaleTimeString()}`;\n        } else if(window.location.hash === '#live') {\n          \/\/ Si on est sur la page live, montrer un message\n          matchesEl.innerHTML = `<div style=\"padding:16px;color:var(--muted)\">Aucun match en direct actuellement.<\/div>`;\n          matchesHeader.textContent = 'Live Matches';\n        }\n      }catch(err){\n        console.warn('live fetch failed',err);\n        if(window.location.hash === '#live'){\n          matchesEl.innerHTML = `<div style=\"padding:16px;color:#b91c1c\">Impossible de charger les matches en direct.<\/div>`;\n        }\n      }\n    }\n\n    \/\/ load leagues with country data\n    async function loadLeagues(){\n      try{\n        \/\/ D'abord charger les pays pour avoir les drapeaux\n        const countriesRes = await fetch(endpoints.countries());\n        const countriesData = await countriesRes.json();\n        const countryMap = {};\n        if(Array.isArray(countriesData)){\n          countriesData.forEach(c => {\n            countryMap[c.country_name.toLowerCase()] = {\n              logo: c.country_logo,\n              id: c.country_id\n            };\n          });\n        }\n        \n        \/\/ Ensuite charger les ligues\n        const res = await fetch(endpoints.leagues());\n        const data = await res.json();\n        const leagues = Array.isArray(data) ? data : [];\n        \n        \/\/ Enrichir les ligues avec les logos des pays\n        const enriched = leagues.map(l => ({\n          id: l.league_id || l.id,\n          name: l.league_name || l.name,\n          country: l.country_name || l.country,\n          logo: l.league_logo || (l.country_name && countryMap[l.country_name.toLowerCase()]?.logo) || '',\n          matchesCount: Math.floor(Math.random()*6) \/\/ simul\u00e9 pour le moment\n        }));\n        \n        renderCompetitionList(enriched);\n      }catch(err){\n        console.warn('leagues\/countries fetch failed',err);\n        \/\/ fallback avec quelques ligues par d\u00e9faut\n        const demo = [\n          {id:'1',name:'Premier League',country:'England',logo:''},\n          {id:'2',name:'Ligue 1',country:'France',logo:''},\n          {id:'3',name:'LaLiga',country:'Spain',logo:''},\n          {id:'4',name:'Botola Pro',country:'Morocco',logo:''},\n        ];\n        renderCompetitionList(demo);\n      }\n    }\n\n    \/\/ refresh orchestration\n    async function refreshAll(){\n      \/\/ reload fixtures for selected date and live\n      await loadFixturesForDate(selectedDate);\n      await loadLeagues();\n      await loadLiveMatches();\n    }\n\n    \/\/ set interval\n    function startAutoRefresh(){\n      stopAutoRefresh();\n      autoRefreshTimer = setInterval(async ()=>{\n        await loadLiveMatches();\n        \/\/ also update currently shown page if it's \"all\"\n        const activeNav = document.querySelector('.nav-item.active')?.dataset?.page;\n        if(activeNav === 'all') await loadFixturesForDate(selectedDate);\n      }, REFRESH_INTERVAL);\n    }\n    function stopAutoRefresh(){ if(autoRefreshTimer) clearInterval(autoRefreshTimer); autoRefreshTimer = null; }\n\n    \/\/ navigation\n    document.getElementById('nav').addEventListener('click', (e)=>{\n      const item = e.target.closest('.nav-item');\n      if(!item) return;\n      document.querySelectorAll('.nav-item').forEach(n=>n.classList.remove('active'));\n      item.classList.add('active');\n      const page = item.dataset.page;\n      \/\/ pages: all, live, fav, news, leagues\n      if(page === 'live'){\n        \/\/ show live matches\n        matchesHeader.textContent = 'Live Matches';\n        loadLiveMatches();\n      }else if(page === 'fav'){\n        \/\/ show favorites\n        matchesHeader.textContent = 'Favorites';\n        \/\/ show list of favorite leagues or teams (simple)\n        matchesEl.innerHTML = '';\n        if(savedFavorites.length===0){\n          matchesEl.innerHTML = `<div style=\"padding:16px;color:var(--muted)\">Aucun favori. Ajoute des ligues depuis la liste.<\/div>`;\n        }else{\n          matchesEl.innerHTML = `<div style=\"padding:12px\">Favoris: ${savedFavorites.join(', ')}<\/div>`;\n        }\n      }else if(page === 'leagues'){\n        matchesHeader.textContent = 'All Leagues';\n        loadLeagues();\n      }else if(page === 'news'){\n        matchesHeader.textContent = 'News';\n        matchesEl.innerHTML = `<div style=\"padding:16px;color:var(--muted)\">Aucune actualit\u00e9 pour le moment.<\/div>`;\n      }else{\n        \/\/ all games\n        loadFixturesForDate(selectedDate);\n      }\n    });\n\n    \/\/ manual refresh button\n    btnRefresh.addEventListener('click', async ()=>{\n      btnRefresh.disabled = true;\n      btnRefresh.textContent = '\u2b6e';\n      await refreshAll();\n      btnRefresh.disabled = false;\n    });\n\n    \/\/ initial boot\n    (function init(){\n      renderDatePills(selectedDate);\n      showSkeleton();\n      loadLeagues();\n      loadFixturesForDate(selectedDate);\n      startAutoRefresh();\n      \/\/ set broader counts placeholders\n      allCountEl.textContent = '\u2014';\n      \/\/ clicking anywhere outside search hides it\n      document.getElementById('btn-search').addEventListener('click', ()=>{\n        const wrap = document.getElementById('searchWrap');\n        const visible = wrap.getAttribute('aria-hidden') === 'false';\n        wrap.setAttribute('aria-hidden', (!visible).toString());\n        wrap.style.display = visible ? 'none' : 'block';\n        if(!visible) document.getElementById('search').focus();\n      });\n    })();\n\n    \/\/ --- Helper: fetch wrapper with timeout\n    async function fetchWithTimeout(url, opts={}, timeout=15000){\n      const controller = new AbortController();\n      const id = setTimeout(()=>controller.abort(), timeout);\n      try{\n        const res = await fetch(url, {...opts, signal: controller.signal});\n        clearTimeout(id);\n        return res;\n      }catch(err){\n        clearTimeout(id);\n        throw err;\n      }\n    }\n\n    \/\/ override built-in fetch used above to include timeout by default (optional)\n    \/\/ window.fetch = (u,o)=>fetchWithTimeout(u,o,15000);\n\n  <\/script>\n<\/body>\n<\/html>\n\n","protected":false},"excerpt":{"rendered":"<p>QuickScore \u2014 Football QS QuickScore Football \u2022 Live scores \u2b6e \ud83d\udd0d All games &#8212;&#8212; FAVOURITE COMPETITIONS Football Matches for Today \u2014 Leagues Chargement des ligues&#8230; \ud83c\udfdfAll \ud83d\udd34Live \u2b50Fav \ud83d\udcf0News \ud83c\udfc6Leagues<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-6","page","type-page","status-publish","hentry"],"_hostinger_reach_plugin_has_subscription_block":false,"_hostinger_reach_plugin_is_elementor":false,"_links":{"self":[{"href":"https:\/\/jafyou.com\/index.php?rest_route=\/wp\/v2\/pages\/6","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jafyou.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/jafyou.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/jafyou.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jafyou.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6"}],"version-history":[{"count":4,"href":"https:\/\/jafyou.com\/index.php?rest_route=\/wp\/v2\/pages\/6\/revisions"}],"predecessor-version":[{"id":11,"href":"https:\/\/jafyou.com\/index.php?rest_route=\/wp\/v2\/pages\/6\/revisions\/11"}],"wp:attachment":[{"href":"https:\/\/jafyou.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}