🎉 Le site est parfaitement en ligne avec HTTPS et le CSS !
https://pmu.ineraopendata.com fonctionne complètement — design Burkina Faso, navbar, footer, tout est là.

Prochaines étapes
1. Copier les modèles ML sur le VPS
bash# Sur votre Mac
scp models/catboost_model.pkl root@51.91.100.79:/var/www/Projet_PMU/models/
scp models/catboost_optimized_model.pkl root@51.91.100.79:/var/www/Projet_PMU/models/
scp models/xgboost_optimized_model.pkl root@51.91.100.79:/var/www/Projet_PMU/models/
scp models/encoders.pkl root@51.91.100.79:/var/www/Projet_PMU/models/
scp models/scaler.pkl root@51.91.100.79:/var/www/Projet_PMU/models/
2. Créer le compte admin sur le VPS
bashcd /var/www/Projet_PMU
source env/bin/activate
python manage.py createsuperuser
3. Mettre à jour settings.py pour la production
pythonDEBUG = False
ALLOWED_HOSTS = ['pmu.ineraopendata.com']
Puis redémarrer :
bashsudo systemctl restart pmule site en locale et en ligneJe vois la différence — le site en local a un meilleur design (logo plus grand, fonts Google chargées, bande tricolore visible) que le site en ligne.
Le problème sur le VPS c'est que Google Fonts ne se charge pas — probablement bloqué ou lent. C'est pour ça que les fonts et certains styles diffèrent.

Solution — Télécharger les fonts en local
Sur votre Mac, téléchargez les fonts :
bashcd /var/www/Projet_PMU/static/fonts  # ou sur Mac dans static/fonts/
mkdir -p static/fonts
Allez sur google-webfonts-helper.herokuapp.com et téléchargez :

Inter (weights 300,400,500,600,700)
Playfair Display (weights 700,800)


Ou plus simple — dans votre pmu.css, remplacez l'import Google Fonts par des fonts système :
Avant :
css@import url('https://fonts.googleapis.com/css2?family=Inter...');
Après — supprimez cette ligne et modifiez les variables :
css:root {
  --font: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --font-serif: Georgia, 'Times New Roman', serif;
}
Partout où vous avez font-family: 'Inter' → remplacez par font-family: var(--font).
Partout où vous avez font-family: 'Playfair Display' → remplacez par font-family: var(--font-serif).
Puis sur le VPS :
bashcd /var/www/Projet_PMU
git pull
python manage.py collectstatic
sudo systemctl restart pmuje ne comprend pas vraiment, pour il faut tout caLe problème est simple.
Sur votre site en ligne, le navigateur essaie de charger les fonts depuis Google :
https://fonts.googleapis.com/css2?family=Inter...
Mais cette requête prend du temps ou échoue — donc les fonts ne se chargent pas et le design change.

Deux solutions :
Option 1 — Laisser Google Fonts (plus simple)
Ne rien changer. Les fonts se chargeront quand la connexion internet sera meilleure. C'est juste un problème de latence.

Option 2 — Fonts en local (plus robuste)
Au lieu de charger depuis Google, les fonts sont dans votre projet. Ça marche même sans internet.

Pour votre cas, regardez bien les deux images — la différence principale c'est :

Local → fonts Google chargées → beau rendu
En ligne → fonts Google non chargées → fonts système utilisées

Le contenu et le design de base sont identiques. Ce n'est pas un bug critique.
Voulez-vous qu'on intègre les fonts en local dans le projet pour avoir exactement le même rendu partout ?ok c'est quoi il faut pour chargerPour charger les fonts en local, il faut :
1. Les fichiers de fonts (.woff2) dans static/fonts/
2. Remplacer l'import Google dans pmu.css par des @font-face locaux

Étape 1 — Télécharger les fonts sur votre Mac
bashcd /chemin/vers/Projet_PMU/static
mkdir fonts
cd fonts

# Inter
curl -o inter-300.woff2 "https://fonts.gstatic.com/s/inter/v13/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZ9hiJ-Ek-_EeA.woff2"
curl -o inter-400.woff2 "https://fonts.gstatic.com/s/inter/v13/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZ9hiA.woff2"
curl -o inter-600.woff2 "https://fonts.gstatic.com/s/inter/v13/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZ9hiJ-Ek-_EeA.woff2"
curl -o inter-700.woff2 "https://fonts.gstatic.com/s/inter/v13/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZ9hiJ-Ek-_EeA.woff2"

# Playfair Display
curl -o playfair-700.woff2 "https://fonts.gstatic.com/s/playfairdisplay/v30/nuFvD-vYSZviVYUb_rj3ij__anPXJzDwcbmjWBN2PKdFvUDQ.woff2"
curl -o playfair-800.woff2 "https://fonts.gstatic.com/s/playfairdisplay/v30/nuFvD-vYSZviVYUb_rj3ij__anPXJzDwcbmjWBN2PKd3vUDQ.woff2"

