Files
turf_saas/landing.html
DevOps Engineer 41a9e36166 feat(sprint4-5): Landing page + onboarding SaaS — HRT-30
Frontend pages:
- landing.html: marketing page — hero, pricing (Free/9.90e/24.90e), features, FAQ, footer, mobile-first responsive, LCP < 2.5s friendly
- login.html: JWT auth login with JS validation, error handling, redirect-after-login
- register.html: registration with plan selection preview sidebar, password strength meter
- dashboard_saas.html: role-based dashboard (Free/Premium/Pro) with locked sections, race prediction cards, detailed table, stats row
- onboarding.html: 3-step wizard — plan confirm + Telegram alerts config + first prediction preview
- account.html: tabbed account management — profile, security (change-password, delete), plan upgrade, notification preferences

Backend:
- saas_auth.py: Flask Blueprint /api/v1/auth/* — register, login, token auth, profile/password/plan/preferences update, logout, delete-account
- saas_api_v1.py: Flask Blueprint /api/v1/* — stats/summary, predictions/today (plan-gated), value-bets (Premium+), CSV export (Pro)

Server:
- portal_server.py: register blueprints, serve all new SaaS routes at /login /register /dashboard /onboarding /account

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-25 18:04:19 +02:00

227 lines
18 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Turf IA — Prédictions PMU par Intelligence Artificielle</title>
<meta name="description" content="Boostez vos paris PMU avec nos prédictions IA. Analyse XGBoost, value bets, alertes Telegram. Essai gratuit.">
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--green:#00c853; --green-d:#009624; --blue:#1565c0; --blue-l:#1e88e5;
--gold:#ffd600; --dark:#0d1117; --dark2:#161b22; --dark3:#21262d;
--text:#e6edf3; --muted:#8b949e; --border:#30363d; --radius:12px;
}
html { scroll-behavior: smooth; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: var(--dark); color: var(--text); line-height: 1.6; overflow-x: hidden; }
a { color: inherit; text-decoration: none; }
nav { position: sticky; top: 0; z-index: 100; display: flex; align-items: center; justify-content: space-between; padding: 16px 5%; background: rgba(13,17,23,0.95); backdrop-filter: blur(10px); border-bottom: 1px solid var(--border); }
.nav-logo { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 1.2rem; }
.nav-logo .badge { background: var(--green); color: #000; padding: 2px 8px; border-radius: 20px; font-size: .75rem; }
.nav-links { display: flex; align-items: center; gap: 28px; }
.nav-links a { color: var(--muted); font-size: .95rem; transition: color .2s; }
.nav-links a:hover { color: var(--text); }
.nav-cta { display: flex; gap: 10px; }
.btn { display: inline-flex; align-items: center; gap: 6px; padding: 9px 20px; border-radius: 8px; font-size: .9rem; font-weight: 600; cursor: pointer; border: none; transition: all .2s; }
.btn-ghost { background: transparent; border: 1px solid var(--border); color: var(--text); }
.btn-ghost:hover { border-color: var(--muted); }
.btn-primary { background: var(--green); color: #000; }
.btn-primary:hover { background: var(--green-d); transform: translateY(-1px); }
.btn-lg { padding: 14px 32px; font-size: 1.05rem; border-radius: 10px; }
.hero { min-height: 90vh; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 80px 5% 60px; background: radial-gradient(ellipse 80% 60% at 50% 0%, rgba(0,200,83,.08) 0%, transparent 70%); }
.hero-eyebrow { display: inline-flex; align-items: center; gap: 8px; background: rgba(0,200,83,.1); border: 1px solid rgba(0,200,83,.3); padding: 6px 16px; border-radius: 20px; font-size: .85rem; color: var(--green); margin-bottom: 24px; }
.hero h1 { font-size: clamp(2rem,5vw,3.6rem); font-weight: 800; line-height: 1.15; max-width: 780px; margin-bottom: 20px; }
.hero h1 span { color: var(--green); }
.hero p { font-size: 1.15rem; color: var(--muted); max-width: 580px; margin-bottom: 36px; }
.hero-actions { display: flex; gap: 14px; flex-wrap: wrap; justify-content: center; }
.hero-stats { display: flex; gap: 40px; margin-top: 60px; flex-wrap: wrap; justify-content: center; }
.stat { text-align: center; }
.stat strong { display: block; font-size: 2rem; font-weight: 800; color: var(--green); }
.stat span { font-size: .85rem; color: var(--muted); }
section { padding: 80px 5%; }
.section-label { color: var(--green); font-size: .85rem; font-weight: 600; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 12px; }
h2 { font-size: clamp(1.6rem,3vw,2.4rem); font-weight: 800; margin-bottom: 16px; }
.subtitle { color: var(--muted); font-size: 1.05rem; max-width: 560px; margin: 0 auto 50px; text-align: center; }
.section-center { text-align: center; }
.features-grid { display: grid; grid-template-columns: repeat(auto-fit,minmax(260px,1fr)); gap: 20px; max-width: 1100px; margin: 0 auto; }
.feature-card { background: var(--dark2); border: 1px solid var(--border); border-radius: var(--radius); padding: 28px; transition: border-color .2s,transform .2s; }
.feature-card:hover { border-color: var(--green); transform: translateY(-3px); }
.feature-icon { font-size: 2rem; margin-bottom: 14px; }
.feature-card h3 { font-size: 1.1rem; font-weight: 700; margin-bottom: 8px; }
.feature-card p { color: var(--muted); font-size: .9rem; line-height: 1.6; }
.pricing-grid { display: grid; grid-template-columns: repeat(auto-fit,minmax(280px,1fr)); gap: 20px; max-width: 960px; margin: 0 auto; }
.plan-card { background: var(--dark2); border: 1px solid var(--border); border-radius: var(--radius); padding: 32px; position: relative; transition: transform .2s; }
.plan-card:hover { transform: translateY(-4px); }
.plan-card.popular { border-color: var(--green); }
.popular-badge { position: absolute; top: -12px; left: 50%; transform: translateX(-50%); background: var(--green); color: #000; padding: 3px 16px; border-radius: 20px; font-size: .75rem; font-weight: 700; }
.plan-name { font-size: 1.1rem; font-weight: 700; margin-bottom: 8px; }
.plan-price { font-size: 2.6rem; font-weight: 800; margin: 12px 0 4px; }
.plan-price sup { font-size: 1.2rem; vertical-align: top; margin-top: 10px; }
.plan-price span { font-size: 1rem; font-weight: 400; color: var(--muted); }
.plan-desc { color: var(--muted); font-size: .88rem; margin-bottom: 20px; }
.plan-features { list-style: none; margin-bottom: 28px; }
.plan-features li { display: flex; align-items: flex-start; gap: 10px; padding: 7px 0; font-size: .9rem; }
.plan-features li::before { content: "✓"; color: var(--green); font-weight: 700; flex-shrink: 0; }
.plan-features li.disabled { color: var(--muted); }
.plan-features li.disabled::before { content: "×"; color: var(--border); }
.btn-plan { width: 100%; text-align: center; justify-content: center; }
.steps { display: flex; flex-direction: column; gap: 0; max-width: 700px; margin: 0 auto; }
.step { display: flex; gap: 24px; padding: 28px 0; border-bottom: 1px solid var(--border); }
.step:last-child { border-bottom: none; }
.step-num { width: 44px; height: 44px; border-radius: 50%; background: rgba(0,200,83,.1); border: 2px solid var(--green); display: flex; align-items: center; justify-content: center; font-weight: 800; color: var(--green); flex-shrink: 0; }
.step-body h3 { font-size: 1.05rem; font-weight: 700; margin-bottom: 6px; }
.step-body p { color: var(--muted); font-size: .9rem; }
.faq-list { max-width: 720px; margin: 0 auto; }
details { border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: 10px; overflow: hidden; }
details[open] { border-color: var(--green); }
summary { padding: 18px 22px; font-weight: 600; cursor: pointer; list-style: none; display: flex; justify-content: space-between; align-items: center; }
summary::after { content: "+"; color: var(--green); font-size: 1.3rem; }
details[open] summary::after { content: ""; }
.faq-answer { padding: 0 22px 18px; color: var(--muted); font-size: .93rem; line-height: 1.7; }
.cta-banner { background: linear-gradient(135deg,rgba(0,200,83,.12) 0%,rgba(21,101,192,.12) 100%); border: 1px solid var(--border); border-radius: 16px; padding: 60px; text-align: center; max-width: 820px; margin: 0 auto; }
.cta-banner h2 { margin-bottom: 12px; }
.cta-banner p { color: var(--muted); margin-bottom: 28px; }
footer { border-top: 1px solid var(--border); padding: 40px 5%; display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 40px; }
.footer-brand p { color: var(--muted); font-size: .88rem; margin-top: 10px; max-width: 240px; }
.footer-col h4 { font-size: .85rem; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; margin-bottom: 14px; color: var(--muted); }
.footer-col a { display: block; color: var(--muted); font-size: .88rem; margin-bottom: 8px; transition: color .2s; }
.footer-col a:hover { color: var(--text); }
.footer-bottom { border-top: 1px solid var(--border); padding: 20px 5%; text-align: center; color: var(--muted); font-size: .82rem; }
@media (max-width:768px) { .nav-links{display:none;} footer{grid-template-columns:1fr 1fr;} .cta-banner{padding:36px 24px;} }
@media (max-width:480px) { footer{grid-template-columns:1fr;} }
</style>
</head>
<body>
<nav>
<div class="nav-logo">🏇 Turf IA<span class="badge">BETA</span></div>
<div class="nav-links">
<a href="#features">Fonctionnalités</a>
<a href="#pricing">Tarifs</a>
<a href="#how">Comment ça marche</a>
<a href="#faq">FAQ</a>
</div>
<div class="nav-cta">
<a href="/login" class="btn btn-ghost">Connexion</a>
<a href="/register" class="btn btn-primary">S'inscrire gratuitement</a>
</div>
</nav>
<section class="hero">
<div class="hero-eyebrow">🤖 Intelligence Artificielle · XGBoost · Données PMU temps réel</div>
<h1>Pariez plus <span>intelligemment</span><br>grâce à l'IA</h1>
<p>Nos modèles XGBoost analysent chaque course PMU en temps réel — cotes, historique, jockeys, météo — pour vous donner les meilleures prédictions du marché.</p>
<div class="hero-actions">
<a href="/register" class="btn btn-primary btn-lg">Commencer gratuitement</a>
<a href="#how" class="btn btn-ghost btn-lg">Voir comment ça marche</a>
</div>
<div class="hero-stats">
<div class="stat"><strong>+73%</strong><span>précision Top-3</span></div>
<div class="stat"><strong>150+</strong><span>courses analysées/jour</span></div>
<div class="stat"><strong>2.4s</strong><span>temps de réponse moyen</span></div>
<div class="stat"><strong>3 plans</strong><span>adaptés à chaque profil</span></div>
</div>
</section>
<section id="features">
<div class="section-center">
<div class="section-label">Fonctionnalités</div>
<h2>Tout ce dont vous avez besoin pour gagner</h2>
<p class="subtitle">Un moteur IA complet, des alertes instantanées, et des analyses détaillées pour chaque parieur.</p>
</div>
<div class="features-grid">
<div class="feature-card"><div class="feature-icon">🧠</div><h3>Prédictions XGBoost</h3><p>Modèle entraîné sur des milliers de courses PMU. Probabilités Top-1 et Top-3 pour chaque partant, mis à jour en continu.</p></div>
<div class="feature-card"><div class="feature-icon">💎</div><h3>Value Bets identifiés</h3><p>Détection automatique des cotes sous-évaluées par le marché. Seulement les paris où l'espérance mathématique est positive.</p></div>
<div class="feature-card"><div class="feature-icon">📱</div><h3>Alertes Telegram</h3><p>Recevez les meilleures opportunités directement sur votre téléphone, avant le départ, avec toutes les infos clés.</p></div>
<div class="feature-card"><div class="feature-icon">📊</div><h3>Dashboard temps réel</h3><p>Tableau de bord complet : courses du jour, historique de performance, ROI, statistiques par hippodrome et discipline.</p></div>
<div class="feature-card"><div class="feature-icon">🌤️</div><h3>Analyse météo & terrain</h3><p>Impact des conditions météo et de l'état du terrain intégré dans chaque prédiction pour une précision maximale.</p></div>
<div class="feature-card"><div class="feature-icon">📤</div><h3>Export CSV & API</h3><p>Exportez vos données, intégrez nos prédictions dans vos propres outils via notre API documentée (plan Pro).</p></div>
</div>
</section>
<section id="how" style="background:var(--dark2);margin:0;border-top:1px solid var(--border);border-bottom:1px solid var(--border);">
<div class="section-center">
<div class="section-label">Comment ça marche</div>
<h2>En 3 étapes, prêt à parier</h2>
<p class="subtitle">De l'inscription à votre première prédiction en moins de 2 minutes.</p>
</div>
<div class="steps">
<div class="step"><div class="step-num">1</div><div class="step-body"><h3>Créez votre compte gratuitement</h3><p>Inscription en 30 secondes, sans carte bancaire. Accès immédiat au plan Free avec un aperçu des prédictions du jour.</p></div></div>
<div class="step"><div class="step-num">2</div><div class="step-body"><h3>Choisissez votre plan</h3><p>Free pour découvrir, Premium (9,90€/mois) pour toutes les courses et alertes, Pro (24,90€/mois) pour l'API et les exports.</p></div></div>
<div class="step"><div class="step-num">3</div><div class="step-body"><h3>Recevez vos premières prédictions</h3><p>Notre IA analyse les 150+ courses du jour. Accédez aux Top-3, value bets et probabilités depuis votre dashboard ou Telegram.</p></div></div>
</div>
</section>
<section id="pricing">
<div class="section-center">
<div class="section-label">Tarifs</div>
<h2>Des prix transparents</h2>
<p class="subtitle">Commencez gratuitement. Passez au niveau supérieur quand vous êtes prêt.</p>
</div>
<div class="pricing-grid">
<div class="plan-card">
<div class="plan-name">Free</div>
<div class="plan-price">0<sup></sup><span>/mois</span></div>
<p class="plan-desc">Pour découvrir la puissance de l'IA turf.</p>
<ul class="plan-features">
<li>Aperçu Top-3 du jour (limité)</li><li>1 course complète par jour</li><li>Statistiques basiques</li>
<li class="disabled">Alertes Telegram</li><li class="disabled">Toutes les courses</li><li class="disabled">Value bets</li>
</ul>
<a href="/register" class="btn btn-ghost btn-plan">Commencer gratuitement</a>
</div>
<div class="plan-card popular">
<div class="popular-badge">⭐ Le plus populaire</div>
<div class="plan-name">Premium</div>
<div class="plan-price">9<sup></sup>,90<span>/mois</span></div>
<p class="plan-desc">Pour les parieurs sérieux qui veulent un vrai avantage.</p>
<ul class="plan-features">
<li>Toutes les courses du jour</li><li>Prédictions Top-1 et Top-3</li><li>Value bets identifiés</li>
<li>Alertes Telegram configurables</li><li>Historique 90 jours</li><li>Analyse météo & terrain</li>
</ul>
<a href="/register?plan=premium" class="btn btn-primary btn-plan">Choisir Premium</a>
</div>
<div class="plan-card">
<div class="plan-name">Pro</div>
<div class="plan-price">24<sup></sup>,90<span>/mois</span></div>
<p class="plan-desc">Pour les professionnels et développeurs qui veulent tout.</p>
<ul class="plan-features">
<li>Tout du plan Premium</li><li>Export CSV illimité</li><li>Accès API REST documentée</li>
<li>Backtest personnalisé</li><li>Historique illimité</li><li>Support prioritaire</li>
</ul>
<a href="/register?plan=pro" class="btn btn-ghost btn-plan">Choisir Pro</a>
</div>
</div>
</section>
<section id="faq" style="background:var(--dark2);border-top:1px solid var(--border);border-bottom:1px solid var(--border);">
<div class="section-center">
<div class="section-label">FAQ</div>
<h2>Questions fréquentes</h2>
</div>
<div class="faq-list">
<details><summary>Comment fonctionne le modèle IA ?</summary><div class="faq-answer">Notre modèle XGBoost est entraîné sur plusieurs années de données PMU : cotes, historique des chevaux et drivers, conditions météo, état du terrain, statistiques par hippodrome. Il calcule pour chaque partant une probabilité d'arriver dans le Top-1 et Top-3.</div></details>
<details><summary>Les prédictions garantissent-elles des gains ?</summary><div class="faq-answer">Non. Aucune prédiction ne garantit des gains. Le pari hippique reste un jeu de hasard. Notre IA améliore vos chances en identifiant les opportunités statistiquement favorables. Pariez de façon responsable.</div></details>
<details><summary>Puis-je annuler à tout moment ?</summary><div class="faq-answer">Oui, sans engagement. Vous pouvez annuler votre abonnement Premium ou Pro à tout moment depuis votre espace compte.</div></details>
<details><summary>Les alertes Telegram fonctionnent-elles sur mobile ?</summary><div class="faq-answer">Oui. Après activation dans vos paramètres, vous recevrez les alertes value bets et top picks directement dans votre application Telegram.</div></details>
<details><summary>Quelles disciplines sont couvertes ?</summary><div class="faq-answer">Nous couvrons toutes les disciplines PMU : Plat, Trot Attelé, Trot Monté, et Galop sur les hippodromes français.</div></details>
</div>
</section>
<section>
<div class="cta-banner">
<h2>Prêt à parier plus intelligemment ?</h2>
<p>Rejoignez des centaines de parieurs qui utilisent déjà Turf IA chaque jour. Essai gratuit, sans carte bancaire.</p>
<a href="/register" class="btn btn-primary btn-lg">Créer mon compte gratuit →</a>
</div>
</section>
<footer>
<div class="footer-brand"><div style="font-weight:700;font-size:1.1rem;">🏇 Turf IA</div><p>Prédictions PMU par intelligence artificielle. Analyse XGBoost, value bets, alertes temps réel.</p></div>
<div class="footer-col"><h4>Produit</h4><a href="#features">Fonctionnalités</a><a href="#pricing">Tarifs</a><a href="/dashboard">Dashboard</a></div>
<div class="footer-col"><h4>Compte</h4><a href="/login">Connexion</a><a href="/register">Inscription</a><a href="/account">Mon compte</a></div>
<div class="footer-col"><h4>Légal</h4><a href="/legal/cgu">CGU</a><a href="/legal/privacy">Confidentialité</a><a href="/legal/cookies">Cookies</a></div>
</footer>
<div class="footer-bottom"><p>© 2026 Turf IA — H3R7 Tech. Tous droits réservés. Le jeu peut être dangereux, jouez de façon responsable. <strong>18+</strong></p></div>
<script>
document.querySelectorAll('a[href^="#"]').forEach(a => {
a.addEventListener('click', e => {
const t = document.querySelector(a.getAttribute('href'));
if (t) { e.preventDefault(); t.scrollIntoView({behavior:'smooth'}); }
});
});
</script>
</body>
</html>