live (Résultat 2025)
Actions
Composition
Face à Face
Équipe Locale
Équipe Visiteuse
×
En direct
Sud Radio
Votre navigateur ne supporte pas l’élément audio.
var teamRequest = false;
// ✅ PATCH : recalcul simple des stats si l’API renvoie 0 partout
function buildEmptyStats() {
return {
locale: { drop:0, essai:0, « mi-temps »: null, penalite:0, carton_jaune:0, carton_rouge:0, transformation:0 },
ext: { drop:0, essai:0, « mi-temps »: null, penalite:0, carton_jaune:0, carton_rouge:0, transformation:0 }
};
}
function normalizeActionType(t) {
return String(t || »).toUpperCase().trim();
}
function applyStatsFromActions(data) {
if (!data || !Array.isArray(data.actions)) return data;
// si stats absentes -> on les crée
if (!data.stats) data.stats = buildEmptyStats();
// si stats présentes mais vides -> on peut recalculer
const sL = data.stats.locale || {};
const sE = data.stats.ext || {};
const sum =
(sL.essai||0)+(sL.transformation||0)+(sL.penalite||0)+(sL.drop||0)+(sL.carton_jaune||0)+(sL.carton_rouge||0) +
(sE.essai||0)+(sE.transformation||0)+(sE.penalite||0)+(sE.drop||0)+(sE.carton_jaune||0)+(sE.carton_rouge||0);
// Si l’API a déjà des stats > 0, on ne touche pas
if (sum > 0) return data;
// Recalcul depuis actions
const stats = buildEmptyStats();
const localId = String(data.local_team?.id || »);
const visitorId = String(data.visitor_team?.id || »);
for (const a of data.actions) {
if (!a) continue;
const type = normalizeActionType(a.type);
const teamId = String(a.competitionEquipeId || »);
const side = (teamId === localId) ? ‘locale’ : (teamId === visitorId ? ‘ext’ : null);
if (type === ‘TRY’) { if (side) stats[side].essai += 1; }
else if (type === ‘GOALAFTERTRY’) { if (side) stats[side].transformation += 1; }
else if (type === ‘GOALPENALTY’) { if (side) stats[side].penalite += 1; }
else if (type === ‘DROPGOAL’) { if (side) stats[side].drop += 1; }
else if (type === ‘PENALTY TRY’ || type === ‘PENALTYTRY’) { if (side) stats[side].essai += 1; }
else if (type === ‘CARD’) {
const st = String(a.sousType || a.description || »).toUpperCase();
if (side && st.includes(‘YELLOW’)) stats[side].carton_jaune += 1;
if (side && st.includes(‘RED’)) stats[side].carton_rouge += 1;
}
else if (type === ‘MT’) {
stats.locale[« mi-temps »] = stats.locale[« mi-temps »] ?? ‘MT’;
stats.ext[« mi-temps »] = stats.ext[« mi-temps »] ?? ‘MT’;
}
}
data.stats = stats;
return data;
}
function getRencontreId() {
let urlParams = new URLSearchParams(window.location.search);
let rId = urlParams.get(‘id’);
if (!rId) {
const matchContainer = document.getElementById(‘match-container’);
if (matchContainer) {
rId = matchContainer.getAttribute(‘data-match-id’);
}
}
if (!rId) {
rId = findRencontreIdInComments();
}
console.log(rId);
return rId;
}
function findRencontreIdInComments() {
var urlElement = document.querySelector(‘dd.tribe-events-event-url a’);
if (urlElement) {
var href = urlElement.getAttribute(‘href’);
var rId = new URL(href).searchParams.get(‘id’);
return rId;
} else {
const matchContainer = document.getElementById(‘team-container’);
if (matchContainer) {
rId = matchContainer.getAttribute(‘team-match-id’);
teamRequest = true;
return rId;
}
}
if (!rId) {
const parentElement = document.querySelector(‘#tribe-events-content’);
const commentNode = Array.from(parentElement.childNodes).find(node => node.nodeType === 8);
if (commentNode) {
const match = commentNode.nodeValue.match(/Rencontre ID: (\d+)/);
if (match) {
rId = match[1];
console.log(‘Rencontre ID:’, rId);
return rId;
} else {
console.log(‘ID non trouvé dans le commentaire.’);
}
} else {
console.log(‘Aucun commentaire trouvé.’);
}
}
}
function fetchDataAndUpdate() {
var apiUrl = »;
const rencontreId = getRencontreId();
if (teamRequest) {
apiUrl = `https://rugby-app-4ebacff10fda.herokuapp.com/rencontres/next_rencontre?id=${rencontreId}`;
} else {
apiUrl = `https://rugby-app-4ebacff10fda.herokuapp.com/rencontres/${rencontreId}`;
}
fetch(apiUrl)
.then(response => response.json())
.then(allData => {
const data = allData[0];
applyStatsFromActions(data);
const chartSection = document.querySelector(‘.chart-section’);
const summarySection = document.querySelector(‘.match-summary’);
if (data.rencontre_resultat_locale && data.rencontre_resultat_visiteuse && data.chart && data.chart.length > 0) {
createChart(data);
chartSection.style.display = ‘block’;
} else {
chartSection.style.display = ‘none’;
}
if (data.stats) {
updateLists(data);
summarySection.style.display = ‘block’;
} else {
summarySection.style.display = ‘none’;
}
updateActions(data);
updateScoreAndTeams(data);
creerTableau(data);
const contentDisplay = document.getElementById(‘content-display’);
if (data.content) {
contentDisplay.innerHTML = data.content;
}
const radioContainer = document.querySelector(‘.refresh-button-container’);
radioContainer.innerHTML = »;
const radios = (data.local_team.radios || []).concat(data.visitor_team.radios || []);
const uniqueRadios = Array.from(new Set(radios.map(radio => radio.id)))
.map(id => radios.find(radio => radio.id === id));
if (radios && radios.length > 0) {
uniqueRadios.forEach(radio => {
const radioButton = document.createElement(‘button’);
radioButton.textContent = `Écouter ${radio.name}`;
radioButton.classList.add(‘radio-btn’);
radioButton.onclick = function() {
playRadio(radio.name, radio.link, radio.logo);
};
radioContainer.appendChild(radioButton);
});
} else {
radioContainer.style.display = ‘none’;
}
if (data.youtube_link) {
const youtubeContainer = document.querySelector(‘.youtube-container’);
const youtubeIframe = document.getElementById(‘youtube-video’);
youtubeIframe.src = data.youtube_link;
youtubeContainer.style.display = ‘flex’;
}
const liveFbLink = data.fb_live;
const container_fb = document.getElementById(‘fb-live-container’);
if (liveFbLink && liveFbLink.includes(‘?v=’)) {
const videoId = liveFbLink.split(‘?v=’)[1];
const videoUrlEncoded = encodeURIComponent(`https://www.facebook.com/facebook/videos/${videoId}/`);
const iframeSrc = `https://www.facebook.com/plugins/video.php?href=${videoUrlEncoded}&width=560&height=314&show_text=false&appId&mute=0`;
const iframe = document.createElement(‘iframe’);
iframe.src = iframeSrc;
iframe.width = ‘560’;
iframe.height = ‘314’;
iframe.style.border = ‘none’;
iframe.style.overflow = ‘hidden’;
iframe.scrolling = ‘no’;
iframe.setAttribute(‘frameborder’, ‘0’);
iframe.setAttribute(‘allowfullscreen’, ‘true’);
iframe.setAttribute(‘allow’, ‘autoplay; clipboard-write; encrypted-media; picture-in-picture; web-share’);
container_fb.style.display = ‘flex’;
container_fb.appendChild(iframe);
}
if (data.etat === ‘termine’ || radios.length === 0) {
radioContainer.style.display = ‘none’;
} else {
resetTimer();
}
});
}
function creerTableau(statsData) {
const table = document.getElementById(‘matchTable’);
table.innerHTML = »;
let headerRow = `
${statsData.local_team.name}
Statistiques
${statsData.visitor_team.name}
`;
table.insertAdjacentHTML(‘beforeend’, headerRow);
const labels = {
« classement_actuel »: « Classement actuel »,
« victoires_domicile »: « Victoires domicile »,
« victoires_exterieur »: « Victoires extérieur »,
« points_domicile »: « Points domicile »,
« points_exterieur »: « Points extérieur »,
« essais_marques_domicile »: « Essais marqués domicile »,
« essais_marques_exterieur »: « Essais marqués extérieur »,
« essais_encaisses_domicile »: « Essais encaissés domicile »,
« essais_encaisses_exterieur »: « Essais encaissés extérieur »,
« tendance_globale »: « Tendance globale »,
« penalites_encaissees_domicile »: « Pénalités encaissées domicile »,
« penalites_encaissees_exterieur »: « Pénalités encaissées extérieur »
};
Object.keys(labels).forEach(key => {
let row = `
${formatData(statsData.local_team_stats[key])}
${labels[key]}
${formatData(statsData.visitor_team_stats[key])}
`;
table.insertAdjacentHTML(‘beforeend’, row);
});
table.insertAdjacentHTML(‘beforeend’, ‘ ‘);
}
function formatData(data) {
if (typeof data === ‘string’ && data.match(/V|N|D/)) {
let formattedData = data.split(‘ ‘).map(el => {
switch (el) {
case ‘V’:
return ‘
‘ + el + ‘ ‘;
case ‘N’:
return ‘
‘ + el + ‘ ‘;
case ‘D’:
return ‘
‘ + el + ‘ ‘;
default:
return el;
}
}).join(‘ ‘);
return formattedData;
} else {
return data;
}
}
function createTimelineItem(action, actionTeamName, isLocalTeam, actionTeam) {
const li = document.createElement(‘li’);
if (action.type === ‘comment’) {
li.className = ‘timeline-item timeline-comment’;
const commentText = action.comment || action.text || action.description || action.content || ‘Commentaire sans texte’;
li.innerHTML = `
`;
return li;
}
if (action.type === ‘tweet’) {
li.className = ‘timeline-item timeline-comment’;
const tweetUrl = action.description || action.comment || action.tweetUrl || »;
const tweetContent = action.text || »;
li.innerHTML = `
`;
if (tweetUrl) {
setTimeout(() => {
embedTweet(tweetUrl, `tweet-embed-${action.minutes || Date.now()}`);
}, 100);
}
return li;
}
li.className = ‘timeline-item ‘ + (isLocalTeam ? ‘timeline-local’ : ‘timeline-visitor’);
let sousTypeString = »;
let minute = action.minutes + « ‘ »;
if (action.type === ‘CARD’) {
sousTypeString = action.description.toUpperCase() || »;
}
const imgSrc = `https://vibrez-rugby.com/wp-content/uploads/2024/08/${action.type_traduit ? action.type_traduit.normalize(« NFD »).replace(/[\u0300-\u036f]/g, « »).toLowerCase().replace(/\s+/g, ») : »}${sousTypeString}.png`;
let actionsVar = »;
const specialTypes = new Set([‘Start’, ‘Stop’, ‘MT’, ‘MATCHBEGIN’, ‘MATCHOVER’]);
if (!specialTypes.has(action.type)) {
actionsVar = action.type_traduit ?? action.type;
} else {
minute = »;
switch (action.type) {
case ‘Start’:
case ‘MATCHBEGIN’:
actionsVar = ‘Coup d\’envoi’;
break;
case ‘Stop’:
case ‘MATCHOVER’:
actionsVar = ‘Fin du match’;
break;
case ‘MT’:
actionsVar = ‘Mi-temps’;
break;
default:
actionsVar = action.type_traduit ?? action.type;
}
}
const showTeamInfo = !specialTypes.has(action.type);
li.innerHTML = `
${minute ? `
${minute} ` : »}
${showTeamInfo ? `
` : »}
${actionsVar}
${action.Joueur1 ? `
${action.Joueur1.Personne.nom}
` : »}
${action.Joueur2 ? `
${action.Joueur2.Personne.nom}
` : »}
`;
return li;
}
function loadTwitterWidgets() {
if (!window.twttr && !document.getElementById(‘twitter-widgets’)) {
const script = document.createElement(‘script’);
script.id = ‘twitter-widgets’;
script.src = ‘https://platform.twitter.com/widgets.js’;
script.async = true;
script.charset = ‘utf-8’;
document.head.appendChild(script);
}
}
function embedTweet(tweetUrl, containerId) {
const checkTwitter = () => {
if (window.twttr && window.twttr.widgets) {
const container = document.getElementById(containerId);
if (container) {
window.twttr.widgets.createTweet(
extractTweetId(tweetUrl),
container,
{
theme: ‘light’,
width: 400,
align: ‘center’,
conversation: ‘none’,
cards: ‘visible’
}
).then(() => {
console.log(‘Tweet embedded successfully’);
}).catch(err => {
console.error(‘Error embedding tweet:’, err);
container.innerHTML = `
`;
});
}
} else {
setTimeout(checkTwitter, 100);
}
};
checkTwitter();
}
function extractTweetId(url) {
const match = url.match(/status\/(\d+)/);
return match ? match[1] : null;
}
function updateActions(data, invertOrder = true) {
const timeline = document.querySelector(‘.timeline’);
timeline.innerHTML = »;
loadTwitterWidgets();
const actionsTab = document.querySelector(‘.tab-btn[data-tab= »actions »]’);
const compositionTab = document.querySelector(‘.tab-btn[data-tab= »composition »]’);
const actionsPanel = document.getElementById(‘actions’);
const compositionPanel = document.getElementById(‘composition’);
// Vérifier s’il y a des actions
const hasActions = data.etat !== ‘A venir’ && data.etat !== ‘avenir’ && Array.isArray(data.actions) && data.actions.length > 0;
if (hasActions) {
const actions = data.actions.filter(a => a && a.type !== ‘KICKOFF’);
const priorityOf = (t) => {
switch (t) {
case ‘Start’:
case ‘MATCHBEGIN’:
return 0;
default:
return 1;
case ‘MT’:
return 2;
case ‘MATCHOVER’:
case ‘Stop’:
return 3;
}
};
const normMinute = (a) => {
const m = typeof a.minutes === ‘number’ ? a.minutes : parseInt(a.minutes, 10);
if (Number.isFinite(m)) return m;
if (a.type === ‘Start’ || a.type === ‘MATCHBEGIN’) return -1;
if (a.type === ‘MATCHOVER’ || a.type === ‘Stop’) return 999;
if (a.type === ‘MT’) return 500;
return 999;
};
const orderedAsc = actions.slice().sort((a, b) => {
const pa = priorityOf(a.type);
const pb = priorityOf(b.type);
if (pa !== pb) return pa – pb;
const ma = normMinute(a);
const mb = normMinute(b);
if (ma !== mb) return ma – mb;
const aLocal = String(a.competitionEquipeId) === String(data.local_team?.id);
const bLocal = String(b.competitionEquipeId) === String(data.local_team?.id);
return (bLocal ? 1 : 0) – (aLocal ? 1 : 0);
});
const orderedActions = invertOrder ? orderedAsc.slice().reverse() : orderedAsc;
for (const action of orderedActions) {
const isLocalTeam = String(action.competitionEquipeId) === String(data.local_team?.id);
const actionTeam = isLocalTeam ? data.local_team : data.visitor_team;
const actionTeamImg = actionTeam?.img_url || »;
const item = createTimelineItem(action, actionTeamImg, isLocalTeam, actionTeam);
timeline.appendChild(item);
}
actionsTab.style.display = ‘block’;
} else {
actionsTab.style.display = ‘none’;
actionsPanel.classList.remove(‘active’);
}
// Vérifier s’il y a des compositions
const hasComposition = data.compositon_equipe_local && data.compositon_equipe_local.length > 0;
if (!hasComposition) {
compositionTab.style.display = ‘none’;
compositionPanel.classList.remove(‘active’);
// Si pas d’actions ni de composition, activer l’onglet Face à Face
if (!hasActions) {
const enjeuxTab = document.querySelector(‘.tab-btn[data-tab= »enjeux »]’);
const enjeuxPanel = document.getElementById(‘enjeux’);
enjeuxTab.classList.add(‘active’);
enjeuxPanel.classList.add(‘active’);
}
return;
}
compositionTab.style.display = ‘block’;
const table = document.querySelector(« .custom-composition-table tbody »);
table.innerHTML = »;
const sortedEquipeLocal = (data.compositon_equipe_local || []).slice().sort((a, b) => a.numero – b.numero);
const sortedEquipeVisiteur = (data.compositon_equipe_visiteur || []).slice().sort((a, b) => a.numero – b.numero);
for (let i = 0; i < sortedEquipeLocal.length; i++) {
const joueurLocal = sortedEquipeLocal[i] || {};
const joueurVisiteur = sortedEquipeVisiteur[i];
const row = table.insertRow();
row.insertCell(0).innerHTML =
`
${joueurLocal.numero ?? »}
${joueurLocal.nom ?? »}
${joueurLocal.estCapitaine ? «
C » : « »}`;
row.insertCell(1).innerHTML = joueurVisiteur
? `
${joueurVisiteur.numero ?? »}
${joueurVisiteur.nom ?? »}
${joueurVisiteur.estCapitaine ? «
C » : « »}`
: »;
}
}
function getFormeHtml(equipe) {
let formeArray = equipe.forme;
return formeArray.map(val => {
if (val === ‘V’) {
return ‘
‘;
} else if (val === ‘N’) {
return ‘
‘;
} else if (val === ‘D’) {
return ‘
‘;
}
}).join( »);
}
function updateScoreAndTeams(data) {
const scoreContainer = document.querySelector(« .custom-score-container »);
const emblemeLocal = document.querySelector(« .custom-emblem-local »);
const dateContainer = document.querySelector(« .custom_date »);
const nomLocal = document.querySelector(« .custom-local-name »);
const emblemeVisiteur = document.querySelector(« .custom-emblem-visitor »);
const nomVisiteur = document.querySelector(« .custom-visitor-name »);
const h1Container = document.querySelector(« .custom-h1 »);
const competitionBadge = document.querySelector(« .competition-badge »);
const matchDay = document.querySelector(« .match-day »);
const matchStatusBadge = document.querySelector(« .match-status-badge »);
emblemeLocal.src = data.local_team.img_url;
emblemeVisiteur.src = data.visitor_team.img_url;
let formeEquipeLocale = getFormeHtml(data.local_team);
let formeEquipeVisiteuse = getFormeHtml(data.visitor_team);
nomLocal.innerHTML = `${data.local_team.name}
${formeEquipeLocale}
`;
nomVisiteur.innerHTML = `${data.visitor_team.name}
${formeEquipeVisiteuse}
`;
// Mise à jour du badge de compétition
competitionBadge.textContent = data.competition || »;
// Mise à jour de la journée
// Formats possibles: « 13e-journee », « poule 3 », « journee-13″, etc.
let day = String(data.day || »)
.replace(/-/g, ‘ ‘) // Remplace les tirets par des espaces
.replace(/journee\s*(\d+)/gi, ‘Journée $1’) // « journee 13 » -> « Journée 13 »
.replace(/(\d+)e?\s*journee/gi, ‘Journée $1’) // « 13e journee » ou « 13 journee » -> « Journée 13 »
.replace(/poule\s*(\d+)/gi, ‘Poule $1’); // « poule 3 » -> « Poule 3″
matchDay.textContent = day;
const gameStatus = data.etat === ‘endirect’ || data.etat === ‘avenir’ ? ‘En Direct’ : »;
const gameFinish = data.etat === ‘termine’ ? ‘Terminé’ : »;
// Mise à jour du badge de statut
if (data.etat === ‘endirect’) {
matchStatusBadge.textContent = ‘LIVE’;
matchStatusBadge.className = ‘match-status-badge status-live’;
document.body.classList.add(‘match-live’);
} else if (data.etat === ‘termine’) {
matchStatusBadge.textContent = ‘Terminé’;
matchStatusBadge.className = ‘match-status-badge status-finished’;
document.body.classList.remove(‘match-live’);
} else {
matchStatusBadge.textContent = ‘À venir’;
matchStatusBadge.className = ‘match-status-badge status-upcoming’;
document.body.classList.remove(‘match-live’);
}
h1Container.textContent = `${data.local_team.name} – ${data.visitor_team.name}`;
const date = new Date(data.date);
const dateFormatted = `${date.toLocaleDateString(‘fr-FR’, {
weekday: ‘long’,
year: ‘numeric’,
month: ‘long’,
day: ‘numeric’,
})}`;
const heureFormatted = `${date.toLocaleTimeString(‘fr-FR’, {
hour: ‘2-digit’,
minute: ‘2-digit’,
})}`;
if (data.rencontre_resultat_locale && data.etat === « termine ») {
scoreContainer.innerHTML = `
${data.rencontre_resultat_locale.pointsDeMarque}
–
${data.rencontre_resultat_visiteuse.pointsDeMarque}
`;
if (data.periode) {
document.querySelector(‘.match-period’).textContent = data.periode;
}
dateContainer.innerHTML = `
${dateFormatted} `;
} else if (data.etat === ‘endirect’) {
scoreContainer.innerHTML = `
${data.rencontre_resultat_locale.pointsDeMarque}
–
${data.rencontre_resultat_visiteuse.pointsDeMarque}
`;
if (data.periode) {
document.querySelector(‘.match-period’).textContent = data.periode;
}
dateContainer.innerHTML = `
${dateFormatted} `;
} else {
scoreContainer.innerHTML = `
${heureFormatted}
`;
dateContainer.innerHTML = `
${dateFormatted} `;
}
}
function updateLists(data) {
const summaryTable = document.querySelector(‘.summary-table’);
summaryTable.innerHTML = »;
const orderedKeys = [
‘MI-TEMPS’, ‘ESSAI’, ‘TRANSFORMATION’, ‘PENALITE’,
‘ESSAIS DE PÉNALITÉ’, ‘DROP’, ‘CARTON_JAUNE’, ‘CARTON_ROUGE’
];
const keyMap = {
‘MI-TEMPS’: ‘mi-temps’,
‘ESSAI’: ‘essai’,
‘TRANSFORMATION’: ‘transformation’,
‘PENALITE’: ‘penalite’,
‘ESSAIS DE PÉNALITÉ’: ‘Essais de pénalité’,
‘DROP’: ‘drop’,
‘CARTON_JAUNE’: ‘carton_jaune’,
‘CARTON_ROUGE’: ‘carton_rouge’
};
const displayLabels = {
‘MI-TEMPS’: ‘Mi-temps’,
‘ESSAI’: ‘Essais’,
‘TRANSFORMATION’: ‘Transformations’,
‘PENALITE’: ‘Pénalités’,
‘ESSAIS DE PÉNALITÉ’: ‘Essais pénalité’,
‘DROP’: ‘Drops’,
‘CARTON_JAUNE’: ‘Cartons jaunes’,
‘CARTON_ROUGE’: ‘Cartons rouges’
};
const localeStats = data?.stats?.locale || {};
const extStats = data?.stats?.ext || {};
orderedKeys.forEach((key) => {
const dataKey = keyMap[key];
let localValue = localeStats.hasOwnProperty(dataKey) ? localeStats[dataKey] : 0;
let visitorValue = extStats.hasOwnProperty(dataKey) ? extStats[dataKey] : 0;
if (key === ‘MI-TEMPS’) {
localValue = localeStats.hasOwnProperty(dataKey) ? localeStats[dataKey] : null;
visitorValue = extStats.hasOwnProperty(dataKey) ? extStats[dataKey] : null;
}
if (localValue !== null || visitorValue !== null) {
const tr = document.createElement(‘tr’);
tr.innerHTML = `
${localValue}
${displayLabels[key]}
${visitorValue}
`;
summaryTable.appendChild(tr);
}
});
}
// Gestion des onglets
document.querySelectorAll(‘.tab-btn’).forEach(btn => {
btn.addEventListener(‘click’, () => {
const tabId = btn.dataset.tab;
// Mise à jour des boutons
document.querySelectorAll(‘.tab-btn’).forEach(b => b.classList.remove(‘active’));
btn.classList.add(‘active’);
// Mise à jour des panneaux
document.querySelectorAll(‘.tab-panel’).forEach(panel => panel.classList.remove(‘active’));
document.getElementById(tabId).classList.add(‘active’);
});
});
let myChart;
function createChart(data) {
const chartData = data.chart;
if (chartData) {
const labels = Array.from({ length: 80 }, (_, i) => i);
const teams = {
[data.local_team.id]: { name: data.local_team.name, color: ‘#004D90’ },
[data.visitor_team.id]: { name: data.visitor_team.name, color: ‘#e63946′ }
};
const datasets = Object.keys(teams).map(teamId => {
const rawTeamData = chartData
.filter(item => item.team === teamId)
.map(item => ({ x: item.minutes, y: item.score }));
return {
label: teams[teamId].name,
data: rawTeamData,
borderColor: teams[teamId].color,
backgroundColor: teams[teamId].color + ’20’,
borderWidth: 3,
tension: 0.3,
fill: false,
pointRadius: 0,
pointHoverRadius: 6,
};
});
const localTeamDataset = datasets.find(dataset => dataset.label === teams[data.local_team.id].name);
const sortedDatasets = [localTeamDataset].concat(datasets.filter(dataset => dataset !== localTeamDataset));
if (myChart) {
myChart.destroy();
}
if (document.getElementById(‘myChart’)) {
const ctx = document.getElementById(‘myChart’).getContext(‘2d’);
myChart = new Chart(ctx, {
type: ‘line’,
data: {
labels: labels,
datasets: sortedDatasets
},
options: {
responsive: true,
maintainAspectRatio: true,
plugins: {
legend: {
display: true,
position: ‘top’,
labels: {
usePointStyle: true,
padding: 20,
font: {
family: ‘Poppins’,
size: 12
}
}
}
},
scales: {
x: {
display: true,
title: {
display: true,
text: ‘Minutes’,
font: {
family: ‘Poppins’,
size: 12
}
},
type: ‘linear’,
position: ‘bottom’,
min: 0,
max: 80,
grid: {
color: ‘rgba(0, 0, 0, 0.05)’
}
},
y: {
display: true,
title: {
display: true,
text: ‘Points’,
font: {
family: ‘Poppins’,
size: 12
}
},
grid: {
color: ‘rgba(0, 0, 0, 0.05)’
}
}
},
}
});
}
}
}
let refreshTimeout = null;
function resetTimer() {
if (refreshTimeout) {
clearTimeout(refreshTimeout);
}
refreshTimeout = setTimeout(() => {
fetchDataAndUpdate();
}, 60000);
}
function playRadio(name, url, logo) {
const playerContainer = document.querySelector(‘.spotify-style-player’);
const audioTitle = playerContainer.querySelector(‘.audio-title’);
const audioSource = playerContainer.querySelector(‘audio source’);
const audioPlayer = playerContainer.querySelector(‘audio’);
const logoImg = playerContainer.querySelector(‘.radio-logo’);
const closeButton = playerContainer.querySelector(‘.close-button’);
closeButton.onclick = function() {
playerContainer.style.display = ‘none’;
audioPlayer.pause();
};
audioTitle.textContent = name;
audioSource.src = url;
logoImg.src = logo;
audioPlayer.load();
playerContainer.style.display = ‘flex’;
audioPlayer.play().catch(error => {
console.error(« Autoplay blocked by the browser: « , error);
});
}
window.onload = function() {
fetchDataAndUpdate();
};
:root {
/* Couleurs Vibrez Rugby */
–color-primary: #004D90;
–color-primary-dark: #002759;
–color-accent: #0693e3;
–color-danger: #e63946;
–color-success: #2a9d8f;
–color-warning: #f4a261;
/* Neutres */
–color-white: #ffffff;
–color-gray-50: #f8fafc;
–color-gray-100: #f1f5f9;
–color-gray-200: #e2e8f0;
–color-gray-300: #cbd5e1;
–color-gray-400: #94a3b8;
–color-gray-500: #64748b;
–color-gray-600: #475569;
–color-gray-700: #334155;
–color-gray-800: #1e293b;
–color-gray-900: #0f172a;
/* Typographie */
–font-family: ‘Poppins’, -apple-system, BlinkMacSystemFont, ‘Segoe UI’, sans-serif;
/* Espacements */
–spacing-xs: 0.25rem;
–spacing-sm: 0.5rem;
–spacing-md: 1rem;
–spacing-lg: 1.5rem;
–spacing-xl: 2rem;
–spacing-2xl: 3rem;
/* Bordures */
–radius-sm: 0.375rem;
–radius-md: 0.5rem;
–radius-lg: 0.75rem;
–radius-xl: 1rem;
–radius-full: 9999px;
/* Ombres */
–shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
–shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
–shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
–shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
}
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: var(–font-family);
background: var(–color-gray-50);
color: var(–color-gray-800);
line-height: 1.6;
-webkit-font-smoothing: antialiased;
}
/* Container principal */
.main-container {
max-width: 1000px;
margin: 0 auto;
padding: var(–spacing-md);
}
/* Header du match */
.match-header {
text-align: center;
padding: var(–spacing-sm) 0;
}
.match-meta {
display: flex;
justify-content: center;
align-items: center;
gap: var(–spacing-sm);
margin-bottom: var(–spacing-sm);
flex-wrap: wrap;
}
.competition-badge {
background: linear-gradient(135deg, var(–color-primary), var(–color-primary-dark));
color: var(–color-white);
padding: var(–spacing-xs) var(–spacing-md);
border-radius: var(–radius-full);
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.match-day {
color: var(–color-gray-500);
font-size: 0.875rem;
}
.match-title {
font-size: clamp(1.25rem, 3vw, 1.75rem);
font-weight: 700;
color: var(–color-gray-900);
margin-bottom: var(–spacing-xs);
}
.match-date-time {
color: var(–color-gray-500);
font-size: 0.9rem;
}
.date-text {
text-transform: capitalize;
}
/* Scoreboard */
.scoreboard {
display: grid;
grid-template-columns: 1fr auto 1fr;
gap: var(–spacing-sm);
align-items: center;
background: var(–color-white);
border-radius: var(–radius-xl);
padding: var(–spacing-md);
box-shadow: var(–shadow-md);
margin-bottom: var(–spacing-sm);
}
.team-block {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.team-emblem-wrapper {
width: 80px;
height: 80px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: var(–spacing-xs);
}
.team-emblem {
max-width: 100%;
max-height: 100%;
object-fit: contain;
border-radius: var(–radius-md);
}
.team-name {
font-size: 0.9rem;
font-weight: 600;
color: var(–color-gray-800);
margin-bottom: 0;
}
.team-form-dots {
display: flex;
justify-content: center;
gap: 4px;
margin-top: var(–spacing-xs);
}
.form-dot {
width: 10px;
height: 10px;
border-radius: var(–radius-full);
}
.form-dot-win { background-color: var(–color-success); }
.form-dot-draw { background-color: var(–color-warning); }
.form-dot-loss { background-color: var(–color-danger); }
.score-block {
display: flex;
flex-direction: column;
align-items: center;
min-width: 140px;
}
.score-display {
display: flex;
align-items: center;
gap: var(–spacing-sm);
}
.score-value {
font-size: 2rem;
font-weight: 700;
color: var(–color-gray-900);
min-width: 45px;
text-align: center;
}
.score-live {
color: var(–color-danger);
}
.score-separator {
font-size: 1.5rem;
font-weight: 300;
color: var(–color-gray-400);
}
.match-period {
font-size: 0.75rem;
color: var(–color-gray-500);
margin-top: var(–spacing-xs);
}
.match-status-badge {
display: inline-flex;
align-items: center;
padding: var(–spacing-xs) var(–spacing-sm);
border-radius: var(–radius-full);
font-size: 0.7rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
margin-top: var(–spacing-sm);
}
.status-live {
background-color: var(–color-danger);
color: var(–color-white);
animation: pulse 2s infinite;
}
.status-finished {
background-color: var(–color-gray-200);
color: var(–color-gray-600);
}
.status-upcoming {
background-color: var(–color-accent);
color: var(–color-white);
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}
.match-kickoff {
text-align: center;
}
.kickoff-time {
font-size: 2rem;
font-weight: 700;
color: var(–color-primary);
}
/* Match summary stats */
.match-summary {
margin-bottom: var(–spacing-sm);
}
.summary-table {
width: 100%;
background: var(–color-white);
border-radius: var(–radius-md);
overflow: hidden;
box-shadow: var(–shadow-sm);
}
.summary-table tr {
display: grid;
grid-template-columns: 60px 1fr 60px;
border-bottom: 1px solid var(–color-gray-100);
align-items: center;
}
.summary-table tr:last-child {
border-bottom: none;
}
.summary-table td {
padding: 4px var(–spacing-sm);
border: none;
}
.summary-table .stat-value {
font-weight: 600;
font-size: 0.8rem;
}
.summary-table .stat-local {
text-align: center;
color: var(–color-primary);
}
.summary-table .stat-visitor {
text-align: center;
color: var(–color-danger);
}
.summary-table .stat-label {
text-align: center;
color: var(–color-gray-500);
font-size: 0.7rem;
}
/* Radio section */
.radio-section {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: var(–spacing-sm);
margin-bottom: var(–spacing-lg);
}
.radio-btn {
display: inline-flex;
align-items: center;
gap: var(–spacing-xs);
padding: var(–spacing-sm) var(–spacing-lg);
background: linear-gradient(135deg, var(–color-danger), #c1121f);
color: var(–color-white);
border: none;
border-radius: var(–radius-full);
font-family: var(–font-family);
font-size: 0.875rem;
font-weight: 500;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
}
.radio-btn:hover {
transform: translateY(-2px);
box-shadow: var(–shadow-md);
}
/* Video sections */
.video-section {
display: flex;
justify-content: center;
margin-bottom: var(–spacing-lg);
border-radius: var(–radius-lg);
overflow: hidden;
}
.video-section iframe {
width: 100%;
max-width: 700px;
aspect-ratio: 16/9;
border: none;
border-radius: var(–radius-lg);
}
/* Chart section */
.chart-section {
background: var(–color-white);
border-radius: var(–radius-md);
padding: var(–spacing-sm) var(–spacing-md);
margin-bottom: var(–spacing-md);
box-shadow: var(–shadow-sm);
}
#myChart {
max-height: 180px;
}
/* Tabs */
.tabs-nav {
display: flex;
background: var(–color-white);
border-radius: var(–radius-lg);
padding: var(–spacing-xs);
gap: var(–spacing-xs);
margin-bottom: var(–spacing-lg);
box-shadow: var(–shadow-sm);
}
.tab-btn {
flex: 1;
padding: var(–spacing-sm) var(–spacing-md);
background: transparent;
border: none;
border-radius: var(–radius-md);
font-family: var(–font-family);
font-size: 0.875rem;
font-weight: 500;
color: var(–color-gray-600);
cursor: pointer;
transition: all 0.2s;
}
.tab-btn:hover {
background: var(–color-gray-100);
}
.tab-btn.active {
background: linear-gradient(135deg, var(–color-primary), var(–color-primary-dark));
color: var(–color-white);
}
.tab-panels {
min-height: 200px;
}
.tab-panel {
display: none;
}
.tab-panel.active {
display: block;
}
/* Timeline */
.timeline {
list-style: none;
position: relative;
padding: var(–spacing-lg) 0;
}
.timeline::before {
content: »;
position: absolute;
left: 50%;
top: 0;
bottom: 0;
width: 2px;
background: var(–color-gray-200);
transform: translateX(-50%);
}
.timeline-item {
position: relative;
width: 50%;
padding: var(–spacing-md);
margin-bottom: var(–spacing-md);
}
.timeline-item.timeline-local {
padding-right: calc(var(–spacing-xl) + 25px);
text-align: right;
}
.timeline-item.timeline-visitor {
margin-left: 50%;
padding-left: calc(var(–spacing-xl) + 25px);
text-align: left;
}
.timeline-marker {
position: absolute;
top: 50%;
width: 40px;
height: 40px;
transform: translateY(-50%);
background: var(–color-white);
border-radius: var(–radius-full);
display: flex;
align-items: center;
justify-content: center;
box-shadow: var(–shadow-md);
z-index: 1;
}
.timeline-item.timeline-local .timeline-marker {
right: -20px;
}
.timeline-item.timeline-visitor .timeline-marker {
left: -20px;
}
.timeline-icon {
width: 28px;
height: 28px;
object-fit: contain;
}
.timeline-card {
background: var(–color-white);
border-radius: var(–radius-lg);
padding: var(–spacing-md);
box-shadow: var(–shadow-sm);
display: inline-flex;
flex-direction: column;
align-items: center;
min-width: 180px;
}
.timeline-time {
font-size: 0.75rem;
font-weight: 600;
color: var(–color-primary);
background: var(–color-gray-100);
padding: 2px 8px;
border-radius: var(–radius-full);
margin-bottom: var(–spacing-xs);
}
.timeline-team-logo {
width: 36px;
height: 36px;
object-fit: contain;
margin-bottom: var(–spacing-xs);
}
.timeline-action-title {
font-size: 0.9rem;
font-weight: 600;
color: var(–color-gray-800);
}
.timeline-player {
font-size: 0.8rem;
color: var(–color-gray-600);
margin-top: 2px;
}
.timeline-player-secondary {
color: var(–color-gray-400);
}
/* Timeline comments */
.timeline-comment {
width: 100%;
display: flex;
justify-content: center;
left: 0 !important;
margin-left: 0 !important;
padding: var(–spacing-md) !important;
}
.timeline-card-comment,
.timeline-card-tweet {
max-width: 500px;
width: 100%;
text-align: center;
}
.timeline-card-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(–spacing-sm) var(–spacing-md);
background: linear-gradient(135deg, var(–color-primary), var(–color-primary-dark));
border-radius: var(–radius-lg) var(–radius-lg) 0 0;
margin: calc(-1 * var(–spacing-md));
margin-bottom: var(–spacing-md);
width: calc(100% + 2 * var(–spacing-md));
}
.timeline-card-header-tweet {
background: linear-gradient(135deg, #1da1f2, #0d8bd9);
}
.timeline-card-header .timeline-time {
background: rgba(255, 255, 255, 0.2);
color: var(–color-white);
}
.comment-logo,
.tweet-logo {
width: 28px;
height: 28px;
border-radius: var(–radius-full);
}
.timeline-card-text {
font-size: 0.95rem;
color: var(–color-gray-700);
line-height: 1.5;
}
.tweet-embed {
margin-top: var(–spacing-md);
}
.tweet-fallback {
padding: var(–spacing-md);
background: var(–color-gray-50);
border-radius: var(–radius-md);
}
.tweet-fallback a {
color: var(–color-accent);
text-decoration: none;
}
/* Composition table */
.composition-grid {
max-width: 700px;
margin: 0 auto;
}
.composition-table {
width: 100%;
background: var(–color-white);
border-radius: var(–radius-lg);
overflow: hidden;
box-shadow: var(–shadow-sm);
border-collapse: collapse;
table-layout: fixed;
}
.composition-table thead th {
background: linear-gradient(135deg, var(–color-primary), var(–color-primary-dark));
color: var(–color-white);
padding: var(–spacing-sm) var(–spacing-md);
font-weight: 600;
font-size: 0.85rem;
width: 50%;
text-align: center;
}
.composition-table tbody td {
padding: var(–spacing-sm) var(–spacing-md);
border-bottom: 1px solid var(–color-gray-100);
vertical-align: middle;
}
.composition-table tbody td .player-wrapper {
display: inline-flex;
align-items: center;
text-align: left;
}
.composition-table tbody tr:nth-child(odd) {
background: var(–color-gray-50);
}
.composition-table tbody tr:hover {
background: var(–color-gray-100);
}
/* Les deux colonnes : texte aligné à gauche, centré dans l’espace */
.composition-table tbody td:first-child,
.composition-table tbody td:last-child {
text-align: left;
padding-left: 15%;
}
.player-number {
display: inline-flex;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
background: var(–color-primary);
color: var(–color-white);
border-radius: var(–radius-sm);
font-size: 0.7rem;
font-weight: 600;
margin-right: var(–spacing-xs);
}
.player-name {
font-weight: 500;
font-size: 0.85rem;
}
.captain-badge {
display: inline-flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
background: var(–color-warning);
color: var(–color-gray-900);
border-radius: var(–radius-full);
font-size: 0.65rem;
font-weight: 700;
margin-left: var(–spacing-xs);
}
/* Stats table (Face à Face) */
.stats-table {
width: 100%;
background: var(–color-white);
border-radius: var(–radius-lg);
overflow: hidden;
box-shadow: var(–shadow-sm);
border-collapse: collapse;
table-layout: fixed;
}
.stats-table thead th {
background: linear-gradient(135deg, var(–color-primary), var(–color-primary-dark));
color: var(–color-white);
padding: var(–spacing-sm);
font-weight: 600;
font-size: 0.75rem;
word-wrap: break-word;
}
.stats-table thead th:first-child,
.stats-table thead th:last-child {
width: 25%;
}
.stats-table thead th:nth-child(2) {
width: 50%;
}
.stats-table tbody td {
padding: var(–spacing-xs) var(–spacing-sm);
border-bottom: 1px solid var(–color-gray-100);
text-align: center;
font-size: 0.8rem;
vertical-align: middle;
word-wrap: break-word;
}
.stats-table tbody tr:nth-child(odd) {
background: var(–color-gray-50);
}
.stats-table .stat-label {
font-weight: 500;
color: var(–color-gray-600);
font-size: 0.7rem;
line-height: 1.2;
}
.form-badge {
display: inline-flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
border-radius: var(–radius-sm);
font-size: 0.65rem;
font-weight: 700;
margin: 1px;
}
.form-win {
background: var(–color-success);
color: var(–color-white);
}
.form-draw {
background: var(–color-warning);
color: var(–color-gray-900);
}
.form-loss {
background: var(–color-danger);
color: var(–color-white);
}
/* Content display */
.content-display {
margin-top: var(–spacing-lg);
}
/* Radio player */
.radio-player {
position: fixed;
bottom: var(–spacing-lg);
right: var(–spacing-lg);
width: 320px;
background: var(–color-gray-900);
border-radius: var(–radius-lg);
padding: var(–spacing-md);
box-shadow: var(–shadow-xl);
z-index: 1000;
flex-direction: column;
gap: var(–spacing-sm);
}
.radio-player-close {
position: absolute;
top: var(–spacing-sm);
right: var(–spacing-sm);
background: transparent;
border: none;
color: var(–color-gray-400);
font-size: 1.5rem;
cursor: pointer;
line-height: 1;
padding: 0;
width: 24px;
height: 24px;
}
.radio-player-close:hover {
color: var(–color-white);
}
.radio-player-info {
display: flex;
align-items: center;
gap: var(–spacing-sm);
}
.radio-player-logo {
width: 48px;
height: 48px;
border-radius: var(–radius-md);
object-fit: cover;
}
.radio-player-details {
flex: 1;
}
.radio-player-status {
font-size: 0.7rem;
color: var(–color-danger);
text-transform: uppercase;
font-weight: 600;
letter-spacing: 0.05em;
}
.radio-player-title {
font-size: 0.95rem;
font-weight: 600;
color: var(–color-white);
margin: 0;
}
.radio-player audio {
width: 100%;
height: 36px;
}
/* Responsive */
@media (max-width: 768px) {
.scoreboard {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
gap: var(–spacing-xs);
padding: var(–spacing-sm);
}
.team-block {
flex: 1;
min-width: 0;
}
.team-local { order: 1; }
.score-block { order: 2; }
.team-visitor { order: 3; }
.score-block {
flex: 0 0 auto;
min-width: 80px;
}
.team-emblem-wrapper {
width: 60px;
height: 60px;
}
.team-name {
font-size: 0.8rem;
}
.score-value {
font-size: 1.75rem;
}
/* Summary table mobile */
.summary-table tr {
grid-template-columns: 45px 1fr 45px;
}
.summary-table td {
padding: 3px var(–spacing-xs);
}
.summary-table .stat-value {
font-size: 0.7rem;
}
.summary-table .stat-label {
font-size: 0.6rem;
}
/* Chart mobile */
.chart-section {
max-width: 100%;
padding: var(–spacing-sm);
}
#myChart {
max-height: 150px;
}
/* Timeline mobile */
.timeline::before {
left: 20px;
}
.timeline-item,
.timeline-item.timeline-local,
.timeline-item.timeline-visitor {
width: 100%;
padding-left: 60px;
padding-right: var(–spacing-md);
text-align: left;
margin-left: 0;
}
.timeline-marker,
.timeline-item.timeline-local .timeline-marker,
.timeline-item.timeline-visitor .timeline-marker {
left: 0;
right: auto;
}
.timeline-card {
width: 100%;
align-items: flex-start;
}
.timeline-comment {
padding-left: var(–spacing-md) !important;
}
.timeline-comment .timeline-card {
align-items: center;
}
/* Tabs mobile */
.tabs-nav {
flex-direction: row;
}
.tab-btn {
font-size: 0.75rem;
padding: var(–spacing-sm) var(–spacing-xs);
}
/* Radio player mobile */
.radio-player {
bottom: var(–spacing-md);
right: var(–spacing-md);
left: var(–spacing-md);
width: auto;
}
/* Composition table mobile */
.composition-grid {
max-width: 100%;
}
.composition-table {
font-size: 0.75rem;
}
.composition-table thead th {
padding: var(–spacing-xs) var(–spacing-sm);
font-size: 0.7rem;
}
.composition-table tbody td {
padding: var(–spacing-xs) var(–spacing-sm);
}
.composition-table tbody td:first-child,
.composition-table tbody td:last-child {
padding-left: 10%;
}
.player-number {
width: 18px;
height: 18px;
font-size: 0.6rem;
margin-right: 2px;
}
.player-name {
font-size: 0.7rem;
}
.captain-badge {
width: 14px;
height: 14px;
font-size: 0.55rem;
}
/* Stats table (Face à Face) mobile */
.stats-table {
font-size: 0.7rem;
}
.stats-table thead th {
padding: var(–spacing-xs);
font-size: 0.6rem;
line-height: 1.2;
}
.stats-table thead th:first-child,
.stats-table thead th:last-child {
width: 22%;
}
.stats-table thead th:nth-child(2) {
width: 56%;
}
.stats-table tbody td {
padding: var(–spacing-xs) 2px;
font-size: 0.65rem;
}
.stats-table .stat-label {
font-size: 0.6rem;
}
.form-badge {
width: 14px;
height: 14px;
font-size: 0.5rem;
margin: 0;
}
}
@media (max-width: 480px) {
.main-container {
padding: var(–spacing-xs);
}
.match-header {
padding: var(–spacing-sm) 0;
}
.match-title {
font-size: 0.9rem;
}
.match-meta {
gap: var(–spacing-xs);
}
.competition-badge {
font-size: 0.6rem;
padding: 2px var(–spacing-sm);
}
.match-day {
font-size: 0.7rem;
}
.match-date-time {
font-size: 0.75rem;
}
.scoreboard {
padding: var(–spacing-xs);
gap: var(–spacing-xs);
}
.team-emblem-wrapper {
width: 45px;
height: 45px;
}
.team-name {
font-size: 0.65rem;
}
.form-dot {
width: 5px;
height: 5px;
}
.score-block {
min-width: 60px;
}
.score-value {
font-size: 1.25rem;
min-width: 30px;
}
.score-separator {
font-size: 1rem;
}
.match-status-badge {
font-size: 0.6rem;
padding: 2px 6px;
}
.kickoff-time {
font-size: 1.25rem;
}
/* Summary even smaller */
.summary-table tr {
grid-template-columns: 35px 1fr 35px;
}
.summary-table td {
padding: 2px var(–spacing-xs);
}
.summary-table .stat-value {
font-size: 0.65rem;
}
.summary-table .stat-label {
font-size: 0.55rem;
}
/* Timeline smaller */
.timeline-item,
.timeline-item.timeline-local,
.timeline-item.timeline-visitor {
padding-left: 50px;
padding-right: var(–spacing-xs);
}
.timeline-marker {
width: 32px;
height: 32px;
}
.timeline-icon {
width: 22px;
height: 22px;
}
.timeline-card {
padding: var(–spacing-xs);
}
.timeline-time {
font-size: 0.65rem;
padding: 1px 6px;
}
.timeline-team-logo {
width: 28px;
height: 28px;
}
.timeline-action-title {
font-size: 0.75rem;
}
.timeline-player {
font-size: 0.7rem;
}
/* Tables even smaller */
.stats-table thead th {
font-size: 0.55rem;
padding: 4px 2px;
}
.stats-table tbody td {
font-size: 0.6rem;
padding: 4px 2px;
}
.stats-table .stat-label {
font-size: 0.55rem;
}
.form-badge {
width: 12px;
height: 12px;
font-size: 0.45rem;
}
.composition-table thead th {
font-size: 0.6rem;
}
.composition-table tbody td {
padding: 4px 2px;
}
.player-number {
width: 16px;
height: 16px;
font-size: 0.55rem;
}
.player-name {
font-size: 0.65rem;
}
.captain-badge {
width: 12px;
height: 12px;
font-size: 0.5rem;
}
/* Radio button smaller */
.radio-btn {
font-size: 0.75rem;
padding: var(–spacing-xs) var(–spacing-md);
}
}
/* Hide elements */
.entry-title {
display: none;
}
live (Résultat 2025)
live (Résultat 2025) sur Vibrez Rugby. Pronostics, face-à-face, compositions, statistiques : tout savoir avant le direct. Accédez ensuite à notre radio live et/ou à notre score live commenté en temps réel pour ne rien manquer de l’action.
Comment suivre live (Résultat 2025) ?
Plusieurs options s’offrent à vous pour vivre cette rencontre comme si vous y étiez. Choisissez celle qui vous convient le mieux en fonction de votre situation.
À la radio ou en score live commenté
Si vous ne pouvez pas regarder le match, écoutez live (Résultat 2025) à la radio ou suivez notre score live. Chaque action clé, essai, pénalité et carton est mis à jour instantanément pour vous offrir une expérience immersive.
Sur quelle chaîne TV ?
Pour connaître l’heure et la chaîne de diffusion TV de live (Résultat 2025) , consultez notre programme TV complet, mis à jour quotidiennement avec les informations des diffuseurs officiels (Top 14 , Pro D2 , Coupe d’Europe, etc.).
Vibrez Rugby : Votre référence pour le rugby en direct
Notre plateforme vous donne accès à un large éventail de compétitions, chaque week-end. Plongez au cœur de l’action en un seul clic !
Toutes vos compétitions préférées
Ne ratez rien de live (Résultat 2025) : suivez le score en live, écoutez le match à la radio et vibrez au rythme des plus grandes rencontres de rugby.
1
Pour accéder à la diffusion en direct, dirigez-vous vers le menu principal. Dans cet espace, l’onglet « 🔴EN DIRECT » est entièrement consacré aux matchs en cours. Un clic vous transporte virtuellement dans le stade, où vous pouvez suivre le match du Stade Toulousain en temps réel.
Grâce à une équipe de commentateurs passionnés, nous garantissons une immersion totale dans l’action. Des essais spectaculaires aux pénalités décisives, vous serez informé de chaque moment clé en direct. Nous fournissons également des statistiques, des anecdotes et des analyses qui enrichissent votre expérience Stade Toulousain en direct .
Pour les amateurs de radio, profitez des commentaires en direct du Stade Toulousain en direct avec notre équipe passionnée. Où que vous soyez, restez connecté aux matchs du Stade Toulousain grâce à cette option.
Disponible sur ordinateur, tablette ou téléphone, notre plateforme de direct vous suit partout. Pour encore plus de praticité, utilisez notre application rugby dédiée, qui vous permet de ne rien rater du Stade Toulousain en direct.
Rejoignez-nous pour vivre chaque match de Toulouse en direct, que ce soit par radio ou en suivant les scores. Plongez au cœur de l’action et vivez votre passion du rugby sans interruption.
${commentText}