Showing source for: https://maestroiptv.eu/index/
Duration: 0.394104s
Server: cloudflare
<!DOCTYPE html>
<html lang="fr">
<head>
<link rel="icon" type="image/png" href="https://maestroiptv.eu/fav.png?v=2">
<link rel="shortcut icon" href="https://maestroiptv.eu/fav.png?v=2">
<link rel="apple-touch-icon" href="https://maestroiptv.eu/fav.png?v=2">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MAESTRO IPTV â Le meilleur abonnement en Europe-Streaming Premium</title>
<meta name="description" content="MAESTRO IPTV â Plateforme OTT premium. Accès multi-appareils, installation rapide, support et offres flexibles.">
<meta name="robots" content="index,follow,max-image-preview:large">
<link rel="canonical" href="https://maestroiptv.eu/index/">
<meta name="theme-color" content="#000000">
<link rel="icon" href="/favicon.ico">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<!-- Open Graph -->
<meta property="og:title" content="MAESTRO IPTV â Plateforme OTT & Streaming Premium">
<meta property="og:description" content="Accès multi-appareils, offres flexibles, installation rapide, support.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://maestroiptv.eu/index/">
<meta property="og:image" content="https://maestroiptv.eu/index/img/maes.png">
<!-- Twitter -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="MAESTRO IPTV â Plateforme OTT & Streaming Premium">
<meta name="twitter:description" content="Accès multi-appareils, offres flexibles, installation rapide, support.">
<meta name="twitter:image" content="https://maestroiptv.eu/og.jpg">
<!-- Perf -->
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
<link rel="preconnect" href="https://cdn.tailwindcss.com" crossorigin>
<!-- â
Theme init BEFORE CSS/JS to avoid flicker -->
<script>
(function () {
const saved = localStorage.getItem('theme'); // 'dark' | 'light'
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
const useDark = saved ? (saved === 'dark') : prefersDark;
document.documentElement.classList.toggle('dark', useDark);
})();
</script>
<!-- â
Tailwind WITHOUT defer (important) -->
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" />
<!-- JSON-LD -->
<script type="application/ld+json">
{
"@context":"https://schema.org",
"@graph":[
{
"@type":"Organization",
"name":"MAESTRO IPTV",
"url":"https://maestroiptv.eu/index/",
"logo":"https://maestroiptv.eu/index/img/maes.png"
},
{
"@type":"WebSite",
"name":"MAESTRO IPTV",
"url":"https://maestroiptv.eu/index/",
"potentialAction":{
"@type":"SearchAction",
"target":"https://maestroiptv.eu/?q={search_term_string}",
"query-input":"required name=search_term_string"
}
}
]
}
</script>
<script>
tailwind.config = {
darkMode: 'class',
theme: {
extend: {
colors: {
'apple-light': '#f5f5f7',
'apple-dark': '#000000',
'apple-gray': '#86868b',
'apple-blue': '#0071e3',
'apple-card': '#ffffff',
'apple-card-dark': '#1d1d1f',
'apple-text': '#1d1d1f',
'apple-text-dark': '#f5f5f7'
},
fontFamily: {
'apple': ['-apple-system', 'BlinkMacSystemFont', 'San Francisco', 'Segoe UI', 'Roboto', 'Helvetica Neue', 'sans-serif']
}
}
}
}
</script>
<style>
* { font-family: -apple-system, BlinkMacSystemFont, 'San Francisco', 'Segoe UI', Roboto, Helvetica Neue, sans-serif; }
/* â
DO NOT set background/color here (Tailwind handles it) */
body{
line-height: 1.47059;
font-weight: 400;
letter-spacing: -.022em;
}
/* Navigation */
.apple-nav {
backdrop-filter: saturate(180%) blur(20px);
-webkit-backdrop-filter: saturate(180%) blur(20px);
background-color: rgba(255, 255, 255, 0.8);
transition: background-color 0.5s ease;
border-bottom: 1px solid rgba(0,0,0,0.06);
}
.dark .apple-nav {
background-color: rgba(0, 0, 0, 0.8);
border-bottom: 1px solid rgba(255,255,255,0.08);
}
.apple-nav-link {
color: #1d1d1f;
font-size: 12px;
line-height: 1;
font-weight: 500;
letter-spacing: -.01em;
transition: color 0.3s ease;
opacity: .92;
}
.dark .apple-nav-link { color: #f5f5f7; }
.apple-nav-link:hover { color: #86868b; opacity: 1; }
/* Hero */
.apple-hero {
background: linear-gradient(135deg, #000000 0%, #434343 100%);
padding-top: 120px;
padding-bottom: 80px;
position: relative;
overflow: hidden;
}
.dark .apple-hero {
background: linear-gradient(135deg, #000000 0%, #1d1d1f 100%);
}
/* Section Headers */
.apple-section-header {
font-size: 40px;
line-height: 1.1;
font-weight: 700;
letter-spacing: 0em;
}
.apple-section-subheader {
font-size: 21px;
line-height: 1.381;
font-weight: 400;
letter-spacing: .011em;
margin-top: 6px;
color: #86868b;
}
.dark .apple-section-subheader { color: #a1a1a6; }
/* Buttons */
.apple-button {
background: #0071e3;
color: #ffffff;
border-radius: 999px;
font-size: 17px;
line-height: 1.17648;
font-weight: 500;
letter-spacing: -.022em;
padding: 12px 22px;
transition: all 0.25s ease;
border: none;
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 10px;
text-align: center;
box-shadow: 0 10px 28px rgba(0,0,0,.08);
}
.apple-button:hover { background: #0077ed; transform: translateY(-1px) scale(1.01); }
.apple-button-secondary {
background: transparent;
color: #0071e3;
border: 1px solid #0071e3;
border-radius: 999px;
font-size: 17px;
line-height: 1.17648;
font-weight: 500;
letter-spacing: -.022em;
padding: 11px 21px;
transition: all 0.25s ease;
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.apple-button-secondary:hover { background: rgba(0, 113, 227, 0.1); transform: translateY(-1px); }
/* Tabs (Catalogue) */
.apple-tabs {
display: flex;
border-bottom: 1px solid #d2d2d7;
margin-bottom: 30px;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
gap: 8px;
}
.dark .apple-tabs { border-bottom: 1px solid #424245; }
.apple-tab {
padding: 10px 16px;
font-size: 15px;
line-height: 1.17648;
font-weight: 500;
letter-spacing: -.022em;
color: #86868b;
border-bottom: 2px solid transparent;
transition: all 0.25s ease;
white-space: nowrap;
background: none;
border: none;
cursor: pointer;
border-radius: 999px;
}
.dark .apple-tab { color: #a1a1a6; }
.apple-tab.active {
color: #ffffff;
background: #0071e3;
border-bottom-color: transparent;
}
.apple-tab:hover:not(.active) { background: rgba(0,0,0,.04); color: #1d1d1f; }
.dark .apple-tab:hover:not(.active) { background: rgba(255,255,255,.07); color: #f5f5f7; }
/* Search */
.apple-search-container { position: relative; margin: 0 auto 30px; max-width: 520px; }
.apple-search-input {
width: 100%;
padding: 12px 45px 12px 18px;
border-radius: 999px;
border: 1px solid #d2d2d7;
background: rgba(255,255,255,.92);
color: #1d1d1f;
font-size: 17px;
transition: all 0.25s ease;
}
.dark .apple-search-input {
background: rgba(29,29,31,.92);
border-color: #424245;
color: #f5f5f7;
}
.apple-search-input:focus {
outline: none;
border-color: #0071e3;
box-shadow: 0 0 0 4px rgba(0, 113, 227, 0.12);
}
.apple-search-icon { position: absolute; right: 15px; top: 50%; transform: translateY(-50%); color: #86868b; }
.dark .apple-search-icon { color: #a1a1a6; }
/* ===== Apple TV+ Catalogue Cards (NO LOGOS) ===== */
/* â
Catalogue en carrousel 1 ligne (desktop + mobile) */
.tv-grid{
display:flex;
flex-wrap:nowrap;
overflow-x:auto;
gap:16px;
padding: 8px 4px 18px;
scroll-snap-type:x mandatory;
-webkit-overflow-scrolling: touch;
}
.tv-grid > .tv-card{
flex: 0 0 180px; /* largeur carte */
scroll-snap-align:start;
}
@media (max-width: 768px){
.tv-grid > .tv-card{ flex-basis: 160px; }
}
/* optionnel: scroll plus âsmoothâ */
.tv-grid{ scroll-behavior:smooth; }
/* optionnel: scrollbar plus propre */
.tv-grid::-webkit-scrollbar{ height: 8px; }
.tv-grid::-webkit-scrollbar-thumb{ border-radius: 999px; }
.tv-card{
--rx: 0deg; --ry: 0deg; --mx: 0px; --my: 0px;
position:relative; border-radius:18px; overflow:hidden;
background: rgba(255,255,255,.92); border: 1px solid rgba(0,0,0,.06);
box-shadow: 0 10px 30px rgba(0,0,0,.06);
transition: transform .35s ease, box-shadow .35s ease;
transform: translateY(0) scale(1) rotateX(var(--rx)) rotateY(var(--ry));
will-change: transform;
}
.dark .tv-card{
background: rgba(29,29,31,.92);
border-color: rgba(255,255,255,.08);
box-shadow: 0 20px 60px rgba(0,0,0,.32);
}
.tv-card::before{
content:""; position:absolute; inset:0; padding:1px; border-radius:18px;
background: linear-gradient(135deg, rgba(0,113,227,.65), rgba(255,255,255,.25), rgba(0,0,0,0));
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
-webkit-mask-composite: xor; mask-composite: exclude;
opacity:0; transition: opacity .35s ease; pointer-events:none;
}
.tv-card:hover::before{ opacity:.95; }
.tv-card:hover{ transform: translateY(-6px) scale(1.02) rotateX(var(--rx)) rotateY(var(--ry)); box-shadow: 0 24px 70px rgba(0,0,0,.16); }
.dark .tv-card:hover{ box-shadow: 0 34px 90px rgba(0,0,0,.5); }
.tv-poster{ aspect-ratio:2/3; width:100%; position:relative; overflow:hidden; background:#f5f5f7; }
.dark .tv-poster{ background:#1d1d1f; }
.tv-poster-img{
position:absolute; inset:0;
transform: scale(1.03) translate(var(--mx), var(--my));
transition: transform .45s ease; will-change: transform;
background-size:cover; background-position:center;
}
.tv-card:hover .tv-poster-img{ transform: scale(1.10) translate(var(--mx), var(--my)); }
.tv-poster-generic{
background:
radial-gradient(900px 450px at 20% 15%, hsla(var(--h) 90% 70% / .40), transparent 60%),
radial-gradient(700px 350px at 80% 25%, hsla(calc(var(--h) + 40) 90% 60% / .26), transparent 60%),
linear-gradient(180deg, rgba(0,0,0,.06), rgba(0,0,0,.78));
}
.dark .tv-poster-generic{
background:
radial-gradient(900px 450px at 20% 15%, hsla(var(--h) 90% 65% / .25), transparent 60%),
radial-gradient(700px 350px at 80% 25%, hsla(calc(var(--h) + 40) 90% 55% / .18), transparent 60%),
linear-gradient(180deg, rgba(0,0,0,.12), rgba(0,0,0,.85));
}
.tv-icon-chip{
position:absolute; top:12px; left:12px;
display:inline-flex; align-items:center; gap:8px;
padding:8px 10px; border-radius:999px;
background: rgba(255,255,255,.14);
border: 1px solid rgba(255,255,255,.18);
backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
color:#fff; font-size:12px; font-weight:700; z-index:2;
}
.tv-badge{
position:absolute; top:12px; right:12px;
padding:7px 10px; border-radius:999px;
background: rgba(0,0,0,.50); color:#fff;
font-size:11px; font-weight:900; letter-spacing:.06em; text-transform:uppercase;
backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); z-index:2;
}
.tv-meta{ padding: 12px 12px 14px; }
.tv-title{
font-weight: 800; font-size: 14px; line-height: 1.25; color: #1d1d1f;
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
overflow:hidden; min-height: 35px;
}
.dark .tv-title{ color: #f5f5f7; }
.tv-sub{ margin-top: 8px; display:flex; gap:8px; flex-wrap:wrap; }
.tv-pill{
font-size: 11px; font-weight: 700; padding: 5px 10px; border-radius: 999px;
border: 1px solid rgba(134,134,139,.35); color: #1d1d1f;
background: rgba(255,255,255,.75); backdrop-filter: blur(10px);
}
.dark .tv-pill{ color:#f5f5f7; border-color: rgba(161,161,166,.35); background: rgba(29,29,31,.55); }
@keyframes shimmer { 0%{ background-position:-600px 0; } 100%{ background-position:600px 0; } }
.skeleton{
background: linear-gradient(90deg, rgba(210,210,215,.65) 25%, rgba(245,245,247,.95) 50%, rgba(210,210,215,.65) 75%);
background-size: 1200px 100%;
animation: shimmer 1.15s infinite linear;
border-radius: 16px;
}
.dark .skeleton{
background: linear-gradient(90deg, rgba(66,66,69,.65) 25%, rgba(29,29,31,.95) 50%, rgba(66,66,69,.65) 75%);
background-size: 1200px 100%;
}
/* Compétitions */
.match-card{ background: rgba(255,255,255,.92); border-radius: 20px; padding: 18px; border: 1px solid rgba(0,0,0,.06); box-shadow: 0 10px 30px rgba(0,0,0,.06); transition: transform .35s ease, box-shadow .35s ease; }
.dark .match-card{ background: rgba(29,29,31,.92); border-color: rgba(255,255,255,.08); box-shadow: 0 20px 60px rgba(0,0,0,.32); }
.match-card:hover{ transform: translateY(-6px); box-shadow: 0 24px 70px rgba(0,0,0,.16); }
.match-head{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom: 12px; }
.match-competition{ font-weight: 800; font-size: 13px; color: #1d1d1f; display:flex; align-items:center; gap:8px; }
.dark .match-competition{ color:#f5f5f7; }
.match-time{ font-size: 12px; color: #86868b; display:flex; align-items:center; gap:6px; white-space:nowrap; }
.dark .match-time{ color:#a1a1a6; }
.match-status{ padding: 5px 10px; border-radius: 999px; font-size: 11px; font-weight: 900; letter-spacing: .06em; text-transform: uppercase; white-space:nowrap; }
.status-live{ background:#ff3b30; color:#fff; }
.status-upcoming{ background:#0071e3; color:#fff; }
.status-finished{ background:#34c759; color:#fff; }
@keyframes pulse { 0%{opacity:1} 50%{opacity:.55} 100%{opacity:1} }
.live-pulse{ animation: pulse 1.7s infinite; }
.match-teams{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top: 12px; }
.team{ flex:1; display:flex; flex-direction:column; align-items:center; text-align:center; gap:6px; }
.team-logo{ width: 54px; height: 54px; border-radius: 999px; background: rgba(0,0,0,.05); display:flex; align-items:center; justify-content:center; font-weight: 900; font-size: 16px; letter-spacing: .03em; color:#1d1d1f; border: 1px solid rgba(0,0,0,.06); }
.dark .team-logo{ background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.10); color:#fff; }
.team-name{ font-weight: 800; font-size: 13px; color:#1d1d1f; }
.dark .team-name{ color:#f5f5f7; }
.match-mid{ min-width: 78px; text-align:center; display:flex; flex-direction:column; align-items:center; gap:6px; }
.match-score{ font-size: 22px; font-weight: 900; letter-spacing: -.02em; }
.match-vs{ font-size: 14px; font-weight: 800; color: #86868b; letter-spacing: .08em; }
.dark .match-vs{ color:#a1a1a6; }
.match-foot{ margin-top: 14px; display:flex; justify-content:space-between; align-items:center; gap:10px; color:#86868b; font-size: 12px; }
.dark .match-foot{ color:#a1a1a6; }
/* FAQ */
.faq-item { margin-bottom: 10px; }
.faq-question { cursor: pointer; padding: 15px 0; border-bottom: 1px solid #d2d2d7; }
.dark .faq-question { border-bottom: 1px solid #424245; }
.faq-answer { padding: 15px 0; display: none; }
.faq-answer.active { display: block; }
/* Modal */
.modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); z-index: 1000; align-items: center; justify-content: center; }
.modal.active { display: flex; }
.modal-content { background: #ffffff; border-radius: 18px; padding: 30px; width: 90%; max-width: 520px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); }
.dark .modal-content { background: #1d1d1f; }
/* Toast */
.toast { position: fixed; bottom: 20px; right: 20px; background: #1d1d1f; color: #ffffff; padding: 15px 20px; border-radius: 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); z-index: 1001; display: none; }
.dark .toast { background: #ffffff; color: #1d1d1f; }
/* Blog */
.blog-article-card { background: #ffffff; border-radius: 16px; overflow: hidden; transition: all 0.3s ease; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); border: 1px solid #f0f0f0; height: 100%; display: flex; flex-direction: column; }
.dark .blog-article-card { background: #1d1d1f; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); border: 1px solid #333; }
.blog-article-card:hover { transform: translateY(-8px); box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1); }
.dark .blog-article-card:hover { box-shadow: 0 12px 24px rgba(0, 0, 0, 0.25); }
.article-image { height: 200px; background-size: cover; background-position: center; position: relative; }
.article-badge { position: absolute; top: 12px; left: 12px; padding: 6px 12px; border-radius: 8px; font-size: 12px; font-weight: 700; color: white; }
.badge-installation { background: linear-gradient(135deg, #0071e3, #0056b3); }
.badge-guides { background: linear-gradient(135deg, #34c759, #28a745); }
.badge-sport { background: linear-gradient(135deg, #ff3b30, #d70015); }
.badge-default { background: linear-gradient(135deg, #8e8e93, #6e6e73); }
.article-content { padding: 20px; flex: 1; display: flex; flex-direction: column; }
.article-date { color: #86868b; font-size: 14px; margin-bottom: 8px; display: flex; align-items: center; }
.dark .article-date { color: #a1a1a6; }
.article-date i { margin-right: 6px; }
.article-title { font-size: 18px; font-weight: 700; line-height: 1.4; margin-bottom: 12px; color: #1d1d1f; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.dark .article-title { color: #f5f5f7; }
.article-excerpt { color: #86868b; font-size: 14px; line-height: 1.5; margin-bottom: 16px; flex: 1; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.dark .article-excerpt { color: #a1a1a6; }
.article-read-more { display: inline-flex; align-items: center; color: #0071e3; font-weight: 600; font-size: 14px; text-decoration: none; transition: all 0.3s ease; }
.article-read-more:hover { color: #0056b3; transform: translateX(4px); }
.article-read-more i { margin-left: 6px; transition: transform 0.3s ease; }
.article-read-more:hover i { transform: translateX(4px); }
@media (max-width: 768px) {
.apple-section-header { font-size: 32px; }
.apple-section-subheader { font-size: 18px; }
}
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: #f5f5f7; }
.dark ::-webkit-scrollbar-track { background: #1d1d1f; }
::-webkit-scrollbar-thumb { background: #d2d2d7; border-radius: 8px; }
.dark ::-webkit-scrollbar-thumb { background: #424245; }
::-webkit-scrollbar-thumb:hover { background: #86868b; }
.dark ::-webkit-scrollbar-thumb:hover { background: #6e6e73; }
.comp-card{
background: rgba(255,255,255,.92);
border: 1px solid rgba(0,0,0,.06);
border-radius: 24px;
padding: 18px;
box-shadow: 0 10px 30px rgba(0,0,0,.06);
transition: transform .35s ease, box-shadow .35s ease;
}
.dark .comp-card{
background: rgba(29,29,31,.92);
border-color: rgba(255,255,255,.08);
box-shadow: 0 20px 60px rgba(0,0,0,.32);
}
.comp-card:hover{
transform: translateY(-6px);
box-shadow: 0 24px 70px rgba(0,0,0,.16);
}
.comp-badge{
display:inline-flex; align-items:center; gap:8px;
padding:8px 10px; border-radius:999px;
background: rgba(0,113,227,.12);
color:#0071e3;
font-size:12px; font-weight:800;
}
.dark .comp-badge{ background: rgba(0,113,227,.22); color:#7bb5ff; }
.comp-meta{ color:#86868b; font-size:12px; }
.dark .comp-meta{ color:#a1a1a6; }
</style>
</head>
<body class="dark:bg-apple-dark bg-apple-light dark:text-apple-text-dark text-apple-text">
<!-- Navigation -->
<nav class="apple-nav fixed top-0 left-0 right-0 z-50 py-4 px-6">
<div class="max-w-7xl mx-auto flex justify-between items-center">
<a href="#home" class="flex items-center group">
<img
src="/index/img/maes.png"
alt="Maestro IPTV"
class="h-12 w-auto object-contain transition-transform duration-300 group-hover:scale-105"
>
</a>
<div class="hidden md:flex space-x-8">
<a href="#home" class="apple-nav-link">Accueil</a>
<a href="#catalogue" class="apple-nav-link">Catalogue</a>
<a href="#matches" class="apple-nav-link">Compétitions</a>
<a href="#installation" class="apple-nav-link">Installation</a>
<a href="#blog" class="apple-nav-link">Blog</a>
<a href="#offers" class="apple-nav-link">Abonnements</a>
<a href="#devices" class="apple-nav-link">Appareils</a>
<a href="#support" class="apple-nav-link">Aide</a>
<a href="https://maestroiptv.eu/system/clientarea/" class="apple-nav-link">
<i class="fas fa-user mr-1"></i> Mon Compte
</a>
</div>
<div class="flex items-center space-x-4">
<button id="theme-toggle" class="apple-nav-link" aria-label="Theme">
<i class="fas fa-moon dark-mode-icon"></i>
<i class="fas fa-sun light-mode-icon hidden"></i>
</button>
<button id="lang-toggle" class="apple-nav-link" aria-label="Langue">
<span class="flag">ð«ð·</span>
</button>
<button id="mobileMenuBtn" class="apple-button md:hidden" type="button">
<i class="fas fa-bars"></i> Menu
</button>
</div>
</div>
<!-- Mobile menu -->
<div id="mobileMenu" class="hidden md:hidden max-w-7xl mx-auto pt-4">
<div class="flex flex-col gap-3 pb-2">
<a href="#home" class="apple-nav-link">Accueil</a>
<a href="#catalogue" class="apple-nav-link">Catalogue</a>
<a href="#matches" class="apple-nav-link">Compétitions</a>
<a href="#installation" class="apple-nav-link">Installation</a>
<a href="#blog" class="apple-nav-link">Blog</a>
<a href="#offers" class="apple-nav-link">Abonnements</a>
<a href="#devices" class="apple-nav-link">Appareils</a>
<a href="#support" class="apple-nav-link">Aide</a>
<a href="https://maestroiptv.eu/system/clientarea/" class="apple-nav-link">
<i class="fas fa-user mr-1"></i> Mon Compte
</a>
</div>
</div>
</nav>
<!-- Hero Section (images kept) -->
<section class="apple-hero relative overflow-hidden h-screen text-white" id="home">
<div class="">
<!-- Slide 1 -->
<div class="absolute inset-0 slide active" data-bg="https://t4.ftcdn.net/jpg/17/53/65/73/240_F_1753657346_LLf3HUMR5bIDAKGiZNwkxo5CJeQEWojR.jpg">
<div class="absolute inset-0 bg-gradient-to-br from-black/70 via-transparent to-black/50 backdrop-blur-sm"></div>
<div class="relative z-10 flex flex-col items-center justify-center h-full text-center px-6">
<div class="inline-flex items-center gap-2 bg-white/10 backdrop-blur-md px-4 py-2 rounded-full border border-white/20 mb-8 animate-fade-in">
<div class="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
<span class="text-sm font-medium text-white/90">PLATEFORME OTT</span>
</div>
<h1 class="text-6xl md:text-7xl font-thin tracking-tight mb-4 animate-slide-up">
MAESTRO <span class="font-medium bg-gradient-to-r from-white to-gray-300 bg-clip-text text-transparent">IPTV</span>
</h1>
<h2 class="text-xl md:text-2xl font-light text-white/80 mb-8 tracking-wide animate-slide-up delay-100">
Streaming premium <span class="text-blue-300 font-normal">multi-appareils</span>
</h2>
<div class="glass-card bg-white/5 backdrop-blur-sm border border-white/10 rounded-2xl p-6 max-w-2xl mx-auto mb-8 animate-slide-up delay-200">
<p class="text-lg text-white/80 leading-relaxed">
Accédez à des contenus via notre plateforme OTT.
<span class="block mt-2 text-white/90 font-medium">Disponibilité selon la région et les droits/licences.</span>
</p>
</div>
<div class="flex flex-col sm:flex-row items-center justify-center gap-4 animate-slide-up delay-300">
<button class="group bg-white text-black px-8 py-4 rounded-full font-medium hover:bg-gray-100 transition-all duration-300 transform hover:scale-105 shadow-2xl">
<span class="flex items-center gap-2">
<i class="fas fa-play-circle"></i>
<a href="#offers">Voir les offres</a>
<i class="fas fa-arrow-right transition-transform group-hover:translate-x-1"></i>
</span>
</button>
<button class="group bg-transparent border border-white/30 text-white px-8 py-4 rounded-full font-medium hover:bg-white/10 hover:border-white/50 transition-all duration-300">
<span class="flex items-center gap-2">
<a href="#support">Support & Aide</a>
<i class="fas fa-chevron-down transition-transform group-hover:translate-y-1"></i>
</span>
</button>
</div>
<div class="flex flex-wrap justify-center gap-4 mt-12 text-white/70 text-sm animate-fade-in delay-500">
<div class="flex items-center gap-2 bg-white/5 backdrop-blur-sm px-3 py-2 rounded-lg">
<i class="fas fa-hd text-blue-400"></i><span>HD / 4K*</span>
</div>
<div class="flex items-center gap-2 bg-white/5 backdrop-blur-sm px-3 py-2 rounded-lg">
<i class="fas fa-bolt text-green-400"></i><span>Expérience fluide</span>
</div>
<div class="flex items-center gap-2 bg-white/5 backdrop-blur-sm px-3 py-2 rounded-lg">
<i class="fas fa-headset text-purple-400"></i><span>Support</span>
</div>
</div>
</div>
</div>
<!-- Slide 2 -->
<div class="absolute inset-0 slide" data-bg="https://t3.ftcdn.net/jpg/02/86/98/82/240_F_286988248_Mkd5IXsJCQ2hMQmyMiPu87tdKSNyKgHW.jpg">
<div class="absolute inset-0 bg-gradient-to-br from-blue-900/60 via-transparent to-blue-900/40 backdrop-blur-sm"></div>
<div class="relative z-10 flex flex-col items-center justify-center h-full text-center px-6">
<div class="inline-flex items-center gap-2 bg-white/10 backdrop-blur-md px-4 py-2 rounded-full border border-white/20 mb-8 animate-fade-in">
<i class="fas fa-layer-group text-yellow-400"></i>
<span class="text-sm font-medium text-white/90">CATALOGUE</span>
</div>
<h2 class="text-6xl md:text-7xl font-thin tracking-tight mb-4 animate-slide-up">
Catalogue <span class="font-medium bg-gradient-to-r from-white to-blue-200 bg-clip-text text-transparent">Ã jour</span>
</h2>
<h3 class="text-xl md:text-2xl font-light text-white/80 mb-8 tracking-wide animate-slide-up delay-100">
Films, séries, replays & live <span class="text-blue-300 font-normal">selon disponibilité</span>
</h3>
<div class="glass-card bg-white/5 backdrop-blur-md border border-white/10 rounded-2xl p-6 max-w-2xl mx-auto mb-8 animate-slide-up delay-200">
<p class="text-lg text-white/80 leading-relaxed">
Une expérience claire et rapide.
<span class="block mt-2 text-white/90 font-medium">Le contenu peut varier selon la zone et les droits.</span>
</p>
</div>
<button class="group bg-white text-blue-600 px-8 py-4 rounded-full font-medium hover:bg-gray-100 transition-all duration-300 transform hover:scale-105 shadow-2xl animate-slide-up delay-450">
<span class="flex items-center gap-2">
<a href="#catalogue">Découvrir le catalogue</a>
<i class="fas fa-arrow-right transition-transform group-hover:translate-x-1"></i>
</span>
</button>
</div>
</div>
<!-- Slide 3 -->
<div class="absolute inset-0 slide" data-bg="https://t4.ftcdn.net/jpg/09/29/43/29/240_F_929432903_PwrBq6F2WBtJsSAD6BR9NKoCi8ybHRsU.jpg">
<div class="absolute inset-0 bg-gradient-to-br from-purple-900/60 via-transparent to-purple-900/40 backdrop-blur-sm"></div>
<div class="relative z-10 flex flex-col items-center justify-center h-full text-center px-6">
<div class="inline-flex items-center gap-2 bg-white/10 backdrop-blur-md px-4 py-2 rounded-full border border-white/20 mb-8 animate-fade-in">
<i class="fas fa-star text-yellow-400"></i>
<span class="text-sm font-medium text-white/90">OFFRES</span>
</div>
<h2 class="text-6xl md:text-7xl font-thin tracking-tight mb-4 animate-slide-up">
Abonnements <span class="font-medium bg-gradient-to-r from-white to-purple-200 bg-clip-text text-transparent">flexibles</span>
</h2>
<h3 class="text-xl md:text-2xl font-light text-white/80 mb-8 tracking-wide animate-slide-up delay-100">
Formules adaptées à <span class="text-purple-300 font-normal">vos besoins</span>
</h3>
<div class="glass-card bg-white/5 backdrop-blur-md border border-white/10 rounded-2xl p-6 max-w-2xl mx-auto mb-8 animate-slide-up delay-200">
<p class="text-lg text-white/80 leading-relaxed">
Formules 1 Ã 12 mois.
<span class="block mt-2 text-white/90 font-medium">Accès multi-appareils + guides + support.</span>
</p>
</div>
<button class="group bg-white text-purple-600 px-8 py-4 rounded-full font-medium hover:bg-gray-100 transition-all duration-300 transform hover:scale-105 shadow-2xl animate-slide-up delay-450">
<span class="flex items-center gap-2">
<a href="#offers">Voir les offres</a>
<i class="fas fa-arrow-right transition-transform group-hover:translate-x-1"></i>
</span>
</button>
</div>
</div>
<!-- Slide 4 -->
<div class="absolute inset-0 slide" data-bg="https://t3.ftcdn.net/jpg/08/08/71/02/240_F_808710204_AgFLGK6qHuM02XCtz1FDYxqahi28mvSe.jpg">
<div class="absolute inset-0 bg-gradient-to-br from-green-900/60 via-transparent to-green-900/40 backdrop-blur-sm"></div>
<div class="relative z-10 flex flex-col items-center justify-center h-full text-center px-6">
<div class="inline-flex items-center gap-2 bg-white/10 backdrop-blur-md px-4 py-2 rounded-full border border-white/20 mb-8 animate-fade-in">
<i class="fas fa-download text-green-400"></i>
<span class="text-sm font-medium text-white/90">INSTALLATION</span>
</div>
<h2 class="text-6xl md:text-7xl font-thin tracking-tight mb-4 animate-slide-up">
Configuration <span class="font-medium bg-gradient-to-r from-white to-green-200 bg-clip-text text-transparent">rapide</span>
</h2>
<h3 class="text-xl md:text-2xl font-light text-white/80 mb-8 tracking-wide animate-slide-up delay-100">
Guide complet & <span class="text-green-300 font-normal">assistance</span>
</h3>
<div class="glass-card bg-white/5 backdrop-blur-md border border-white/10 rounded-2xl p-6 max-w-2xl mx-auto mb-8 animate-slide-up delay-200">
<p class="text-lg text-white/80 leading-relaxed">
Compatible avec plusieurs appareils (selon lâapplication).
<span class="block mt-2 text-white/90 font-medium">Suivez notre guide étape par étape.</span>
</p>
</div>
<button class="group bg-white text-green-600 px-8 py-4 rounded-full font-medium hover:bg-gray-100 transition-all duration-300 transform hover:scale-105 shadow-2xl animate-slide-up delay-450">
<span class="flex items-center gap-2">
<a href="#installation">Guide d'installation</a>
<i class="fas fa-arrow-right transition-transform group-hover:translate-x-1"></i>
</span>
</button>
</div>
</div>
<!-- Slide 5 -->
<div class="absolute inset-0 slide" data-bg="https://images.unsplash.com/photo-1581091012184-7c0d1b7f92d3?auto=format&fit=crop&w=2070&q=80">
<div class="absolute inset-0 bg-gradient-to-br from-yellow-900/60 via-transparent to-yellow-900/40 backdrop-blur-sm"></div>
<div class="relative z-10 flex flex-col items-center justify-center h-full text-center px-6">
<div class="inline-flex items-center gap-2 bg-white/10 backdrop-blur-md px-4 py-2 rounded-full border border-white/20 mb-8 animate-fade-in">
<i class="fas fa-newspaper text-yellow-400"></i>
<span class="text-sm font-medium text-white/90">BLOG</span>
</div>
<h2 class="text-6xl md:text-7xl font-thin tracking-tight mb-4 animate-slide-up">
Blog & <span class="font-medium bg-gradient-to-r from-white to-yellow-200 bg-clip-text text-transparent">Guides</span>
</h2>
<h3 class="text-xl md:text-2xl font-light text-white/80 mb-8 tracking-wide animate-slide-up delay-100">
Conseils et <span class="text-yellow-300 font-normal">astuces</span>
</h3>
<div class="glass-card bg-white/5 backdrop-blur-md border border-white/10 rounded-2xl p-6 max-w-2xl mx-auto mb-8 animate-slide-up delay-200">
<p class="text-lg text-white/80 leading-relaxed">
Guides, astuces et actualités.
<span class="block mt-2 text-white/90 font-medium">Restez informé des nouveautés.</span>
</p>
</div>
<button class="group bg-white text-yellow-600 px-8 py-4 rounded-full font-medium hover:bg-gray-100 transition-all duration-300 transform hover:scale-105 shadow-2xl animate-slide-up delay-450">
<span class="flex items-center gap-2">
<a href="#blog">Lire le blog</a>
<i class="fas fa-arrow-right transition-transform group-hover:translate-x-1"></i>
</span>
</button>
</div>
</div>
</div>
<!-- Navigation -->
<button id="prevBtn" class="absolute left-6 top-1/2 transform -translate-y-1/2 bg-black/20 hover:bg-black/40 text-white w-12 h-12 rounded-full flex items-center justify-center z-10 backdrop-blur-md border border-white/20 transition-all duration-300" aria-label="Slide précédent">
<i class="fas fa-chevron-left text-sm"></i>
</button>
<button id="nextBtn" class="absolute right-6 top-1/2 transform -translate-y-1/2 bg-black/20 hover:bg-black/40 text-white w-12 h-12 rounded-full flex items-center justify-center z-10 backdrop-blur-md border border-white/20 transition-all duration-300" aria-label="Slide suivant">
<i class="fas fa-chevron-right text-sm"></i>
</button>
<!-- Indicators -->
<div class="absolute bottom-8 left-1/2 transform -translate-x-1/2 flex gap-2 z-10">
<button class="indicator w-2 h-2 bg-white/60 rounded-full hover:bg-white transition-all duration-300 backdrop-blur-sm active" data-slide="0"></button>
<button class="indicator w-2 h-2 bg-white/60 rounded-full hover:bg-white transition-all duration-300 backdrop-blur-sm" data-slide="1"></button>
<button class="indicator w-2 h-2 bg-white/60 rounded-full hover:bg-white transition-all duration-300 backdrop-blur-sm" data-slide="2"></button>
<button class="indicator w-2 h-2 bg-white/60 rounded-full hover:bg-white transition-all duration-300 backdrop-blur-sm" data-slide="3"></button>
<button class="indicator w-2 h-2 bg-white/60 rounded-full hover:bg-white transition-all duration-300 backdrop-blur-sm" data-slide="4"></button>
</div>
</section>
<!-- Hero helper styles + script -->
<style>
.glass-card { backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); }
@keyframes slide-up { from {opacity:0; transform: translateY(40px);} to {opacity:1; transform: translateY(0);} }
@keyframes fade-in { from {opacity:0;} to {opacity:1;} }
.animate-slide-up { animation: slide-up 0.8s ease-out forwards; opacity: 0; }
.animate-fade-in { animation: fade-in 0.8s ease-out forwards; opacity: 0; }
.animate-slide-up.delay-100 { animation-delay: 0.1s; }
.animate-slide-up.delay-200 { animation-delay: 0.2s; }
.animate-slide-up.delay-300 { animation-delay: 0.3s; }
.animate-fade-in.delay-500 { animation-delay: 0.5s; }
.slide { opacity: 0; pointer-events:none; transition: opacity 0.8s ease-in-out; }
.slide.active { opacity: 1; pointer-events: all; }
</style>
<script>
// Appliquer automatiquement les images de fond
document.querySelectorAll('.slide').forEach(slide => {
const bg = slide.getAttribute('data-bg');
if (bg) slide.style.background = `url('${bg}') center/cover no-repeat`;
});
// Carousel
let currentSlide = 0;
const slides = document.querySelectorAll('.slide');
const indicators = document.querySelectorAll('.indicator');
const totalSlides = slides.length;
let slideInterval = setInterval(nextSlide, 5000);
function showSlide(index){
slides.forEach(s => s.classList.remove('active'));
indicators.forEach(i => i.classList.remove('active'));
slides[index].classList.add('active');
indicators[index].classList.add('active');
currentSlide = index;
clearInterval(slideInterval);
slideInterval = setInterval(nextSlide, 5000);
}
function nextSlide(){ showSlide((currentSlide + 1) % totalSlides); }
function prevSlide(){ showSlide((currentSlide - 1 + totalSlides) % totalSlides); }
document.getElementById('nextBtn').addEventListener('click', nextSlide);
document.getElementById('prevBtn').addEventListener('click', prevSlide);
indicators.forEach((i, idx)=> i.addEventListener('click', ()=> showSlide(idx)));
const carousel = document.getElementById('home');
carousel.addEventListener('mouseenter', ()=> clearInterval(slideInterval));
carousel.addEventListener('mouseleave', ()=> slideInterval = setInterval(nextSlide,5000));
</script>
<!-- Catalogue Section -->
<section class="py-20 px-6 bg-apple-light dark:bg-apple-dark" id="catalogue">
<div class="max-w-7xl mx-auto">
<h2 class="apple-section-header text-center">Accès complet avec un seul abonnement</h2>
<div class="apple-tabs justify-center mt-12" id="catalogueTabs">
<button class="apple-tab active" data-category="chaines">Chaînes</button>
<button class="apple-tab" data-category="live">Live</button>
<button class="apple-tab" data-category="replay">Replays</button>
<button class="apple-tab" data-category="movies">Films</button>
<button class="apple-tab" data-category="series">Séries</button>
<button class="apple-tab" data-category="radio">Radio</button>
<button class="apple-tab" data-category="ppv">PPV</button>
</div>
<div class="apple-search-container">
<input class="apple-search-input" id="searchInput" placeholder="Rechercher..." type="search"/>
<i class="fas fa-search apple-search-icon"></i>
</div>
<div class="catalogue-container">
<div class="tv-grid" id="mediaGrid"></div>
</div>
<div class="catalogue-footer text-center mt-12">
<button class="apple-button md:inline-flex hidden" id="loadMoreBtn"><i class="fas fa-plus"></i> Voir plus</button>
<button class="apple-button md:hidden inline-flex" id="loadMoreBtnMobile"><i class="fas fa-plus"></i> Voir plus</button>
</div>
</div>
</section>
<!-- Compétitions -->
<!-- â
Compétitions (NEW) -->
<section class="py-20 px-6 bg-white dark:bg-black" id="matches">
<div class="max-w-7xl mx-auto">
<h2 class="apple-section-header text-center">Compétitions & Ligues</h2>
<p class="apple-section-subheader text-center max-w-3xl mx-auto mt-4">
Explorez les grandes compétitions. La disponibilité peut varier selon la région et les droits/licences.
</p>
<div class="mt-6 border-b border-gray-200 dark:border-gray-700"></div>
<!-- Tabs -->
<div class="apple-tabs justify-center mt-12" id="compTabs">
<button class="apple-tab active" data-comp="football"><i class="fas fa-futbol mr-2"></i>Football</button>
<button class="apple-tab" data-comp="basket"><i class="fas fa-basketball-ball mr-2"></i>Basket</button>
<button class="apple-tab" data-comp="tennis"><i class="fas fa-table-tennis-paddle-ball mr-2"></i>Tennis</button>
<button class="apple-tab" data-comp="motorsport"><i class="fas fa-flag-checkered mr-2"></i>Motorsport</button>
</div>
<!-- Cards -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mt-8" id="compGrid"></div>
<!-- CTA -->
<div class="mt-12 flex flex-col sm:flex-row items-center justify-center gap-4">
<a href="#offers" class="apple-button"><i class="fas fa-tags"></i> Voir les offres</a>
<a href="#support" class="apple-button-secondary"><i class="fas fa-headset"></i> Besoin dâaide ?</a>
</div>
<!-- Note -->
</div>
</section>
<!-- Offers Section -->
<section id="offers" class="py-8 transition-colors duration-500 bg-white dark:bg-black text-gray-900 dark:text-gray-100">
<div class="max-w-7xl mx-auto px-6">
<h2 class="text-5xl font-semibold text-center tracking-tight">Nos Offres</h2>
<p class="text-lg text-center text-gray-500 dark:text-gray-400 mt-4 max-w-2xl mx-auto">
Choisissez l'abonnement qui correspond à vos besoins
</p>
<div class="mt-6 border-b border-gray-200 dark:border-gray-700"></div>
<div class="flex justify-center gap-6 mt-12">
<button class="tab-btn px-6 py-2 rounded-full border border-gray-300 dark:border-gray-700 text-gray-900 dark:text-gray-100 bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 transition active" data-tab="subscriptions">
Abonnements
</button>
<button class="tab-btn px-6 py-2 rounded-full border border-gray-300 dark:border-gray-700 text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 transition" data-tab="sellers">
Revendeurs
</button>
</div>
<div class="mt-20">
<div id="subscriptions-content" class="tab-content grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-8">
<!-- 1 Mois -->
<div class="group relative rounded-3xl bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-sm hover:shadow-lg transition transform hover:-translate-y-1 p-8 text-center">
<h3 class="text-2xl font-semibold mb-2">1 Mois</h3>
<div class="text-4xl font-bold mb-1">39â¬</div>
<div class="text-gray-500 dark:text-gray-400 text-sm mb-6">/mois</div>
<ul class="text-left space-y-3 text-gray-700 dark:text-gray-200">
<li><span class="text-green-500 mr-2">â</span> Accès via plateforme OTT</li>
<li><span class="text-green-500 mr-2">â</span> Qualité HD/4K*</li>
<li><span class="text-green-500 mr-2">â</span> Replays selon disponibilité</li>
<li><span class="text-green-500 mr-2">â</span> Guides & support</li>
<li><span class="text-green-500 mr-2">â</span> Assistance</li>
</ul>
<button class="mt-8 w-full bg-black dark:bg-white text-white dark:text-black rounded-full py-3 font-medium hover:bg-gray-900 dark:hover:bg-gray-200 transition">
<a href="https://maestroiptv.eu/system/clientarea/index.php?route=client-checkout&id=8">Commander</a>
</button>
</div>
<!-- 3 Mois -->
<div class="group relative rounded-3xl bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-sm hover:shadow-lg transition transform hover:-translate-y-1 p-8 text-center">
<h3 class="text-2xl font-semibold mb-2">3 Mois</h3>
<div class="text-4xl font-bold mb-1">49â¬</div>
<div class="text-gray-500 dark:text-gray-400 text-sm mb-6">total</div>
<ul class="text-left space-y-3 text-gray-700 dark:text-gray-200">
<li><span class="text-green-500 mr-2">â</span> Accès via plateforme OTT</li>
<li><span class="text-green-500 mr-2">â</span> Qualité HD/4K*</li>
<li><span class="text-green-500 mr-2">â</span> Replays selon disponibilité</li>
<li><span class="text-green-500 mr-2">â</span> Guides & support</li>
<li><span class="text-green-500 mr-2">â</span> Assistance</li>
</ul>
<button class="mt-8 w-full bg-black dark:bg-white text-white dark:text-black rounded-full py-3 font-medium hover:bg-gray-900 dark:hover:bg-gray-200 transition">
<a href="https://maestroiptv.eu/system/clientarea/index.php?route=client-checkout&id=9">Commander</a>
</button>
</div>
<!-- 6 Mois -->
<div class="group relative rounded-3xl bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-sm hover:shadow-lg transition transform hover:-translate-y-1 p-8 text-center">
<h3 class="text-2xl font-semibold mb-2">6 Mois</h3>
<div class="text-4xl font-bold mb-1">69â¬</div>
<div class="text-gray-500 dark:text-gray-400 text-sm mb-6">total</div>
<ul class="text-left space-y-3 text-gray-700 dark:text-gray-200">
<li><span class="text-green-500 mr-2">â</span> Accès via plateforme OTT</li>
<li><span class="text-green-500 mr-2">â</span> Qualité HD/4K*</li>
<li><span class="text-green-500 mr-2">â</span> Replays selon disponibilité</li>
<li><span class="text-green-500 mr-2">â</span> Guides & support</li>
<li><span class="text-green-500 mr-2">â</span> Assistance</li>
</ul>
<button class="mt-8 w-full bg-black dark:bg-white text-white dark:text-black rounded-full py-3 font-medium hover:bg-gray-900 dark:hover:bg-gray-200 transition">
<a href="https://maestroiptv.eu/system/clientarea/index.php?route=client-checkout&id=10">Commander</a>
</button>
</div>
<!-- 12 Mois -->
<div class="group relative rounded-3xl bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-sm hover:shadow-lg transition transform hover:-translate-y-1 p-8 text-center">
<h3 class="text-2xl font-semibold mb-2">12 Mois</h3>
<div class="text-4xl font-bold mb-1">99â¬</div>
<div class="text-gray-500 dark:text-gray-400 text-sm mb-6">total</div>
<ul class="text-left space-y-3 text-gray-700 dark:text-gray-200">
<li><span class="text-green-500 mr-2">â</span> Accès via plateforme OTT</li>
<li><span class="text-green-500 mr-2">â</span> Qualité HD/4K*</li>
<li><span class="text-green-500 mr-2">â</span> Replays selon disponibilité</li>
<li><span class="text-green-500 mr-2">â</span> Guides & support</li>
<li><span class="text-green-500 mr-2">â</span> Assistance</li>
</ul>
<button class="mt-8 w-full bg-black dark:bg-white text-white dark:text-black rounded-full py-3 font-medium hover:bg-gray-900 dark:hover:bg-gray-200 transition">
<a href="https://maestroiptv.eu/system/clientarea/index.php?route=client-checkout&id=11">Commander</a>
</button>
</div>
</div>
<div id="sellers-content" class="tab-content grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 hidden mt-12">
<!-- Pack 40 -->
<div class="group relative rounded-3xl bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-sm hover:shadow-lg transition transform hover:-translate-y-1 p-8 text-center">
<h3 class="text-2xl font-semibold mb-2">Pack 40 Abonnements</h3>
<div class="text-4xl font-bold mb-1">1600â¬</div>
<div class="text-gray-500 dark:text-gray-400 text-sm mb-6">total</div>
<div class="text-sm text-gray-400 dark:text-gray-500 mb-6">â 40â¬/abonnement</div>
<ul class="text-left space-y-3 text-gray-700 dark:text-gray-200">
<li><span class="text-green-500 mr-2">â</span> 40 abonnements de 12 mois</li>
<li><span class="text-green-500 mr-2">â</span> Accès multi-appareils</li>
<li><span class="text-green-500 mr-2">â</span> Replays selon disponibilité</li>
<li><span class="text-green-500 mr-2">â</span> Support prioritaire</li>
</ul>
<a href="https://maestroiptv.eu/system/clientarea/index.php?route=client-tickets"
class="mt-8 block w-full bg-black dark:bg-white text-white dark:text-black rounded-full py-3 font-medium hover:bg-gray-900 dark:hover:bg-gray-200 transition">
Contacter le support
</a>
</div>
<!-- Pack 20 -->
<div class="group relative rounded-3xl bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-sm hover:shadow-lg transition transform hover:-translate-y-1 p-8 text-center">
<h3 class="text-2xl font-semibold mb-2">Pack 20 Abonnements</h3>
<div class="text-4xl font-bold mb-1">900â¬</div>
<div class="text-gray-500 dark:text-gray-400 text-sm mb-6">total</div>
<div class="text-sm text-gray-400 dark:text-gray-500 mb-6">â 45â¬/abonnement</div>
<ul class="text-left space-y-3 text-gray-700 dark:text-gray-200">
<li><span class="text-green-500 mr-2">â</span> 20 abonnements de 12 mois</li>
<li><span class="text-green-500 mr-2">â</span> Accès multi-appareils</li>
<li><span class="text-green-500 mr-2">â</span> Replays selon disponibilité</li>
<li><span class="text-green-500 mr-2">â</span> Support standard</li>
</ul>
<a href="https://maestroiptv.eu/system/clientarea/index.php?route=client-tickets"
class="mt-8 block w-full bg-black dark:bg-white text-white dark:text-black rounded-full py-3 font-medium hover:bg-gray-900 dark:hover:bg-gray-200 transition">
Contacter le support
</a>
</div>
<!-- Pack 10 -->
<div class="group relative rounded-3xl bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-sm hover:shadow-lg transition transform hover:-translate-y-1 p-8 text-center">
<h3 class="text-2xl font-semibold mb-2">Pack 10 Abonnements</h3>
<div class="text-4xl font-bold mb-1">500â¬</div>
<div class="text-gray-500 dark:text-gray-400 text-sm mb-6">total</div>
<div class="text-sm text-gray-400 dark:text-gray-500 mb-6">â 50â¬/abonnement</div>
<ul class="text-left space-y-3 text-gray-700 dark:text-gray-200">
<li><span class="text-green-500 mr-2">â</span> 10 abonnements de 12 mois</li>
<li><span class="text-green-500 mr-2">â</span> Accès multi-appareils</li>
<li><span class="text-green-500 mr-2">â</span> Replays selon disponibilité</li>
<li><span class="text-green-500 mr-2">â</span> Support standard</li>
</ul>
<a href="https://maestroiptv.eu/system/clientarea/index.php?route=client-tickets"
class="mt-8 block w-full bg-black dark:bg-white text-white dark:text-black rounded-full py-3 font-medium hover:bg-gray-900 dark:hover:bg-gray-200 transition">
Contacter le support
</a>
</div>
</div>
</div>
</div>
</section>
<!-- Modal de commande -->
<div id="commandeModal" class="modal">
<div class="modal-content">
<h2 class="text-2xl font-bold mb-4">Finalisez votre commande</h2>
<form id="commandeForm" class="space-y-4">
<input type="hidden" name="pid" id="pidInput">
<div><input type="text" name="firstname" placeholder="Prénom" required class="w-full px-4 py-3 rounded-lg border border-gray-300 dark:bg-apple-card-dark dark:border-gray-600"></div>
<div><input type="text" name="lastname" placeholder="Nom" required class="w-full px-4 py-3 rounded-lg border border-gray-300 dark:bg-apple-card-dark dark:border-gray-600"></div>
<div><input type="email" name="email" placeholder="Email" required class="w-full px-4 py-3 rounded-lg border border-gray-300 dark:bg-apple-card-dark dark:border-gray-600"></div>
<div><input type="tel" name="phone" placeholder="Téléphone" required class="w-full px-4 py-3 rounded-lg border border-gray-300 dark:bg-apple-card-dark dark:border-gray-600"></div>
<div><input type="password" name="password" placeholder="Mot de passe" required minlength="8" class="w-full px-4 py-3 rounded-lg border border-gray-300 dark:bg-apple-card-dark dark:border-gray-600"></div>
<div><input type="text" name="promo_code" placeholder="Code promo (optionnel)" class="w-full px-4 py-3 rounded-lg border border-gray-300 dark:bg-apple-card-dark dark:border-gray-600"></div>
<div class="flex justify-end space-x-3">
<button type="button" id="closeModal" class="apple-button-secondary">Annuler</button>
<button type="submit" id="confirmBtn" class="apple-button">Confirmer</button>
</div>
</form>
</div>
</div>
<div id="toast" class="toast"></div>
<!-- Devices -->
<section class="bg-gray dark:bg-apple-dark py-20" id="devices">
<div class="max-w-7xl mx-auto px-6">
<h2 class="text-4xl font-semibold text-center text-gray-900 dark:text-white mb-4">
Disponible sur tous vos appareils
</h2>
<p class="text-center text-lg text-gray-600 dark:text-gray-300 max-w-2xl mx-auto mb-12">
Profitez de MAESTRO IPTV où que vous soyez, sur l'appareil de votre choix.
</p>
<div class="flex flex-wrap justify-center items-center gap-10">
<div class="device"><i class="fas fa-tv text-4xl text-gray-800 dark:text-gray-100 mb-3"></i><p class="text-sm text-gray-600 dark:text-gray-300">Smart TVs</p></div>
<div class="device"><i class="fas fa-mobile-alt text-4xl text-gray-800 dark:text-gray-100 mb-3"></i><p class="text-sm text-gray-600 dark:text-gray-300">Smartphones</p></div>
<div class="device"><i class="fas fa-laptop text-4xl text-gray-800 dark:text-gray-100 mb-3"></i><p class="text-sm text-gray-600 dark:text-gray-300">Ordinateurs</p></div>
<div class="device"><i class="fas fa-gamepad text-4xl text-gray-800 dark:text-gray-100 mb-3"></i><p class="text-sm text-gray-600 dark:text-gray-300">Consoles</p></div>
<div class="device"><i class="fas fa-box text-4xl text-gray-800 dark:text-gray-100 mb-3"></i><p class="text-sm text-gray-600 dark:text-gray-300">Box Android</p></div>
<div class="device"><i class="fas fa-fire text-4xl text-gray-800 dark:text-gray-100 mb-3"></i><p class="text-sm text-gray-600 dark:text-gray-300">Fire Stick</p></div>
<div class="device"><i class="fas fa-satellite-dish text-4xl text-gray-800 dark:text-gray-100 mb-3"></i><p class="text-sm text-gray-600 dark:text-gray-300">Enigma2</p></div>
</div>
</div>
</section>
<div class="h-5 bg-white dark:bg-apple-dark"></div>
<!-- Installation -->
<section id="installation" class="py-12 px-4 bg-white dark:bg-black dark:text-gray-100">
<div class="max-w-7xl mx-auto text-center mb-8">
<h2 class="text-3xl font-semibold tracking-tight mb-2">Installation & Téléchargement</h2>
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1 max-w-2xl mx-auto">
Accédez à <span class="font-semibold text-gray-800 dark:text-gray-100">MAESTRO IPTV</span> sur vos appareils en quelques minutes.
</p>
<div class="mt-6 border-b border-gray-200 dark:border-gray-700"></div>
</div>
<div class="max-w-6xl mx-auto grid grid-cols-1 lg:grid-cols-2 gap-6">
<div>
<h3 class="text-xl font-semibold mb-6 text-gray-800 dark:text-gray-100">Téléchargements</h3>
<div class="flex flex-nowrap overflow-x-auto gap-6 py-2">
<div class="w-32 flex-shrink-0 bg-white/30 dark:bg-gray-800/30 backdrop-blur-md border border-white/20 dark:border-gray-700/20 rounded-3xl p-5 shadow-lg hover:shadow-2xl transform transition hover:-translate-y-1 text-center">
<div class="w-16 h-16 bg-gradient-to-br from-green-300 to-green-500 dark:from-green-900 dark:to-green-700 rounded-full flex items-center justify-center mx-auto mb-3">
<i class="fab fa-android text-green-700 dark:text-green-300 text-2xl"></i>
</div>
<h4 class="text-sm font-semibold mb-1 text-gray-800 dark:text-gray-100">Android</h4>
<p class="text-gray-600 dark:text-gray-300 text-xs">Télécharger APK</p>
</div>
<div class="w-32 flex-shrink-0 bg-white/30 dark:bg-gray-800/30 backdrop-blur-md border border-white/20 dark:border-gray-700/20 rounded-3xl p-5 shadow-lg hover:shadow-2xl transform transition hover:-translate-y-1 text-center">
<div class="w-16 h-16 bg-gradient-to-br from-gray-200 to-gray-400 dark:from-gray-700 dark:to-gray-900 rounded-full flex items-center justify-center mx-auto mb-3">
<i class="fab fa-apple text-gray-800 dark:text-gray-100 text-2xl"></i>
</div>
<h4 class="text-sm font-semibold mb-1 text-gray-800 dark:text-gray-100">iOS</h4>
<p class="text-gray-600 dark:text-gray-300 text-xs">App Store</p>
</div>
<div class="w-32 flex-shrink-0 bg-white/30 dark:bg-gray-800/30 backdrop-blur-md border border-white/20 dark:border-gray-700/20 rounded-3xl p-5 shadow-lg hover:shadow-2xl transform transition hover:-translate-y-1 text-center">
<div class="w-16 h-16 bg-gradient-to-br from-blue-300 to-blue-500 dark:from-blue-900 dark:to-blue-700 rounded-full flex items-center justify-center mx-auto mb-3">
<i class="fab fa-windows text-blue-700 dark:text-blue-300 text-2xl"></i>
</div>
<h4 class="text-sm font-semibold mb-1 text-gray-800 dark:text-gray-100">Windows</h4>
<p class="text-gray-600 dark:text-gray-300 text-xs">Télécharger .exe</p>
</div>
<div class="w-32 flex-shrink-0 bg-white/30 dark:bg-gray-800/30 backdrop-blur-md border border-white/20 dark:border-gray-700/20 rounded-3xl p-5 shadow-lg hover:shadow-2xl transform transition hover:-translate-y-1 text-center">
<div class="w-16 h-16 bg-gradient-to-br from-purple-300 to-purple-500 dark:from-purple-900 dark:to-purple-700 rounded-full flex items-center justify-center mx-auto mb-3">
<i class="fas fa-tv text-purple-700 dark:text-purple-300 text-2xl"></i>
</div>
<h4 class="text-sm font-semibold mb-1 text-gray-800 dark:text-gray-100">Smart TV</h4>
<p class="text-gray-600 dark:text-gray-300 text-xs">Guide d'installation</p>
</div>
</div>
</div>
<div>
<h3 class="text-lg font-semibold mb-4 text-center lg:text-left">Guide d'installation</h3>
<div class="bg-white dark:bg-zinc-900 rounded-2xl p-6 shadow-lg hover:shadow-2xl transition-all">
<h4 class="text-lg font-semibold mb-4 text-center lg:text-left">Configuration Rapide</h4>
<ol class="space-y-2 text-left">
<li class="flex items-center"><span class="w-6 h-6 bg-black text-white dark:bg-white dark:text-black rounded-full flex items-center justify-center text-xs font-bold mr-3">1</span>Téléchargez l'application</li>
<li class="flex items-center"><span class="w-6 h-6 bg-black text-white dark:bg-white dark:text-black rounded-full flex items-center justify-center text-xs font-bold mr-3">2</span>Ouvrez l'app et sélectionnez "Login"</li>
<li class="flex items-center"><span class="w-6 h-6 bg-black text-white dark:bg-white dark:text-black rounded-full flex items-center justify-center text-xs font-bold mr-3">3</span>Entrez vos identifiants reçus par email</li>
<li class="flex items-center"><span class="w-6 h-6 bg-black text-white dark:bg-white dark:text-black rounded-full flex items-center justify-center text-xs font-bold mr-3">4</span>Profitez de l'expérience</li>
</ol>
</div>
</div>
</div>
</section>
<div class="h-5 bg-white dark:bg-apple-dark"></div>
<!-- Blog -->
<section class="py-20 px-6 bg-gray dark:bg-apple-dark" id="blog">
<div class="max-w-7xl mx-auto">
<h2 class="apple-section-header text-center">Blog & Actualités</h2>
<p class="apple-section-subheader text-center max-w-2xl mx-auto mt-4">
Guides d'installation, astuces et nouveautés
</p>
<div class="mt-6 border-b border-gray-200 dark:border-gray-700"></div>
<div class="flex justify-center mt-12 mb-8">
<div class="flex flex-wrap justify-center gap-2 bg-white dark:bg-apple-card-dark p-2 rounded-2xl shadow-lg">
<button class="apple-tab active px-6 py-3 rounded-xl flex items-center" data-blogcat="tous"><i class="fas fa-th-large mr-2"></i>Tous les articles</button>
<button class="apple-tab px-6 py-3 rounded-xl flex items-center" data-blogcat="installation"><i class="fas fa-download mr-2"></i>Installation</button>
<button class="apple-tab px-6 py-3 rounded-xl flex items-center" data-blogcat="guides"><i class="fas fa-book mr-2"></i>Guides</button>
<button class="apple-tab px-6 py-3 rounded-xl flex items-center" data-blogcat="sport"><i class="fas fa-trophy mr-2"></i>Sport</button>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8" id="blogArticles"></div>
<div class="text-center mt-12">
<button class="apple-button-secondary" id="loadMoreArticles"><i class="fas fa-plus mr-2"></i>Charger plus d'articles</button>
</div>
</div>
</section>
<div class="h-5 bg-white dark:bg-apple-dark"></div>
<!-- Client Area Modal -->
<div class="text-center py-8">
<a
href="https://maestroiptv.eu/system/clientarea/"
class="apple-button inline-flex items-center justify-center gap-2"
>
<i class="fas fa-user"></i>
Espace client
<i class="fas fa-arrow-right"></i>
</a>
</div>
<!-- Live Chat Widget -->
<div id="liveChatWidget" class="fixed bottom-6 right-6 z-50">
<div id="chatButton" class="w-14 h-14 bg-green-500 rounded-full flex items-center justify-center shadow-lg cursor-pointer hover:bg-green-600 transition-colors">
<i class="fas fa-comments text-white text-xl"></i>
</div>
<div id="chatWindow" class="hidden absolute bottom-16 right-0 w-80 h-96 bg-white dark:bg-apple-card-dark rounded-lg shadow-xl border border-gray-200 dark:border-gray-700">
<div class="bg-apple-blue text-white p-4 rounded-t-lg flex justify-between items-center">
<h3 class="font-bold">Support Live Chat</h3>
<button id="closeChat" class="text-white hover:text-gray-200" aria-label="Fermer">
<i class="fas fa-times"></i>
</button>
</div>
<div class="p-4 h-64 overflow-y-auto" id="chatMessages">
<div class="text-center text-apple-gray text-sm py-4">Connectez-vous pour discuter avec notre support</div>
</div>
<div class="p-4 border-t border-gray-200 dark:border-gray-700">
<input type="text" placeholder="Tapez votre message..."
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-apple-blue dark:bg-apple-card-dark"
disabled>
</div>
</div>
</div>
<!-- Avis clients -->
<section class="py-20 px-6 bg-white dark:bg-apple-dark" id="avis-clients">
<div class="max-w-7xl mx-auto text-center mb-12">
<h2 class="apple-section-header text-center">Avis de nos clients</h2>
<p class="apple-section-subheader text-center max-w-2xl mx-auto mt-4">
Découvrez ce que nos clients disent de nos services et partagez votre expérience.
</p>
<div class="mt-6 border-b border-gray-200 dark:border-gray-700"></div>
</div>
<div class="max-w-6xl mx-auto grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-6" id="avis-list"></div>
<div class="text-center space-x-4">
<button id="openModalBtn" class="bg-black text-white dark:bg-white dark:text-black px-6 py-3 rounded-full font-medium hover:opacity-80 transition">Ajouter un avis</button>
<button id="voirTousBtn" class="bg-gray-200 dark:bg-gray-700 text-gray-800 dark:text-gray-100 px-6 py-3 rounded-full font-medium hover:opacity-80 transition">Voir tous les avis</button>
</div>
<div id="avisModal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50">
<div class="bg-white dark:bg-gray-900 rounded-3xl p-6 max-w-md w-full shadow-lg relative backdrop-blur-md">
<button id="closeModalBtn" class="absolute top-3 right-3 text-gray-500 dark:text-gray-300 hover:text-gray-800 dark:hover:text-white">×</button>
<h3 class="text-xl font-semibold text-gray-800 dark:text-gray-100 mb-4 text-center">Ajouter votre avis</h3>
<form id="form-avis" class="space-y-4">
<input type="text" name="nom" placeholder="Votre nom" class="w-full p-3 rounded-xl border border-gray-300 dark:border-gray-700 bg-gray-50 dark:bg-gray-800 text-gray-800 dark:text-gray-100" required>
<textarea name="avis" placeholder="Votre avis" class="w-full p-3 rounded-xl border border-gray-300 dark:border-gray-700 bg-gray-50 dark:bg-gray-800 text-gray-800 dark:text-gray-100" rows="4" required></textarea>
<button type="submit" class="w-full bg-black text-white dark:bg-white dark:text-black px-6 py-3 rounded-full font-medium hover:opacity-80 transition">Envoyer</button>
</form>
</div>
</div>
<div id="tousAvisModal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50 overflow-y-auto">
<div class="bg-white dark:bg-gray-900 rounded-3xl p-6 max-w-3xl w-full shadow-lg relative backdrop-blur-md">
<button id="closeTousBtn" class="absolute top-3 right-3 text-gray-500 dark:text-gray-300 hover:text-gray-800 dark:hover:text-white">×</button>
<h3 class="text-xl font-semibold text-gray-800 dark:text-gray-100 mb-6 text-center">Tous les avis</h3>
<div id="tous-avis-list" class="space-y-4 max-h-[70vh] overflow-y-auto"></div>
</div>
</div>
</section>
<!-- Support -->
<section class="py-20 px-6 bg-apple-light dark:bg-apple-dark" id="support">
<div class="max-w-7xl mx-auto">
<h2 class="apple-section-header text-center">Support & Assistance</h2>
<p class="apple-section-subheader text-center max-w-2xl mx-auto mt-4">
Nous sommes là pour vous aider à chaque étape
</p>
<div class="mt-6 border-b border-gray-200 dark:border-gray-700"></div>
<div class="mt-12 grid grid-cols-1 md:grid-cols-2 gap-12">
<div>
<h3 class="text-2xl font-bold mb-6">Contactez-nous</h3>
<form id="whmcs-ticket-form" class="space-y-4" method="POST">
<div>
<label for="name" class="block text-sm font-medium mb-1">Nom complet</label>
<input type="text" id="name" name="name" class="w-full px-4 py-3 rounded-lg border border-gray-300 dark:bg-apple-card-dark dark:border-gray-600" placeholder="Votre nom" required>
</div>
<div>
<label for="email" class="block text-sm font-medium mb-1">Email</label>
<input type="email" id="email" name="email" class="w-full px-4 py-3 rounded-lg border border-gray-300 dark:bg-apple-card-dark dark:border-gray-600" placeholder="Votre email" required>
</div>
<div>
<label for="subject" class="block text-sm font-medium mb-1">Sujet</label>
<input type="text" id="subject" name="subject" class="w-full px-4 py-3 rounded-lg border border-gray-300 dark:bg-apple-card-dark dark:border-gray-600" placeholder="Sujet de votre message" required>
</div>
<div>
<label for="message" class="block text-sm font-medium mb-1">Message</label>
<textarea id="message" name="message" rows="4" class="w-full px-4 py-3 rounded-lg border border-gray-300 dark:bg-apple-card-dark dark:border-gray-600" placeholder="Votre message" required></textarea>
</div>
<button type="submit" class="apple-button w-full">Envoyer</button>
</form>
<div id="ticket-response" class="hidden mt-4 p-4 rounded-lg"></div>
</div>
<div>
<h3 class="text-2xl font-bold mb-6">Questions fréquentes</h3>
<div class="space-y-4">
<div class="faq-item">
<div class="faq-question flex justify-between items-center cursor-pointer">
<span>Sur quels appareils ça marche ?</span>
<i class="fas fa-chevron-down"></i>
</div>
<div class="faq-answer">
<p class="text-apple-gray">Smart TV, Box Android, iOS/Android, PC/MAC⦠selon lâapplication compatible.</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question flex justify-between items-center cursor-pointer">
<span>Quelles sont les chaînes/bouquets disponibles ?</span>
<i class="fas fa-chevron-down"></i>
</div>
<div class="faq-answer">
<p class="text-apple-gray">
Le catalogue varie selon la région et les droits de diffusion. La liste détaillée dépend de votre abonnement.
</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question flex justify-between items-center cursor-pointer">
<span>Les contenus sont-ils conformes aux droits & licences ?</span>
<i class="fas fa-chevron-down"></i>
</div>
<div class="faq-answer">
<p class="text-apple-gray">
La disponibilité des contenus dépend des droits/licences et de la zone. Pour toute question de conformité, contactez le support.
</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question flex justify-between items-center cursor-pointer">
<span>Ai-je besoin d'une parabole ?</span>
<i class="fas fa-chevron-down"></i>
</div>
<div class="faq-answer">
<p class="text-apple-gray">Non, une connexion internet stable suffit.</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question flex justify-between items-center cursor-pointer">
<span>Ai-je besoin d'un VPN ?</span>
<i class="fas fa-chevron-down"></i>
</div>
<div class="faq-answer">
<p class="text-apple-gray">En général non. Lâaccès dépend surtout des droits de diffusion et de votre zone.</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question flex justify-between items-center cursor-pointer">
<span>Offrez-vous un remboursement ?</span>
<i class="fas fa-chevron-down"></i>
</div>
<div class="faq-answer">
<p class="text-apple-gray">Consultez nos conditions dâutilisation ou contactez le support.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Footer -->
<footer class="py-12 px-6 bg-white dark:bg-apple-card-dark">
<div class="max-w-7xl mx-auto">
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
<div>
<h3 class="text-xl font-bold mb-4">MAESTRO IPTV</h3>
<p class="text-apple-gray">
Plateforme OTT premium. Accédez à des contenus en direct et à la demande selon disponibilité.
</p>
</div>
<div>
<h3 class="text-lg font-bold mb-4">Liens rapides</h3>
<div class="space-y-2">
<a href="#catalogue" class="block text-apple-gray hover:text-apple-blue">Catalogue</a>
<a href="#matches" class="block text-apple-gray hover:text-apple-blue">Compétitions</a>
<a href="#offers" class="block text-apple-gray hover:text-apple-blue">Abonnements</a>
<a href="#support" class="block text-apple-gray hover:text-apple-blue">FAQ & Contact</a>
</div>
</div>
<div>
<h3 class="text-lg font-bold mb-4 text-gray-900 dark:text-white">Support</h3>
<div class="space-y-2">
<a href="/contenue.html" class="block text-gray-600 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400">Notre catalogue</a>
<a href="/guide_installation.html" class="block text-gray-600 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400">Centre d'aide</a>
<a href="/guide_installation.html" class="block text-gray-600 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400">Guide d'installation</a>
<a href="/statut_service.html" class="block text-gray-600 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400">Statut du service</a>
</div>
</div>
<div>
<h3 class="text-lg font-bold mb-4 text-gray-900 dark:text-white">Légal</h3>
<div class="space-y-2">
<a href="/conditions_utilisation.html" class="block text-gray-600 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400">Conditions d'utilisation</a>
<a href="/politique_confidentialite.html" class="block text-gray-600 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400">Politique de confidentialité</a>
<a href="/cookies.html" class="block text-gray-600 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400">Cookies</a>
<a href="/mentions_legales.html" class="block text-gray-600 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400">Mentions légales</a>
</div>
</div>
</div>
<div class="border-t border-gray-200 dark:border-gray-700 mt-12 pt-8 text-center text-apple-gray">
<p>© 2019 MAESTRO IPTV. Tous droits réservés.</p>
</div>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js" defer></script>
<script>
/* =========================
Helpers
========================== */
function showToast(message) {
const toast = document.getElementById('toast');
toast.textContent = message;
toast.style.display = 'block';
clearTimeout(window.__toastTimer);
window.__toastTimer = setTimeout(() => { toast.style.display = 'none'; }, 5000);
}
function escapeText(str) {
return String(str ?? '').replace(/[&<>"']/g, s => ({
'&': '&', '<': '<', '>': '>', '"': '"', "'": '''
}[s]));
}
function hashString(str) {
let h = 0;
const s = String(str || '');
for (let i = 0; i < s.length; i++) { h = ((h << 5) - h) + s.charCodeAt(i); h |= 0; }
return Math.abs(h);
}
function categoryLabel(cat) {
const c = (cat || '').toLowerCase();
return ({
chaines: 'Chaînes',
live: 'Live',
replay: 'Replays',
movies: 'Films',
series: 'Séries',
radio: 'Radio',
ppv: 'PPV'
}[c] || 'Media');
}
function categoryIcon(cat) {
const c = (cat || '').toLowerCase();
return ({
chaines: 'fa-tv',
live: 'fa-play',
replay: 'fa-rotate-left',
movies: 'fa-film',
series: 'fa-clapperboard',
radio: 'fa-radio',
ppv: 'fa-ticket'
}[c] || 'fa-circle-play');
}
const canParallax = window.matchMedia && window.matchMedia('(hover: hover) and (pointer: fine)').matches;
function enableParallax(card) {
if (!canParallax) return;
let raf = null;
card.addEventListener('mousemove', (e) => {
const r = card.getBoundingClientRect();
const x = (e.clientX - r.left) / r.width;
const y = (e.clientY - r.top) / r.height;
const strength = 8;
const move = 8;
const rx = (0.5 - y) * strength;
const ry = (x - 0.5) * strength;
const mx = (x - 0.5) * move;
const my = (y - 0.5) * move;
if (raf) cancelAnimationFrame(raf);
raf = requestAnimationFrame(() => {
card.style.setProperty('--rx', rx.toFixed(2) + 'deg');
card.style.setProperty('--ry', ry.toFixed(2) + 'deg');
card.style.setProperty('--mx', mx.toFixed(1) + 'px');
card.style.setProperty('--my', my.toFixed(1) + 'px');
});
});
card.addEventListener('mouseleave', () => {
card.style.setProperty('--rx', '0deg');
card.style.setProperty('--ry', '0deg');
card.style.setProperty('--mx', '0px');
card.style.setProperty('--my', '0px');
});
}
function initials(name) {
const parts = String(name || '').trim().split(/\s+/).filter(Boolean);
const a = parts[0]?.[0] || 'A';
const b = parts[1]?.[0] || parts[0]?.[1] || '';
return (a + b).toUpperCase();
}
document.addEventListener('DOMContentLoaded', function() {
const mobileMenuBtn = document.getElementById('mobileMenuBtn');
const mobileMenu = document.getElementById('mobileMenu');
if (mobileMenuBtn && mobileMenu) {
mobileMenuBtn.addEventListener('click', () => mobileMenu.classList.toggle('hidden'));
}
/* â
Theme toggle (fixed) */
const themeToggle = document.getElementById('theme-toggle');
const darkIcon = themeToggle?.querySelector('.dark-mode-icon');
const lightIcon = themeToggle?.querySelector('.light-mode-icon');
function syncThemeUI() {
const isDark = document.documentElement.classList.contains('dark');
if (isDark) {
darkIcon?.classList.add('hidden');
lightIcon?.classList.remove('hidden');
} else {
darkIcon?.classList.remove('hidden');
lightIcon?.classList.add('hidden');
}
}
syncThemeUI();
themeToggle?.addEventListener('click', () => {
const html = document.documentElement;
const willBeDark = !html.classList.contains('dark');
html.classList.toggle('dark', willBeDark);
localStorage.setItem('theme', willBeDark ? 'dark' : 'light');
syncThemeUI();
});
const langToggle = document.getElementById('lang-toggle');
const flag = langToggle?.querySelector('.flag');
langToggle?.addEventListener('click', () => {
flag.textContent = (flag.textContent === 'ð«ð·') ? 'ð¬ð§' : 'ð«ð·';
});
const clientModal = document.getElementById('clientModal');
const closeClientModal = document.getElementById('closeClientModal');
const loginForm = document.getElementById('loginForm');
const registerForm = document.getElementById('registerForm');
const clientTabs = document.querySelectorAll('#clientTabs .apple-tab');
closeClientModal?.addEventListener('click', () => clientModal.classList.remove('active'));
clientModal?.addEventListener('click', (e) => { if (e.target === clientModal) clientModal.classList.remove('active'); });
clientTabs.forEach(btn => {
btn.addEventListener('click', () => {
clientTabs.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
const tab = btn.getAttribute('data-clienttab');
if (tab === 'login') {
loginForm.classList.remove('hidden');
registerForm.classList.add('hidden');
} else {
loginForm.classList.add('hidden');
registerForm.classList.remove('hidden');
}
});
});
const chatButton = document.getElementById('chatButton');
const chatWindow = document.getElementById('chatWindow');
const closeChat = document.getElementById('closeChat');
chatButton?.addEventListener('click', () => chatWindow.classList.toggle('hidden'));
closeChat?.addEventListener('click', () => chatWindow.classList.add('hidden'));
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
const targetId = this.getAttribute('href');
const target = document.querySelector(targetId);
if (!target) return;
e.preventDefault();
window.scrollTo({ top: target.offsetTop - 80, behavior: 'smooth' });
mobileMenu?.classList.add('hidden');
});
});
const offerTabs = document.querySelectorAll('#offers .tab-btn');
const offerContents = document.querySelectorAll('#offers .tab-content');
offerTabs.forEach(btn => {
btn.addEventListener('click', () => {
offerTabs.forEach(b => {
b.classList.remove('active', 'bg-gray-100', 'dark:bg-gray-800');
b.classList.add('text-gray-600', 'dark:text-gray-400');
});
btn.classList.add('active', 'bg-gray-100', 'dark:bg-gray-800');
btn.classList.remove('text-gray-600', 'dark:text-gray-400');
offerContents.forEach(c => c.classList.add('hidden'));
document.getElementById(btn.dataset.tab + '-content')?.classList.remove('hidden');
});
});
document.querySelectorAll('.faq-item').forEach(item => {
const question = item.querySelector('.faq-question');
const answer = item.querySelector('.faq-answer');
question.addEventListener('click', () => {
document.querySelectorAll('.faq-answer').forEach(other => { if (other !== answer) other.classList.remove('active'); });
answer.classList.toggle('active');
});
});
// Catalogue
let currentCategory = 'movies';
let currentPage = 1;
let isLoading = false;
let displayedItems = new Set();
const mediaGrid = document.getElementById('mediaGrid');
const searchInput = document.getElementById('searchInput');
const loadMoreButton = document.getElementById('loadMoreBtn');
const loadMoreButtonMobile = document.getElementById('loadMoreBtnMobile');
const tabButtons = document.querySelectorAll('#catalogueTabs .apple-tab[data-category]');
function renderCatalogueSkeleton(count=12){
mediaGrid.innerHTML = '';
for (let i=0;i<count;i++){
const card = document.createElement('div');
card.className = 'tv-card';
card.innerHTML = `
<div class="tv-poster">
<div class="skeleton w-full h-full" style="position:absolute; inset:0;"></div>
</div>
<div class="tv-meta">
<div class="skeleton" style="height:14px; width:78%; margin-bottom:10px;"></div>
<div class="skeleton" style="height:11px; width:54%;"></div>
</div>
`;
mediaGrid.appendChild(card);
}
}
function createMediaCard(item) {
const title = item.name || item.title || 'Sans titre';
const cat = (item.category || currentCategory || '').toLowerCase();
const hue = (hashString(title + '|' + cat) % 360);
const label = categoryLabel(cat);
const icon = categoryIcon(cat);
const card = document.createElement('div');
card.className = 'tv-card';
const pills = [];
if (item.quality) pills.push(String(item.quality));
if (item.country) pills.push(String(item.country));
if (item.season || item.episode) pills.push(`S${item.season || 1} ⢠E${item.episode || 1}`);
if (pills.length === 0) pills.push('HD/4K*');
card.innerHTML = `
<div class="tv-poster">
<div class="tv-poster-img tv-poster-generic" style="--h:${hue}"></div>
<div class="tv-icon-chip"><i class="fas ${icon}"></i> ${escapeText(label)}</div>
<div class="tv-badge">${escapeText(label)}</div>
</div>
<div class="tv-meta">
<div class="tv-title">${escapeText(title)}</div>
<div class="tv-sub">
${pills.slice(0,3).map(p => `<span class="tv-pill">${escapeText(p)}</span>`).join('')}
</div>
</div>
`;
enableParallax(card);
return card;
}
function processChannels(items) {
const channelsMap = new Map();
items.forEach(item => {
const key = String(item.name || '').toLowerCase();
if (!key) return;
if (!channelsMap.has(key)) {
channelsMap.set(key, {
id: item.id,
name: item.name,
category: item.category || 'chaines',
qualities: new Set(),
countries: new Set(),
timestamp: item.timestamp || 0
});
}
const ex = channelsMap.get(key);
if (item.quality) ex.qualities.add(item.quality);
if (item.country) ex.countries.add(item.country);
if (item.timestamp && item.timestamp > ex.timestamp) {
ex.timestamp = item.timestamp;
ex.id = item.id;
}
});
return Array.from(channelsMap.values())
.sort((a,b)=> a.name.localeCompare(b.name))
.map(ch => ({ ...ch, quality: Array.from(ch.qualities).join(' / '), country: Array.from(ch.countries).join(' / ') }));
}
function processSeries(items) {
const seriesMap = new Map();
items.forEach(item => {
const key = String(item.name || '').toLowerCase();
if (!key) return;
if (!seriesMap.has(key)) {
seriesMap.set(key, {
id: item.id,
name: item.name,
category: item.category || 'series',
quality: item.quality,
season: parseInt(item.season) || 0,
episode: parseInt(item.episode) || 0,
timestamp: item.timestamp || 0
});
}
const ex = seriesMap.get(key);
const s = parseInt(item.season) || 0;
const e = parseInt(item.episode) || 0;
const t = item.timestamp || 0;
const isBetter =
s > ex.season ||
(s === ex.season && e > ex.episode) ||
(t && t > ex.timestamp);
if (isBetter) {
ex.season = s;
ex.episode = e;
ex.id = item.id;
ex.quality = item.quality;
ex.timestamp = t || ex.timestamp;
}
});
return Array.from(seriesMap.values()).sort((a,b)=> a.name.localeCompare(b.name));
}
async function fetchMediaItems() {
if (isLoading) return;
isLoading = true;
loadMoreButton.disabled = true;
loadMoreButtonMobile.disabled = true;
try {
const searchQuery = searchInput.value.trim().toLowerCase();
const categoryLimits = { movies: 14, series: 14, chaines: 12, live: 12, replay: 12, radio: 12, ppv: 12 };
const limit = categoryLimits[currentCategory] || 12;
if (currentPage === 1 && !searchQuery) renderCatalogueSkeleton(limit);
const response = await fetch(`get_media.php?category=${encodeURIComponent(currentCategory)}&page=${currentPage}&limit=${limit}&search=${encodeURIComponent(searchQuery)}`);
if (!response.ok) throw new Error(`Erreur HTTP! Statut: ${response.status}`);
const data = await response.json();
if (data.error) throw new Error(data.message || data.error);
const itemsRaw = data.items || [];
const hasMore = (data.has_more !== undefined) ? !!data.has_more : (itemsRaw.length === limit);
if (currentPage === 1) {
mediaGrid.innerHTML = '';
displayedItems.clear();
}
if (!itemsRaw || itemsRaw.length === 0) {
if (currentPage === 1) {
mediaGrid.innerHTML = '<p class="col-span-full text-center py-10 text-apple-gray">Aucun résultat trouvé.</p>';
}
loadMoreButton.style.display = 'none';
loadMoreButtonMobile.style.display = 'none';
return;
}
let items = itemsRaw;
if (currentCategory === 'chaines') items = processChannels(itemsRaw);
if (currentCategory === 'series') items = processSeries(itemsRaw);
items.forEach(item => {
const key = (item.id !== undefined && item.id !== null) ? String(item.id) : String(item.name || '').toLowerCase();
if (!key) return;
if (displayedItems.has(key)) return;
displayedItems.add(key);
if (!item.category) item.category = currentCategory;
mediaGrid.appendChild(createMediaCard(item));
});
currentPage++;
loadMoreButton.style.display = hasMore ? 'inline-flex' : 'none';
loadMoreButtonMobile.style.display = hasMore ? 'inline-flex' : 'none';
} catch (err) {
console.error(err);
mediaGrid.innerHTML = `
<div class="col-span-full text-center py-10 text-red-500">
<p>Erreur de chargement des données</p>
<p class="text-sm">${escapeText(err.message)}</p>
</div>
`;
} finally {
isLoading = false;
loadMoreButton.disabled = false;
loadMoreButtonMobile.disabled = false;
}
}
function showCategory(category) {
currentCategory = category;
currentPage = 1;
displayedItems.clear();
mediaGrid.innerHTML = '';
tabButtons.forEach(btn => btn.classList.toggle('active', btn.getAttribute('data-category') === category));
fetchMediaItems();
}
tabButtons.forEach(btn => {
btn.addEventListener('click', () => showCategory(btn.getAttribute('data-category')));
});
let searchTimer = null;
searchInput.addEventListener('input', () => {
clearTimeout(searchTimer);
searchTimer = setTimeout(() => {
currentPage = 1;
displayedItems.clear();
fetchMediaItems();
}, 380);
});
loadMoreButton.addEventListener('click', fetchMediaItems);
loadMoreButtonMobile.addEventListener('click', fetchMediaItems);
showCategory('movies');
// Matches (demo data)
// Blog
let currentBlogPage = 1;
const articlesPerPage = 8;
let allArticles = []; // Tous les articles chargés (toutes pages confondues)
let filteredArticles = []; // Sous-ensemble selon la catégorie active
const blogArticlesContainer = document.getElementById('blogArticles');
const loadMoreArticlesBtn = document.getElementById('loadMoreArticles');
const blogTabs = document.querySelectorAll('#blog .apple-tab[data-blogcat]');
let currentBlogCategory = 'tous';
// Fonction pour créer une carte d'article
function createArticleCard(article) {
const articleDiv = document.createElement('div');
articleDiv.className = 'blog-article-card';
let badgeClass = 'badge-default';
let badgeText = 'Article';
if (article.category === 'installation') { badgeClass = 'badge-installation'; badgeText = 'Installation'; }
else if (article.category === 'guides') { badgeClass = 'badge-guides'; badgeText = 'Guide'; }
else if (article.category === 'sport') { badgeClass = 'badge-sport'; badgeText = 'Sport'; }
const articleDate = new Date(article.date || Date.now()).toLocaleDateString('fr-FR', {
year: 'numeric', month: 'long', day: 'numeric'
});
// Image fallback si cover vide
let cover = article.cover || 'https://maestroiptv.eu/index/assets/img/no-image.jpg';
articleDiv.innerHTML = `
<div class="article-image" style="background-image: url('${escapeText(cover)}')">
<div class="article-badge ${badgeClass}">${badgeText}</div>
</div>
<div class="article-content">
<div class="article-date"><i class="far fa-calendar"></i>${escapeText(articleDate)}</div>
<h3 class="article-title">${escapeText(article.title || '')}</h3>
<p class="article-excerpt">${escapeText(article.excerpt || '')}</p>
<a href="${escapeText(article.url)}" target="_blank" rel="noopener noreferrer" class="article-read-more">
Lire l'article <i class="fas fa-arrow-right"></i>
</a>
</div>
`;
return articleDiv;
}
// Affiche les articles selon filteredArticles (réinitialise le container)
function displayBlogArticles() {
blogArticlesContainer.innerHTML = '';
if (filteredArticles.length === 0) {
blogArticlesContainer.innerHTML = `
<div class="col-span-full text-center py-10">
<p class="text-apple-gray">Aucun article disponible pour le moment.</p>
</div>
`;
loadMoreArticlesBtn.style.display = 'none';
return;
}
filteredArticles.forEach(article => {
blogArticlesContainer.appendChild(createArticleCard(article));
});
// Afficher le bouton "Charger plus" seulement si on a encore des articles à charger (has_more)
// Pour cela, on doit savoir si la prochaine page existe (has_more)
// On stocke cette info dans une variable globale après chaque fetch
// On utilisera `hasMoreArticles` pour cela.
if (window.hasMoreArticles === false) {
loadMoreArticlesBtn.style.display = 'none';
} else {
loadMoreArticlesBtn.style.display = 'inline-flex';
}
}
// Filtrer les articles selon la catégorie
function filterArticles(category) {
currentBlogCategory = category;
if (category === 'tous') {
filteredArticles = [...allArticles];
} else {
filteredArticles = allArticles.filter(a => a.category === category);
}
displayBlogArticles();
}
// Charger la page donnée et mettre à jour allArticles
async function loadBlogPage(page) {
try {
// ð½ CORRECTION : URL absolue vers l'API
const url = `https://maestroiptv.eu/index/get_kb.php?page=${page}&limit=${articlesPerPage}`;
const response = await fetch(url, {
cache: 'no-store'
});
if (!response.ok) {
throw new Error(`HTTP ${response.status} - ${response.statusText}`);
}
const payload = await response.json();
console.log('API Blog:', payload); // Debug
const items = payload.items || [];
const hasMore = payload.has_more === true;
// Si page=1, on remplace tout, sinon on ajoute
if (page === 1) {
allArticles = items;
} else {
allArticles = allArticles.concat(items);
}
window.hasMoreArticles = hasMore;
// Re-filtrer selon la catégorie actuelle
filterArticles(currentBlogCategory);
return items;
} catch (error) {
console.error('Erreur lors du chargement des articles :', error);
// Afficher un message d'erreur dans le container
if (page === 1) {
blogArticlesContainer.innerHTML = `
<div class="col-span-full text-center py-10">
<p class="text-red-500">Impossible de charger les articles pour le moment.</p>
</div>
`;
loadMoreArticlesBtn.style.display = 'none';
}
throw error;
}
}
// Chargement initial (page 1)
async function loadBlogArticles() {
currentBlogPage = 1;
try {
await loadBlogPage(1);
} catch (e) {
// L'erreur est déjà gérée dans loadBlogPage
}
}
// Gestion du bouton "Charger plus"
async function loadMoreArticles() {
const nextPage = currentBlogPage + 1;
try {
const items = await loadBlogPage(nextPage);
if (items.length > 0) {
currentBlogPage = nextPage;
}
// Si hasMore est false, le bouton sera masqué par displayBlogArticles
// Mais il se peut que la page ait retourné moins d'articles que la limite
// Dans ce cas on considère qu'il n'y a plus d'articles.
if (items.length === 0) {
window.hasMoreArticles = false;
loadMoreArticlesBtn.style.display = 'none';
}
} catch (e) {
// Silencieux
}
}
// Ãvénements sur les onglets de catégorie
blogTabs.forEach(tab => {
tab.addEventListener('click', () => {
const category = tab.getAttribute('data-blogcat');
blogTabs.forEach(t => t.classList.remove('active'));
tab.classList.add('active');
filterArticles(category);
});
});
// Bouton "Charger plus"
loadMoreArticlesBtn.addEventListener('click', loadMoreArticles);
// Lancer le chargement initial
loadBlogArticles();
// Avis clients
const defaultAvis = [
{ nom: "Jean D.", avis: "Excellent service, très stable et rapide." },
{ nom: "Marie L.", avis: "Configuration simple et support réactif." },
{ nom: "Pierre C.", avis: "Interface propre, catalogue clair." }
];
let avisListData = JSON.parse(localStorage.getItem('avisClients')) || defaultAvis;
function afficherAvis() {
const avisList = document.getElementById('avis-list');
avisList.innerHTML = "";
const derniersAvis = avisListData.slice(-3).reverse();
derniersAvis.forEach(av => {
const newAvis = document.createElement('div');
newAvis.className = 'bg-white dark:bg-gray-900 rounded-3xl p-6 shadow-md hover:shadow-xl transition';
newAvis.innerHTML = `<h4 class="font-semibold text-gray-800 dark:text-gray-100 mb-2">${escapeText(av.nom)}</h4>
<p class="text-gray-500 dark:text-gray-400 text-sm">${escapeText(av.avis)}</p>`;
avisList.appendChild(newAvis);
});
}
function afficherTousAvis() {
const tousList = document.getElementById('tous-avis-list');
tousList.innerHTML = "";
avisListData.slice().reverse().forEach(av => {
const avisDiv = document.createElement('div');
avisDiv.className = 'bg-white dark:bg-gray-900 rounded-3xl p-4 shadow-md';
avisDiv.innerHTML = `<h4 class="font-semibold text-gray-800 dark:text-gray-100 mb-1">${escapeText(av.nom)}</h4>
<p class="text-gray-500 dark:text-gray-400 text-sm">${escapeText(av.avis)}</p>`;
tousList.appendChild(avisDiv);
});
}
afficherAvis();
const openModalBtn = document.getElementById('openModalBtn');
const closeModalBtn = document.getElementById('closeModalBtn');
const avisModal = document.getElementById('avisModal');
openModalBtn.addEventListener('click', () => { avisModal.classList.remove('hidden'); avisModal.classList.add('flex'); });
closeModalBtn.addEventListener('click', () => { avisModal.classList.add('hidden'); avisModal.classList.remove('flex'); });
const voirTousBtn = document.getElementById('voirTousBtn');
const tousModal = document.getElementById('tousAvisModal');
const closeTousBtn = document.getElementById('closeTousBtn');
voirTousBtn.addEventListener('click', () => { afficherTousAvis(); tousModal.classList.remove('hidden'); tousModal.classList.add('flex'); });
closeTousBtn.addEventListener('click', () => { tousModal.classList.add('hidden'); tousModal.classList.remove('flex'); });
document.getElementById('form-avis').addEventListener('submit', function(e){
e.preventDefault();
const nom = this.nom.value;
const avisText = this.avis.value;
avisListData.push({ nom: nom, avis: avisText });
localStorage.setItem('avisClients', JSON.stringify(avisListData));
afficherAvis();
this.reset();
avisModal.classList.add('hidden');
avisModal.classList.remove('flex');
});
// Ticket form
const ticketForm = document.getElementById('whmcs-ticket-form');
const ticketResponse = document.getElementById('ticket-response');
ticketForm.addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(this);
fetch('submit_ticket.php', { method: 'POST', body: formData })
.then(response => response.text())
.then(data => {
ticketResponse.innerHTML = data;
ticketResponse.classList.remove('hidden');
ticketResponse.classList.add('bg-green-100', 'text-green-800', 'border', 'border-green-300', 'p-4', 'rounded-lg');
ticketForm.reset();
})
.catch(() => {
ticketResponse.innerHTML = "â Une erreur s'est produite. Veuillez réessayer.";
ticketResponse.classList.remove('hidden');
ticketResponse.classList.add('bg-red-100', 'text-red-800', 'border', 'border-red-300', 'p-4', 'rounded-lg');
});
});
// Command modal
const commandModal = document.getElementById('commandeModal');
const closeModal = document.getElementById('closeModal');
const commandForm = document.getElementById('commandeForm');
const confirmBtn = document.getElementById('confirmBtn');
const pidInput = document.getElementById('pidInput');
document.querySelectorAll('.btn-commander').forEach(button => {
button.addEventListener('click', function() {
const pid = this.getAttribute('data-pid');
pidInput.value = pid;
commandModal.classList.add('active');
});
});
closeModal?.addEventListener('click', () => commandModal.classList.remove('active'));
commandForm.addEventListener('submit', function(e) {
e.preventDefault();
const originalText = confirmBtn.textContent;
confirmBtn.disabled = true;
confirmBtn.textContent = "Veuillez patienter...";
const formData = new FormData(commandForm);
fetch('commande.php', { method: 'POST', body: formData })
.then(r => r.json())
.then(() => {
showToast("Veuillez accéder à votre email pour finaliser l'inscription");
setTimeout(() => {
commandModal.classList.remove('active');
confirmBtn.disabled = false;
confirmBtn.textContent = originalText;
commandForm.reset();
}, 2500);
})
.catch(() => {
showToast("Une erreur s'est produite. Veuillez réessayer.");
confirmBtn.disabled = false;
confirmBtn.textContent = originalText;
});
});
// â
Competitions (NEW)
const compData = {
football: [
{ title: "Championnats Européens", meta: "Top ligues ⢠week-ends", badge: "Football", icon: "fa-futbol" },
{ title: "Compétitions Internationales", meta: "Sélections ⢠grands tournois", badge: "Football", icon: "fa-trophy" },
{ title: "Coupes & Classiques", meta: "Affiches premium", badge: "Football", icon: "fa-star" }
],
basket: [
{ title: "Ligues & Playoffs", meta: "Saison régulière ⢠playoffs", badge: "Basket", icon: "fa-basketball-ball" },
{ title: "Europe & International", meta: "Euro compétitions", badge: "Basket", icon: "fa-globe" },
{ title: "Highlights", meta: "Meilleures actions", badge: "Basket", icon: "fa-bolt" }
],
tennis: [
{ title: "Tournois majeurs", meta: "Grands événements", badge: "Tennis", icon: "fa-table-tennis-paddle-ball" },
{ title: "ATP / WTA", meta: "Matchs & résumés", badge: "Tennis", icon: "fa-medal" },
{ title: "Guides & Calendrier", meta: "Rappels & conseils", badge: "Tennis", icon: "fa-calendar" }
],
motorsport: [
{ title: "Grand Prix", meta: "Courses ⢠qualifs", badge: "Motorsport", icon: "fa-flag-checkered" },
{ title: "Rallye & Endurance", meta: "Formats variés", badge: "Motorsport", icon: "fa-gauge-high" },
{ title: "Résumés & analyses", meta: "Temps forts", badge: "Motorsport", icon: "fa-chart-line" }
]
};
const compGrid = document.getElementById('compGrid');
const compTabs = document.querySelectorAll('#compTabs .apple-tab[data-comp]');
function renderCompetitions(key){
if (!compGrid) return;
compGrid.innerHTML = '';
(compData[key] || []).forEach(item => {
const div = document.createElement('div');
div.className = 'comp-card';
div.innerHTML = `
<div class="flex items-start justify-between gap-3">
<div class="comp-badge"><i class="fas ${item.icon}"></i> ${item.badge}</div>
<div class="comp-meta"><i class="far fa-clock mr-1"></i> Selon disponibilité</div>
</div>
<h3 class="text-xl font-bold mt-4 text-gray-900 dark:text-white">${item.title}</h3>
<p class="text-sm mt-2 text-apple-gray dark:text-gray-300">${item.meta}</p>
<div class="mt-5 flex gap-3">
<a href="#catalogue" class="apple-button-secondary" style="font-size:14px; padding:10px 14px;">
<i class="fas fa-layer-group"></i> Voir le catalogue
</a>
<a href="#support" class="apple-button-secondary" style="font-size:14px; padding:10px 14px;">
<i class="fas fa-circle-question"></i> Aide
</a>
</div>
`;
compGrid.appendChild(div);
});
}
compTabs.forEach(btn => {
btn.addEventListener('click', () => {
compTabs.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
renderCompetitions(btn.getAttribute('data-comp'));
});
});
renderCompetitions('football');
});
</script>
<!--Start of Tawk.to Script-->
<script type="text/javascript">
var Tawk_API=Tawk_API||{}, Tawk_LoadStart=new Date();
(function(){
var s1=document.createElement("script"),s0=document.getElementsByTagName("script")[0];
s1.async=true;
s1.src='https://embed.tawk.to/67ce4cbb01c6981910f1e28b/1ilutnfs3';
s1.charset='UTF-8';
s1.setAttribute('crossorigin','*');
s0.parentNode.insertBefore(s1,s0);
})();
</script>
<!--End of Tawk.to Script-->
</body>
</html>
| # |
Url |
Url |
Source |
Date |
| 1 |
https://maestroiptv.eu/index/ |
|
2026-10-19 01:07:08 |
| 2 |
https://auth.mediacorp.sg/u/login?… |
|
2026-10-19 01:07:08 |
| 3 |
https://www.texarkanatwins.com/%25… |
|
2026-10-19 01:07:07 |
| 4 |
https://www.texarkanatwins.com/%25… |
|
2026-10-19 01:07:07 |
| 5 |
https://www.texarkanatwins.com/%25… |
|
2026-10-19 01:07:06 |
| 6 |
https://www.thebolditalic.com/?gi=… |
|
2026-10-19 01:07:06 |
| 7 |
https://www.texarkanatwins.com/%25… |
|
2026-10-19 01:07:06 |
| 8 |
https://auth.mediacorp.sg/u/login?… |
|
2026-10-19 01:07:05 |
| 9 |
https://www.texarkanatwins.com/%25… |
|
2026-10-19 01:07:05 |
| 10 |
https://www.texarkanatwins.com/%25… |
|
2026-10-19 01:07:04 |
| 11 |
https://www.texarkanatwins.com/%25… |
|
2026-10-19 01:07:04 |
| 12 |
https://www.texarkanatwins.com/%25… |
|
2026-10-19 01:07:04 |
| 13 |
https://www.thebolditalic.com/?gi=… |
|
2026-10-19 01:07:03 |
| 14 |
https://www.texarkanatwins.com/%25… |
|
2026-10-19 01:07:02 |
| 15 |
https://www.texarkanatwins.com/%25… |
|
2026-10-19 01:07:02 |
| 16 |
https://www.thebolditalic.com/?gi=… |
|
2026-10-19 01:07:02 |
| 17 |
https://auth.mediacorp.sg/u/login?… |
|
2026-10-19 01:07:01 |
| 18 |
https://www.texarkanatwins.com/%25… |
|
2026-10-19 01:07:01 |
| 19 |
https://www.texarkanatwins.com/%25… |
|
2026-10-19 01:07:00 |
| 20 |
https://www.texarkanatwins.com/%25… |
|
2026-10-19 01:06:59 |