Spaces:
Running
Running
| <html lang="fr"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>StreamFree - Films, Séries & Animes en HD</title> | |
| <!-- Police Google Fonts (Inter) --> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;900&display=swap" rel="stylesheet"> | |
| <!-- Icônes (Phosphor Icons) --> | |
| <script src="https://unpkg.com/@phosphor-icons/web"></script> | |
| <style> | |
| /* --- VARIABLES & RESET --- */ | |
| :root { | |
| --primary: #E50914; /* Rouge Netflix */ | |
| --primary-hover: #b20710; | |
| --bg-dark: #141414; | |
| --bg-card: #1f1f1f; | |
| --text-white: #ffffff; | |
| --text-gray: #a3a3a3; | |
| --gradient-dark: linear-gradient(to top, #141414 10%, transparent 90%); | |
| --shadow-card: 0 4px 6px rgba(0,0,0,0.3); | |
| --transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94); | |
| --header-height: 80px; | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: 'Inter', sans-serif; | |
| background-color: var(--bg-dark); | |
| color: var(--text-white); | |
| overflow-x: hidden; | |
| -webkit-font-smoothing: antialiased; | |
| } | |
| a { text-decoration: none; color: inherit; } | |
| ul { list-style: none; } | |
| button { border: none; outline: none; cursor: pointer; background: none; font-family: inherit; } | |
| /* --- HEADER --- */ | |
| header { | |
| position: fixed; | |
| top: 0; | |
| width: 100%; | |
| height: var(--header-height); | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 0 4%; | |
| z-index: 1000; | |
| transition: background-color 0.4s ease; | |
| background: linear-gradient(to bottom, rgba(0,0,0,0.7) 10%, transparent); | |
| } | |
| header.scrolled { | |
| background-color: #141414; | |
| box-shadow: 0 2px 10px rgba(0,0,0,0.5); | |
| } | |
| .logo { | |
| font-size: 1.8rem; | |
| font-weight: 900; | |
| color: var(--primary); | |
| letter-spacing: -1px; | |
| text-transform: uppercase; | |
| margin-right: 40px; | |
| } | |
| .nav-menu { | |
| display: flex; | |
| gap: 25px; | |
| } | |
| .nav-link { | |
| font-size: 0.9rem; | |
| color: var(--text-white); | |
| font-weight: 500; | |
| transition: color 0.2s; | |
| } | |
| .nav-link:hover, .nav-link.active { | |
| color: var(--text-gray); | |
| font-weight: 700; | |
| } | |
| .header-right { | |
| display: flex; | |
| align-items: center; | |
| gap: 20px; | |
| } | |
| /* Search Bar */ | |
| .search-container { | |
| display: flex; | |
| align-items: center; | |
| background: rgba(0,0,0,0.5); | |
| border: 1px solid rgba(255,255,255,0.3); | |
| padding: 6px 12px; | |
| border-radius: 20px; | |
| transition: var(--transition); | |
| } | |
| .search-container:focus-within { | |
| background: black; | |
| border-color: var(--text-white); | |
| } | |
| .search-input { | |
| background: transparent; | |
| border: none; | |
| color: white; | |
| width: 0; | |
| opacity: 0; | |
| transition: var(--transition); | |
| font-size: 0.9rem; | |
| } | |
| .search-container.open .search-input { | |
| width: 200px; | |
| opacity: 1; | |
| margin-left: 8px; | |
| } | |
| .search-icon { font-size: 1.2rem; cursor: pointer; } | |
| .user-profile { | |
| width: 35px; | |
| height: 35px; | |
| border-radius: 6px; | |
| background-image: url('https://picsum.photos/seed/user123/100/100'); | |
| background-size: cover; | |
| cursor: pointer; | |
| } | |
| /* --- HERO SECTION --- */ | |
| .hero { | |
| position: relative; | |
| height: 85vh; | |
| width: 100%; | |
| background-size: cover; | |
| background-position: center top; | |
| display: flex; | |
| align-items: center; | |
| padding-left: 4%; | |
| } | |
| .hero-overlay { | |
| position: absolute; | |
| top: 0; left: 0; width: 100%; height: 100%; | |
| background: linear-gradient(to right, rgba(20,20,20,0.9) 0%, rgba(20,20,20,0.6) 40%, transparent 100%), | |
| linear-gradient(to top, #141414 0%, transparent 20%); | |
| } | |
| .hero-content { | |
| position: relative; | |
| z-index: 10; | |
| max-width: 600px; | |
| margin-top: 60px; | |
| opacity: 0; | |
| animation: fadeIn Up 1s forwards 0.5s; | |
| } | |
| .hero-badge { | |
| display: inline-block; | |
| background: rgba(255,255,255,0.2); | |
| padding: 5px 10px; | |
| border-radius: 4px; | |
| font-size: 0.8rem; | |
| font-weight: 600; | |
| margin-bottom: 15px; | |
| backdrop-filter: blur(5px); | |
| } | |
| .hero-title { | |
| font-size: 4rem; | |
| font-weight: 900; | |
| line-height: 1; | |
| margin-bottom: 20px; | |
| text-shadow: 2px 2px 10px rgba(0,0,0,0.5); | |
| } | |
| .hero-desc { | |
| font-size: 1.1rem; | |
| line-height: 1.6; | |
| margin-bottom: 30px; | |
| color: #ddd; | |
| text-shadow: 1px 1px 4px rgba(0,0,0,0.8); | |
| } | |
| .hero-buttons { | |
| display: flex; | |
| gap: 15px; | |
| } | |
| .btn { | |
| padding: 12px 30px; | |
| border-radius: 5px; | |
| font-weight: 600; | |
| font-size: 1.1rem; | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| transition: var(--transition); | |
| } | |
| .btn-primary { | |
| background-color: var(--text-white); | |
| color: black; | |
| } | |
| .btn-primary:hover { background-color: rgba(255,255,255,0.75); } | |
| .btn-secondary { | |
| background-color: rgba(109,109,110,0.7); | |
| color: white; | |
| backdrop-filter: blur(4px); | |
| } | |
| .btn-secondary:hover { background-color: rgba(109,109,110,0.4); } | |
| /* --- MAIN CONTENT (SLIDERS) --- */ | |
| main { | |
| position: relative; | |
| z-index: 20; | |
| margin-top: -100px; /* Chevauchement */ | |
| padding-bottom: 50px; | |
| } | |
| .category-row { | |
| margin-bottom: 40px; | |
| padding-left: 4%; | |
| } | |
| .row-header { | |
| font-size: 1.4rem; | |
| font-weight: 600; | |
| margin-bottom: 15px; | |
| color: #e5e5e5; | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .row-header:hover { color: white; cursor: pointer; } | |
| .slider-container { | |
| display: flex; | |
| gap: 10px; | |
| overflow-x: auto; | |
| padding-right: 4%; | |
| padding-bottom: 30px; /* Espace pour l'hover */ | |
| scroll-behavior: smooth; | |
| } | |
| .slider-container::-webkit-scrollbar { height: 0px; } /* Cacher scrollbar */ | |
| .movie-card { | |
| flex: 0 0 auto; | |
| width: 220px; | |
| height: 330px; | |
| border-radius: 6px; | |
| overflow: hidden; | |
| position: relative; | |
| cursor: pointer; | |
| transition: transform 0.3s ease, z-index 0s 0.3s; | |
| background-color: #222; | |
| } | |
| .movie-card:hover { | |
| transform: scale(1.15); | |
| z-index: 100; | |
| box-shadow: 0 10px 20px rgba(0,0,0,0.7); | |
| transition: transform 0.3s ease, z-index 0s; | |
| } | |
| .card-img { | |
| width: 100%; | |
| height: 100%; | |
| object-fit: cover; | |
| } | |
| .card-details { | |
| position: absolute; | |
| bottom: 0; left: 0; width: 100%; | |
| padding: 15px; | |
| background: linear-gradient(to top, rgba(0,0,0,0.95), transparent); | |
| opacity: 0; | |
| transition: opacity 0.3s; | |
| } | |
| .movie-card:hover .card-details { opacity: 1; } | |
| .card-title { | |
| font-size: 0.95rem; | |
| font-weight: 700; | |
| margin-bottom: 5px; | |
| } | |
| .card-meta { | |
| display: flex; | |
| justify-content: space-between; | |
| font-size: 0.75rem; | |
| color: #46d369; | |
| font-weight: 600; | |
| } | |
| .match-score { color: #46d369; } | |
| .hd-badge { border: 1px solid #666; padding: 0 4px; color: #ddd; } | |
| /* --- MODAL PLAYER --- */ | |
| .modal-backdrop { | |
| position: fixed; | |
| top: 0; left: 0; width: 100%; height: 100%; | |
| background: rgba(0,0,0,0.8); | |
| z-index: 2000; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| opacity: 0; | |
| pointer-events: none; | |
| transition: opacity 0.3s; | |
| } | |
| .modal-backdrop.active { | |
| opacity: 1; | |
| pointer-events: all; | |
| } | |
| .modal-container { | |
| background: #181818; | |
| width: 90%; | |
| max-width: 900px; | |
| border-radius: 10px; | |
| overflow: hidden; | |
| position: relative; | |
| transform: scale(0.9); | |
| transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); | |
| box-shadow: 0 15px 40px rgba(0,0,0,0.6); | |
| } | |
| .modal-backdrop.active .modal-container { transform: scale(1); } | |
| .close-btn { | |
| position: absolute; | |
| top: 15px; right: 15px; | |
| width: 40px; height: 40px; | |
| background: rgba(0,0,0,0.6); | |
| color: white; | |
| border-radius: 50%; | |
| display: flex; justify-content: center; align-items: center; | |
| cursor: pointer; | |
| z-index: 20; | |
| font-size: 1.2rem; | |
| transition: background 0.2s; | |
| } | |
| .close-btn:hover { background: white; color: black; } | |
| .player-area { | |
| width: 100%; | |
| aspect-ratio: 16/9; | |
| background: black; | |
| position: relative; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| } | |
| .player-bg { | |
| position: absolute; top:0; left:0; width:100%; height:100%; | |
| object-fit: cover; opacity: 0.4; | |
| } | |
| .play-overlay-btn { | |
| font-size: 5rem; | |
| color: var(--primary); | |
| cursor: pointer; | |
| transition: transform 0.2s; | |
| filter: drop-shadow(0 0 10px rgba(0,0,0,0.5)); | |
| } | |
| .play-overlay-btn:hover { transform: scale(1.1); color: white; } | |
| .modal-info { padding: 25px; } | |
| .modal-title { font-size: 2rem; font-weight: 800; margin-bottom: 10px; } | |
| .modal-meta-line { display: flex; gap: 15px; color: var(--text-gray); font-size: 0.9rem; margin-bottom: 15px; align-items: center; } | |
| .modal-desc { line-height: 1.6; color: #fff; font-size: 1rem; max-width: 90%; } | |
| /* --- FOOTER --- */ | |
| footer { | |
| margin-top: 80px; | |
| padding: 50px 4%; | |
| text-align: center; | |
| color: var(--text-gray); | |
| font-size: 0.9rem; | |
| border-top: 1px solid #333; | |
| } | |
| .footer-link { color: var(--primary); text-decoration: underline; margin-top: 10px; display: inline-block; } | |
| /* --- RESPONSIVE --- */ | |
| @media (max-width: 768px) { | |
| .hero-title { font-size: 2.5rem; } | |
| .nav-menu { display: none; } /* Simplification mobile */ | |
| .search-container.open .search-input { width: 140px; } | |
| .movie-card { width: 160px; height: 240px; } | |
| .hero { height: 60vh; } | |
| } | |
| /* Animations */ | |
| @keyframes fadeInUp { | |
| from { opacity: 0; transform: translateY(20px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Header --> | |
| <header id="header"> | |
| <div style="display: flex; align-items: center;"> | |
| <div class="logo">StreamFree</div> | |
| <nav> | |
| <ul class="nav-menu"> | |
| <li><a href="#" class="nav-link active" onclick="resetHome()">Accueil</a></li> | |
| <li><a href="#" class="nav-link">Séries</a></li> | |
| <li><a href="#" class="nav-link">Films</a></li> | |
| <li><a href="#" class="nav-link">Animes</a></li> | |
| <li><a href="#" class="nav-link">Ma Liste</a></li> | |
| </ul> | |
| </nav> | |
| </div> | |
| <div class="header-right"> | |
| <div class="search-container" id="search-box"> | |
| <i class="ph ph-magnifying-glass search-icon" id="search-trigger"></i> | |
| <input type="text" class="search-input" id="search-input" placeholder="Titres, genres, personnes..."> | |
| </div> | |
| <div class="user-profile"></div> | |
| </div> | |
| </header> | |
| <!-- Hero Section --> | |
| <section class="hero" id="hero"> | |
| <div class="hero-overlay"></div> | |
| <div class="hero-content"> | |
| <span class="hero-badge" id="hero-badge">N°1 en France aujourd'hui</span> | |
| <h1 class="hero-title" id="hero-title">Chargement...</h1> | |
| <p class="hero-desc" id="hero-desc">...</p> | |
| <div class="hero-buttons"> | |
| <button class="btn btn-primary" onclick="playHero()"> | |
| <i class="ph-fill ph-play"></i> Lecture | |
| </button> | |
| <button class="btn btn-secondary" onclick="playHero()"> | |
| <i class="ph ph-info"></i> Plus d'infos | |
| </button> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Main Content --> | |
| <main id="main-content"> | |
| <!-- Catégories générées par JS --> | |
| </main> | |
| <!-- Modal Player --> | |
| <div class="modal-backdrop" id="modal"> | |
| <div class="modal-container"> | |
| <div class="close-btn" onclick="closeModal()"> | |
| <i class="ph ph-x"></i> | |
| </div> | |
| <div class="player-area"> | |
| <img src="" class="player-bg" id="modal-bg"> | |
| <i class="ph-fill ph-play-circle play-overlay-btn" id="modal-play-btn" onclick="startStream()"></i> | |
| <div id="stream-msg" style="display:none; color:white; font-weight:bold; font-size:1.2rem; background:rgba(0,0,0,0.8); padding:10px 20px; border-radius:5px;"></div> | |
| </div> | |
| <div class="modal-info"> | |
| <h2 class="modal-title" id="modal-title">Titre</h2> | |
| <div class="modal-meta-line"> | |
| <span class="match-score" id="modal-match">98% Match</span> | |
| <span id="modal-year">2023</span> | |
| <span class="hd-badge">HD</span> | |
| <span id="modal-duration">2h 15m</span> | |
| </div> | |
| <p class="modal-desc" id="modal-desc">Description...</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Footer --> | |
| <footer> | |
| <p>© 2024 StreamFree. Application de démonstration UI. Aucun contenu réel n'est hébergé.</p> | |
| <p>Les images sont générées automatiquement.</p> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="footer-link"> | |
| Built with anycoder | |
| </a> | |
| </footer> | |
| <script> | |
| // --- BASE DE DONNÉES ÉTENDUE (Simulant un catalogue réel) --- | |
| const catalog = [ | |
| // Anime | |
| { id: 1, title: "Naruto Shippuden", type: "Anime", year: 2007, match: 99, desc: "Naruto Uzumaki continue son voyage pour devenir Hokage, tout en affrontant l'organisation Akatsuki.", img: "https://placehold.co/600x900/FF8C00/white?text=Naruto", hero: true }, | |
| { id: 2, title: "One Piece", type: "Anime", year: 1999, match: 99, desc: "Luffy et son équipage des Chapeaux de Paille naviguent vers la Grand Line pour trouver le One Piece.", img: "https://placehold.co/600x900/1E90FF/white?text=One+Piece", hero: false }, | |
| { id: 3, title: "Jujutsu Kaisen", type: "Anime", year: 2020, match: 98, desc: "Yuji Itadori avalé un doigt maudit et devient l'hôte du roi des malédictions, Sukuna.", img: "https://placehold.co/600x900/800080/white?text=JJK", hero: false }, | |
| { id: 4, title: "Demon Slayer", type: "Anime", year: 2019, match: 97, desc: "Tanjiro Kamado devient un pourfendeur de démons pour sauver sa sœur transformée en démon.", img: "https://placehold.co/600x900/006400/white?text=Demon+Slayer", hero: false }, | |
| { id: 5, title: "Attack on Titan", type: "Anime", year: 2013, match: 99, desc: "L'humanité se bat pour survivre derrière des murs géants contre des Titans anthropophages.", img: "https://placehold.co/600x900/2F4F4F/white?text=AOT", hero: false }, | |
| { id: 6, title: "Dragon Ball Super", type: "Anime", year: 2015, match: 95, desc: "Goku et ses amis défendent l'univers contre des dieux de la destruction puissants.", img: "https://placehold.co/600x900/FFD700/white?text=DB+Super", hero: false }, | |
| // Séries TV | |
| { id: 7, title: "Breaking Bad", type: "Série", year: 2008, match: 99, desc: "Un professeur de chimie atteint d'un cancer se lance dans la fabrication de méthamphétamine.", img: "https://placehold.co/600x900/228B22/white?text=Breaking+Bad", hero: false }, | |
| { id: 8, title: "Stranger Things", type: "Série", year: 2016, match: 96, desc: "Un groupe d'enfants découvre des forces surnaturelles et une fille aux pouvoirs psychiques.", img: "https://placehold.co/600x900/8B0000/white?text=Stranger+Things", hero: true }, | |
| { id: 9, title: "The Last of Us", type: "Série", year: 2023, match: 98, desc: "Joel, un survivant endurci, est chargé d'escorter Ellie, une adolescente, à travers une Amérique post-apocalyptique.", img: "https://placehold.co/600x900/556B2F/white?text=TLOU", hero: false }, | |
| { id: 10, title: "Wednesday", type: "Série", year: 2022, match: 94, desc: "Wednesday Addams enquête sur des meurtres tout en naviguant dans sa nouvelle école.", img: "https://placehold.co/600x900/000000/white?text=Wednesday", hero: false }, | |
| { id: 11, title: "Squid Game", type: "Série", year: 2021, match: 95, desc: "Des joueurs désespérés risquent leur vie dans un jeu mortel d'enfants pour une grosse somme d'argent.", img: "https://placehold.co/600x900/FF69B4/white?text=Squid+Game", hero: false }, | |
| // Films | |
| { id: 12, title: "Spider-Man: No Way Home", type: "Film", year: 2021, match: 98, desc: "Peter Parker demande l'aide de Doctor Strange pour faire oublier son identité secrète au monde entier.", img: "https://placehold.co/600x900/DC143C/white?text=Spiderman", hero: false }, | |
| { id: 13, title: "Oppenheimer", type: "Film", year: 2023, match: 97, desc: "L'histoire du physicien américain J. Robert Oppenheimer et son rôle dans le développement de la bombe atomique.", img: "https://placehold.co/600x900/191970/white?text=Oppenheimer", hero: true }, | |
| { id: 14, title: "Avatar 2", type: "Film", year: 2022, match: 95, desc: "Jake Sully et Ney'tiri font tout pour rester ensemble et protéger leur famille sur la planète Pandora.", img: "https://placehold.co/600x900/008080/white?text=Avatar+2", hero: false }, | |
| { id: 15, title: "The Batman", type: "Film", year: 2022, match: 96, desc: "Batman enquête sur la corruption à Gotham City tout en poursuivant le Riddler.", img: "https://placehold.co/600x900/2c3e50/white?text=The+Bats", hero: false }, | |
| { id: 16, title: "Dune", type: "Film", year: 2021, match: 97, desc: "Paul Atreides, un jeune brillant, doit se rendre sur la planète la plus dangereuse de l'univers.", img: "https://placehold.co/600x900/DAA520/white?text=Dune", hero: false }, | |
| { id: 17, title: "John Wick 4", type: "Film", year: 2023, match: 96, desc: "John Wick découvre un chemin pour vaincre La Table Haute, mais doit affronter un nouvel ennemi.", img: "https://placehold.co/600x900/696969/white?text=John+Wick", hero: false } | |
| ]; | |
| // --- DOM ELEMENTS --- | |
| const header = document.getElementById('header'); | |
| const searchBox = document.getElementById('search-box'); | |
| const searchTrigger = document.getElementById('search-trigger'); | |
| const searchInput = document.getElementById('search-input'); | |
| const hero = document.getElementById('hero'); | |
| const mainContent = document.getElementById('main-content'); | |
| const modal = document.getElementById('modal'); | |
| // --- INITIALIZATION --- | |
| function init() { | |
| setupHero(); | |
| renderCategories(); | |
| setupEventListeners(); | |
| } | |
| // 1. Configurer le Hero (Film aléatoire ou marqué 'hero') | |
| function setupHero() { | |
| const heroMovies = catalog.filter(m => m.hero); | |
| const movie = heroMovies[Math.floor(Math.random() * heroMovies.length)]; | |
| // Utilisation d'une image haute qualité placeholder | |
| hero.style.backgroundImage = `url('https://placehold.co/1920x1080/111/white?text=${encodeURIComponent(movie.title)}')`; | |
| document.getElementById('hero-title').innerText = movie.title; | |
| document.getElementById('hero-desc').innerText = movie.desc; | |
| hero.dataset.id = movie.id; | |
| } | |
| // 2. Rendu des Catégories | |
| function renderCategories() { | |
| mainContent.innerHTML = ''; | |
| // On crée des catégories virtuelles basées sur les types | |
| const categories = [ | |
| { name: "Tendances Actuelles", filter: m => m.match >= 97 }, | |
| { name: "Animes Populaires", filter: m => m.type === "Anime" }, | |
| { name: "Séries TV Binge-watch", filter: m => m.type === "Série" }, | |
| { name: "Films au Cinéma", filter: m => m.type === "Film" } | |
| ]; | |
| categories.forEach(cat => { | |
| const movies = catalog.filter(cat.filter); | |
| if(movies.length > 0) { | |
| createSection(cat.name, movies); | |
| } | |
| }); | |
| } | |
| // Créer une section HTML | |
| function createSection(title, movies) { | |
| const section = document.createElement('section'); | |
| section.className = 'category-row'; | |
| const header = document.createElement('div'); | |
| header.className = 'row-header'; | |
| header.innerHTML = `${title} <i class="ph ph-caret-right"></i>`; | |
| const slider = document.createElement('div'); | |
| slider.className = 'slider-container'; | |
| movies.forEach(movie => { | |
| const card = createCard(movie); | |
| slider.appendChild(card); | |
| }); | |
| section.appendChild(header); | |
| section.appendChild(slider); | |
| mainContent.appendChild(section); | |
| } | |
| // Créer une carte | |
| function createCard(movie) { | |
| const card = document.createElement('div'); | |
| card.className = 'movie-card'; | |
| card.onclick = () => openModal(movie); | |
| card.innerHTML = ` | |
| <img src="${movie.img}" class="card-img" alt="${movie.title}" loading="lazy"> | |
| <div class="card-details"> | |
| <div class="card-title">${movie.title}</div> | |
| <div class="card-meta"> | |
| <span class="match-score">${movie.match}% Match</span> | |
| <span class="hd-badge">HD</span> | |
| </div> | |
| </div> | |
| `; | |
| return card; | |
| } | |
| // --- SEARCH FUNCTIONALITY --- | |
| function setupEventListeners() { | |
| // Scroll Header Effect | |
| window.addEventListener('scroll', () => { | |
| if(window.scrollY > 50) header.classList.add('scrolled'); | |
| else header.classList.remove('scrolled'); | |
| }); | |
| // Search Toggle | |
| searchTrigger.addEventListener('click', () => { | |
| searchBox.classList.toggle('open'); | |
| if(searchBox.classList.contains('open')) searchInput.focus(); | |
| }); | |
| // Search Input | |
| searchInput.addEventListener('input', (e) => { | |
| const query = e.target.value.toLowerCase().trim(); | |
| if(query.length > 0) { | |
| performSearch(query); | |
| } else { | |
| resetHome(); | |
| } | |
| }); | |
| // Close modal on outside click | |
| modal.addEventListener('click', (e) => { | |
| if(e.target === modal) closeModal(); | |
| }); | |
| } | |
| function performSearch(query) { | |
| // Cacher le Hero | |
| hero.style.display = 'none'; | |
| mainContent.innerHTML = ''; | |
| // Filtrer | |
| const results = catalog.filter(m => | |
| m.title.toLowerCase().includes(query) || | |
| m.type.toLowerCase().includes(query) || | |
| m.desc.toLowerCase().includes(query) | |
| ); | |
| if(results.length === 0) { | |
| mainContent.innerHTML = ` | |
| <div style="text-align:center; padding: 50px; color:#666;"> | |
| <h2>Aucun résultat pour "${query}"</h2> | |
| <p>Essayez "Naruto", "Série", ou "Marvel".</p> | |
| </div> | |
| `; | |
| return; | |
| } | |
| createSection(`Résultats pour "${query}"`, results); | |
| } | |
| function resetHome() { | |
| hero.style.display = 'flex'; | |
| renderCategories(); | |
| searchBox.classList.remove('open'); | |
| searchInput.value = ''; | |
| } | |
| // --- PLAYER LOGIC --- | |
| function openModal(movie) { | |
| document.getElementById('modal-title').innerText = movie.title; | |
| document.getElementById('modal-desc').innerText = movie.desc; | |
| document.getElementById('modal-year').innerText = movie.year; | |
| document.getElementById('modal-match').innerText = `${movie.match}% Match`; | |
| document.getElementById('modal-bg').src = movie.img; | |
| // Reset Player UI | |
| document.getElementById('modal-play-btn').style.display = 'block'; | |
| document.getElementById('stream-msg').style.display = 'none'; | |
| modal.classList.add('active'); | |
| } | |
| function closeModal() { | |
| modal.classList.remove('active'); | |
| } | |
| function playHero() { | |
| const id = parseInt(hero.dataset.id); | |
| const movie = catalog.find(m => m.id === id); | |
| if(movie) openModal(movie); | |
| } | |
| function startStream() { | |
| const btn = document.getElementById('modal-play-btn'); | |
| const msg = document.getElementById('stream-msg'); | |
| const bg = document.getElementById('modal-bg'); | |
| btn.style.display = 'none'; | |
| msg.style.display = 'block'; | |
| msg.innerText = "Connexion au serveur sécurisé..."; | |
| setTimeout(() => { | |
| msg.innerText = "Chargement du flux vidéo (HD)..."; | |
| }, 1000); | |
| setTimeout(() => { | |
| msg.innerText = "Désolé, ceci est une démo UI. Aucun flux vidéo réel n'est connecté."; | |
| msg.style.color = "#e50914"; | |
| bg.style.opacity = "0"; // Dim background to focus on text | |
| }, 2500); | |
| } | |
| // Démarrage | |
| init(); | |
| </script> | |
| </body> | |
| </html> |