Étape 2 — Modifier pmu.css
Supprimez la première ligne :
css@import url('https://fonts.googleapis.com/css2?...');
Remplacez par :
css@font-face {
  font-family: 'Inter';
  font-weight: 300;
  font-style: normal;
  src: url('../fonts/inter-300.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-weight: 400;
  font-style: normal;
  src: url('../fonts/inter-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-weight: 600;
  font-style: normal;
  src: url('../fonts/inter-600.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-weight: 700;
  font-style: normal;
  src: url('../fonts/inter-700.woff2') format('woff2');
}
@font-face {
  font-family: 'Playfair Display';
  font-weight: 700;
  font-style: normal;
  src: url('../fonts/playfair-700.woff2') format('woff2');
}
@font-face {
  font-family: 'Playfair Display';
  font-weight: 800;
  font-style: normal;
  src: url('../fonts/playfair-800.woff2') format('woff2');
}
:root {
  --vert: #006B3C;
  --vert-mid: #009A44;
  --vert-dark: #004D2C;
  --vert-pale: #E8F5ED;
  --jaune: #FCD116;
  --jaune-pale: #FFFDE7;
  --rouge: #EF2B2D;
  --rouge-dark: #B71C1C;
  --rouge-pale: #FFEBEE;
  --noir: #1A1A1A;
  --gris-mid: #4A4A4A;
  --gris-light: #f0f4f0;
  --border: #E0E0E0;
  --white: #FFFFFF;
  --radius: 12px;
  --shadow: 0 2px 16px rgba(0,0,0,0.08);
  --shadow-lg: 0 6px 32px rgba(0,0,0,0.14);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: 'Inter', sans-serif;
  background: var(--gris-light);
  color: var(--noir);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* ─── TRI BAR ─── */
.tri-bar { height: 5px; display: flex; }
.tri-bar div:nth-child(1) { flex: 1; background: var(--rouge); }
.tri-bar div:nth-child(2) { flex: 1; background: var(--jaune); }
.tri-bar div:nth-child(3) { flex: 1; background: var(--vert-mid); }

/* ─── HEADER PUBLIC ─── */
.site-header { background: var(--vert); }

.navbar {
  max-width: 1400px;
  margin: 0 auto;
  padding: 1rem 2rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

.navbar-brand {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-shrink: 0;
}

.logo-mark {
  width: 44px; height: 44px;
  background: var(--jaune);
  border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; flex-shrink: 0;
}

.logo-mark-sm {
  width: 30px; height: 30px;
  background: var(--jaune);
  border-radius: 7px;
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; flex-shrink: 0;
}

.site-title {
  font-family: 'Playfair Display', serif;
  font-size: 1.4rem; font-weight: 800;
  color: var(--white); line-height: 1.1;
}

.site-subtitle {
  font-size: .68rem; color: var(--jaune);
  letter-spacing: .14em; text-transform: uppercase;
  font-weight: 700; margin-top: 2px;
}

.navbar-links { display: flex; gap: .25rem; }

.nav-link {
  display: flex; align-items: center; gap: .4rem;
  color: rgba(255,255,255,.7);
  font-size: .82rem; font-weight: 600;
  padding: .4rem .85rem; border-radius: 7px;
  text-decoration: none;
  transition: background .15s, color .15s;
}
.nav-link:hover  { background: rgba(255,255,255,.12); color: #fff; }
.nav-link.active { background: rgba(255,255,255,.18); color: #fff; }

/* ─── MAIN ─── */
.main {
  max-width: 1400px;
  margin: 0 auto;
  padding: 2rem 2rem 3rem;
  flex: 1;
  width: 100%;
}

/* ─── DATE HEADER ─── */
.date-header {
  background: #fff;
  border: 1px solid #D8EDD8;
  border-radius: var(--radius);
  padding: 1rem 1.5rem;
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 1.5rem;
  box-shadow: var(--shadow);
}

.date-label {
  display: flex; align-items: center; gap: .4rem;
  font-size: .72rem; font-weight: 700; color: #888;
  text-transform: uppercase; letter-spacing: .07em;
  margin-bottom: .3rem;
}

.date-value {
  font-family: 'Playfair Display', serif;
  font-size: 1.5rem; font-weight: 800; color: var(--vert-dark);
}

.date-badge {
  background: var(--vert-pale);
  border: 1px solid #A5D6A7;
  border-radius: 9px; padding: .5rem .9rem; text-align: center;
}

.date-badge-label { font-size: .7rem; color: #2E7D32; font-weight: 700; }
.date-badge-time  { font-size: 1rem; font-weight: 800; color: var(--vert-dark); }

/* ─── EMPTY STATE ─── */
.empty-state { text-align: center; padding: 4rem 2rem; }

.empty-icon {
  width: 72px; height: 72px;
  background: var(--vert-pale); border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 1.1rem;
}

.empty-title {
  font-family: 'Playfair Display', serif;
  font-size: 1.5rem; font-weight: 800; color: var(--vert-dark);
  margin-bottom: .65rem;
}

.empty-desc { font-size: .95rem; color: #666; max-width: 420px; margin: 0 auto; line-height: 1.65; }
.empty-hint { margin-top: .9rem; font-size: .82rem; color: #9E9E9E; }

/* ─── CONSENSUS BANNER ─── */
.consensus-banner {
  background: var(--vert);
  border-radius: 16px; padding: 1.5rem 2rem;
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; margin-bottom: 2rem;
  position: relative; overflow: hidden;
}

.consensus-banner::before {
  content: '';
  position: absolute; bottom: 0; left: 0; right: 0; height: 5px;
  background: linear-gradient(90deg, var(--rouge) 33%, var(--jaune) 33% 66%, var(--vert-mid) 66%);
}

.consensus-banner::after {
  content: '🏆';
  position: absolute; right: 1.5rem; top: 50%; transform: translateY(-50%);
  font-size: 5rem; opacity: .06;
}

.consensus-label {
  font-size: .7rem; font-weight: 800;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--jaune); margin-bottom: .4rem;
}

.consensus-value {
  font-family: 'Playfair Display', serif;
  font-size: 2rem; font-weight: 800; color: var(--white);
}

.consensus-sub { font-size: .75rem; color: rgba(255,255,255,.4); margin-top: .25rem; }

.consensus-badge {
  background: var(--jaune); color: var(--vert-dark);
  border-radius: 999px; padding: .4rem 1.1rem;
  font-size: .78rem; font-weight: 800; flex-shrink: 0;
}

/* ─── SECTION TITLE ─── */
.section-title {
  font-size: 1.1rem; font-weight: 700; color: var(--noir);
  margin-bottom: 1rem;
  display: flex; align-items: center; gap: .6rem;
}

.section-title::before {
  content: '';
  display: inline-block; width: 4px; height: 20px;
  background: linear-gradient(180deg, var(--rouge), var(--jaune), var(--vert-mid));
  border-radius: 2px;
}

/* ─── ALGO CARDS ─── */
.algo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1rem; margin-bottom: 2rem;
}

.algo-card {
  background: var(--white); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow);
  transition: transform .2s, box-shadow .2s;
}
.algo-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.algo-card.consensus { border: 2px solid var(--jaune); }

.algo-card-header {
  padding: .85rem 1.1rem;
  display: flex; align-items: center; justify-content: space-between;
  border-bottom: 1px solid var(--border); background: #F9FBF9;
}
.algo-card.consensus .algo-card-header { background: var(--jaune-pale); }

.algo-name { font-size: .78rem; font-weight: 800; color: var(--gris-mid); letter-spacing: .05em; text-transform: uppercase; }

.algo-tag { font-size: .68rem; padding: .2rem .65rem; border-radius: 999px; font-weight: 700; }
.tag-cat  { background: var(--vert-pale); color: var(--vert-dark); border: 1px solid #A5D6A7; }
.tag-xgb  { background: var(--jaune-pale); color: #5D4037; border: 1px solid var(--jaune); }
.tag-cons { background: var(--jaune); color: var(--vert-dark); }
.tag-ml   { background: var(--rouge-pale); color: var(--rouge-dark); border: 1px solid #EF9A9A; }

.algo-card-body { padding: 1.1rem; }
.algo-card-label { font-size: .68rem; color: #9E9E9E; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; margin-bottom: .6rem; }

/* ─── HORSE CHIPS ─── */
.horse-sequence { display: flex; flex-direction: row; flex-wrap: wrap; gap: 6px; align-items: center; }

.horse-chip {
  background: var(--vert-pale); color: var(--vert-dark);
  min-width: 34px; height: 34px; padding: 0 8px;
  border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .85rem; font-weight: 800; flex-shrink: 0;
}
.horse-chip.rank-1 { background: var(--jaune); color: var(--vert-dark); }
.horse-chip.rank-2 { background: var(--vert);  color: var(--white); }
.horse-chip.rank-3 { background: var(--rouge); color: var(--white); }

.algo-card-footer { margin-top: .85rem; text-align: right; padding-top: .75rem; border-top: 1px solid var(--border); }

/* ─── PANELS ─── */
.panel { display: none; }
.panel.active { display: block; }

.panel-card { background: var(--white); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow); overflow: hidden; margin-bottom: 1.5rem; }

.panel-header {
  background: var(--vert); padding: 1.1rem 1.5rem;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  border-bottom: 4px solid var(--jaune);
}
.panel-title   { font-size: 1rem; font-weight: 700; color: var(--white); }
.panel-subtitle { font-size: .75rem; color: rgba(255,255,255,.5); margin-top: 2px; }

/* ─── DATA TABLE ─── */
.data-table { width: 100%; border-collapse: collapse; }
.data-table th { padding: .7rem 1rem; font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .08em; color: var(--gris-mid); background: #F9FBF9; text-align: left; border-bottom: 1px solid var(--border); }
.data-table td { padding: .65rem 1rem; font-size: .86rem; border-bottom: 1px solid #F0F0F0; color: var(--noir); }
.data-table tr:last-child td { border-bottom: none; }
.data-table tr:hover td { background: #F9FBF9; }
.horse-num { font-weight: 800; font-size: .95rem; color: var(--vert-dark); }

.pct-bar { display: flex; align-items: center; gap: .65rem; }
.bar-track { flex: 1; height: 6px; background: var(--border); border-radius: 999px; overflow: hidden; }
.bar-fill { height: 100%; background: linear-gradient(90deg, var(--rouge), var(--jaune), var(--vert-mid)); border-radius: 999px; }
.bar-label { font-weight: 700; color: var(--gris-mid); min-width: 42px; text-align: right; font-size: .8rem; }

.rank-badge { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 6px; font-size: .75rem; font-weight: 800; background: #F5F5F5; color: var(--gris-mid); }
.rank-badge.r1 { background: var(--jaune);  color: var(--vert-dark); }
.rank-badge.r2 { background: var(--vert);   color: var(--white); }
.rank-badge.r3 { background: var(--rouge);  color: var(--white); }

/* ─── BUTTONS ─── */
.btn-detail {
  background: none; border: 1.5px solid var(--vert); border-radius: 8px;
  padding: .3rem .8rem; font-size: .78rem; font-weight: 700; color: var(--vert);
  cursor: pointer; transition: background .2s, color .2s; font-family: inherit;
}
.btn-detail:hover { background: var(--vert); color: var(--white); }

.btn-back {
  display: inline-flex; align-items: center; gap: .4rem;
  background: none; border: 1px solid var(--border); border-radius: var(--radius);
  padding: .55rem 1.1rem; font-size: .88rem; font-weight: 600; color: var(--gris-mid);
  cursor: pointer; text-decoration: none; transition: border-color .15s, color .15s;
  font-family: inherit;
}
.btn-back:hover { border-color: var(--vert); color: var(--vert); }

.moyenne-cta { text-align: center; margin-top: 1.25rem; }

/* ─── ALERTS ─── */
.messages-container { margin-bottom: 1.25rem; }
.alert { padding: .75rem 1.1rem; border-radius: 9px; font-size: .88rem; margin-bottom: .5rem; display: flex; align-items: center; gap: .5rem; }
.alert-success, .alert-messages-success { background: var(--vert-pale); border: 1px solid #A5D6A7; color: #1B5E20; }
.alert-error, .alert-messages-error, .alert-danger { background: var(--rouge-pale); border: 1px solid #EF9A9A; color: var(--rouge-dark); }

/* ─── FOOTER ─── */
.site-footer { background: var(--vert-dark); margin-top: auto; }

.footer-inner {
  max-width: 1100px; margin: 0 auto;
  padding: 1.75rem 2rem 1.25rem;
  display: flex; align-items: flex-start; justify-content: space-between; gap: 2rem;
}

.footer-brand { display: flex; align-items: center; gap: .6rem; margin-bottom: .5rem; }
.footer-title  { color: var(--white); font-weight: 800; font-size: .95rem; }
.footer-desc   { font-size: .78rem; color: rgba(255,255,255,.45); max-width: 320px; line-height: 1.55; }

.footer-links { display: flex;   flex-direction: row;gap: 1.5rem; align-items: center; }
.footer-links a { color: rgba(255,255,255,.5); font-size: .82rem; text-decoration: none; transition: color .15s; }
.footer-links a:hover { color: var(--jaune); }

.footer-copy {
  
  max-width: 1400px;
  margin: 0 auto;
  padding: .75rem 2rem 1.25rem;
  font-size: .75rem;
  color: rgba(255,255,255,.3);
  border-top: 1px solid rgba(255,255,255,.08);
  text-align: center;
}

/* ─── RESPONSIVE ─── */
@media (max-width: 640px) {
  .navbar { padding: .85rem 1rem; flex-wrap: wrap; gap: .75rem; }
  .navbar-links { order: 3; width: 100%; }
  .consensus-value { font-size: 1.4rem; }
  .main { padding: 1.5rem 1rem 2rem; }
  .footer-inner { flex-direction: column; gap: 1rem; padding: 1.25rem 1rem; }
  .date-header { flex-direction: column; align-items: flex-start; gap: .75rem; }
}
