anycoder-329ef7a3 / index.html
Mousco's picture
Upload folder using huggingface_hub
ebd57be verified
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>StreamFree - Votre Cinéma à la Maison</title>
<!-- Importation de FontAwesome pour les icônes -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
/*
* DESIGN SYSTEM & VARIABLES CSS
* Utilisation de variables pour une maintenance facile et un thème sombre moderne
*/
:root {
--primary-color: #E50914; /* Rouge style Netflix */
--primary-hover: #b20710;
--background-dark: #141414;
--background-light: #1f1f1f;
--text-white: #ffffff;
--text-gray: #b3b3b3;
--font-main: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
--transition-speed: 0.3s;
--card-ratio: 1.5; /* Ratio pour les affiches 2:3 approx */
}
/* RESET & BASE */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: var(--font-main);
background-color: var(--background-dark);
color: var(--text-white);
overflow-x: hidden;
-webkit-font-smoothing: antialiased;
}
a {
text-decoration: none;
color: var(--text-white);
}
/* HEADER / NAVIGATION */
header {
position: fixed;
top: 0;
width: 100%;
height: 70px;
z-index: 1000;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 4%;
background: linear-gradient(to bottom, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0) 100%);
transition: background-color var(--transition-speed);
}
header.scrolled {
background-color: var(--background-dark);
}
.logo {
font-size: 1.8rem;
font-weight: bold;
color: var(--primary-color);
text-transform: uppercase;
letter-spacing: 2px;
margin-right: 40px;
}
.nav-links {
display: flex;
gap: 20px;
list-style: none;
}
.nav-links li a {
font-size: 0.9rem;
color: var(--text-gray);
transition: color var(--transition-speed);
}
.nav-links li a:hover, .nav-links li a.active {
color: var(--text-white);
font-weight: bold;
}
.header-right {
display: flex;
align-items: center;
gap: 20px;
}
/* Barre de recherche */
.search-box {
background: rgba(0,0,0,0.75);
border: 1px solid var(--text-white);
display: flex;
align-items: center;
padding: 5px 10px;
border-radius: 4px;
transition: width 0.3s;
}
.search-box input {
background: transparent;
border: none;
color: white;
outline: none;
width: 0; /* Caché par défaut */
transition: width 0.4s;
padding-left: 0;
}
.search-box:hover input, .search-box input:focus {
width: 200px;
padding-left: 10px;
}
.search-box i {
cursor: pointer;
}
/* HERO SECTION (Film mis en avant) */
.hero {
position: relative;
height: 85vh;
width: 100%;
background: url('https://picsum.photos/seed/hero2/1920/1080') center/cover no-repeat;
display: flex;
align-items: center;
}
.hero::after {
content: '';
position: absolute;
top: 0; left: 0; width: 100%; height: 100%;
background: linear-gradient(to top, var(--background-dark) 0%, transparent 60%, rgba(0,0,0,0.4) 100%);
}
.hero-content {
position: relative;
z-index: 10;
padding-left: 4%;
max-width: 600px;
padding-top: 100px;
}
.hero-title {
font-size: 3.5rem;
margin-bottom: 15px;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
.hero-desc {
font-size: 1.2rem;
margin-bottom: 25px;
line-height: 1.5;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
}
.hero-buttons {
display: flex;
gap: 15px;
}
.btn {
padding: 10px 25px;
border-radius: 4px;
font-size: 1.1rem;
font-weight: bold;
cursor: pointer;
border: none;
display: flex;
align-items: center;
gap: 10px;
transition: transform 0.2s, background-color 0.2s;
}
.btn:hover {
transform: scale(1.05);
}
.btn-play {
background-color: var(--text-white);
color: black;
}
.btn-play:hover {
background-color: rgba(255, 255, 255, 0.75);
}
.btn-info {
background-color: rgba(109, 109, 110, 0.7);
color: white;
}
.btn-info:hover {
background-color: rgba(109, 109, 110, 0.4);
}
/* CATEGORIES & CAROUSELS */
.category-section {
padding: 20px 0 40px 4%;
position: relative;
z-index: 20;
margin-top: -50px; /* Chevauchement avec le Hero */
}
.category-title {
font-size: 1.4rem;
margin-bottom: 15px;
font-weight: 600;
color: #e5e5e5;
}
.carousel-container {
position: relative;
width: 100%;
}
.carousel {
display: flex;
gap: 10px;
overflow-x: auto;
scroll-behavior: smooth;
padding-right: 4%;
padding-bottom: 20px; /* Pour la scrollbar ou le hover */
}
/* Masquer la scrollbar tout en gardant le scroll */
.carousel::-webkit-scrollbar {
height: 5px;
}
.carousel::-webkit-scrollbar-track {
background: transparent;
}
.carousel::-webkit-scrollbar-thumb {
background: #333;
border-radius: 10px;
}
.carousel::-webkit-scrollbar-thumb:hover {
background: #555;
}
.movie-card {
flex: 0 0 auto;
width: 200px;
height: 300px; /* Ratio Poster */
position: relative;
cursor: pointer;
border-radius: 4px;
transition: transform 0.3s ease, z-index 0.3s;
overflow: hidden;
}
.movie-card img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 4px;
}
.movie-card:hover {
transform: scale(1.15);
z-index: 100;
box-shadow: 0 10px 20px rgba(0,0,0,0.8);
}
/* Overlay sur la carte au survol */
.card-info {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding: 10px;
background: linear-gradient(to top, rgba(0,0,0,0.9), transparent);
opacity: 0;
transition: opacity 0.3s;
}
.movie-card:hover .card-info {
opacity: 1;
}
.card-title {
font-size: 0.9rem;
font-weight: bold;
margin-bottom: 5px;
}
.card-meta {
font-size: 0.7rem;
color: #46d369; /* Vert "Match" */
font-weight: bold;
}
/* MODAL PLAYER (Overlay) */
.video-modal {
position: fixed;
top: 0; left: 0; width: 100%; height: 100%;
background: rgba(0,0,0,0.9);
z-index: 2000;
display: none; /* Caché par défaut */
justify-content: center;
align-items: center;
flex-direction: column;
opacity: 0;
transition: opacity 0.4s;
}
.video-modal.active {
display: flex;
opacity: 1;
}
.modal-content {
width: 90%;
max-width: 1000px;
position: relative;
}
.close-modal {
position: absolute;
top: -40px;
right: 0;
color: white;
font-size: 2rem;
cursor: pointer;
background: none;
border: none;
}
.video-wrapper {
position: relative;
padding-bottom: 56.25%; /* 16:9 Aspect Ratio */
height: 0;
background: black;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 0 50px rgba(229, 9, 20, 0.3);
}
.video-wrapper video, .video-wrapper iframe {
position: absolute;
top: 0; left: 0; width: 100%; height: 100%;
border: none;
}
.modal-details {
margin-top: 20px;
color: white;
}
.modal-details h2 {
margin-bottom: 10px;
color: var(--primary-color);
}
/* FOOTER */
footer {
margin-top: 50px;
padding: 50px 4%;
color: var(--text-gray);
font-size: 0.9rem;
text-align: center;
}
.footer-links {
margin-bottom: 20px;
}
.footer-links a {
margin: 0 10px;
}
.anycoder-badge {
margin-top: 20px;
font-size: 0.8rem;
opacity: 0.7;
}
.anycoder-badge a {
color: var(--primary-color);
font-weight: bold;
}
/* RESPONSIVE DESIGN */
@media (max-width: 768px) {
.nav-links {
display: none; /* Menu burger non implémenté pour simplifier, on cache le texte */
}
.hero-title {
font-size: 2.5rem;
}
.hero-desc {
font-size: 1rem;
max-width: 100%;
}
.movie-card {
width: 140px;
height: 210px;
}
}
/* Loader */
.loader {
border: 4px solid #f3f3f3;
border-top: 4px solid var(--primary-color);
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
margin: 20px auto;
display: none;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
</head>
<body>
<!-- Header -->
<header id="main-header">
<div style="display: flex; align-items: center;">
<div class="logo">StreamFree</div>
<ul class="nav-links">
<li><a href="#" class="active">Accueil</a></li>
<li><a href="#">Séries</a></li>
<li><a href="#">Films</a></li>
<li><a href="#">Ma Liste</a></li>
</ul>
</div>
<div class="header-right">
<!-- Search Bar -->
<div class="search-box">
<i class="fas fa-search"></i>
<input type="text" id="searchInput" placeholder="Titres, personnes, genres">
</div>
<i class="fas fa-bell" style="font-size: 1.2rem; cursor: pointer;"></i>
<div style="width: 30px; height: 30px; background: #e5e5e5; border-radius: 4px; cursor: pointer;">
<img src="https://picsum.photos/seed/user/30/30" alt="User" style="border-radius: 4px;">
</div>
</div>
</header>
<!-- Main Content -->
<main>
<!-- Hero Section -->
<section class="hero" id="hero-section">
<div class="hero-content">
<h1 class="hero-title" id="hero-title">Chargement...</h1>
<p class="hero-desc" id="hero-desc">Découvrez cette histoire incroyable.</p>
<div class="hero-buttons">
<button class="btn btn-play" onclick="playHeroMovie()">
<i class="fas fa-play"></i> Lecture
</button>
<button class="btn btn-info">
<i class="fas fa-info-circle"></i> Plus d'infos
</button>
</div>
</div>
</section>
<!-- Dynamic Content Area -->
<div id="content-area">
<!-- Les catégories seront injectées ici par JS -->
</div>
<div class="loader" id="loader"></div>
</main>
<!-- Video Player Modal -->
<div class="video-modal" id="videoModal">
<div class="modal-content">
<button class="close-modal" onclick="closePlayer()">&times;</button>
<div class="video-wrapper" id="videoContainer">
<!-- Video ou Iframe sera injecté ici -->
</div>
<div class="modal-details" id="modalDetails">
<!-- Détails du film -->
</div>
</div>
</div>
<!-- Footer -->
<footer>
<div class="footer-links">
<a href="#">Audiodescription</a>
<a href="#">Centre d'aide</a>
<a href="#">Cartes cadeaux</a>
<a href="#">Médias</a>
<a href="#">Relations Investisseurs</a>
<a href="#">Emplois</a>
<a href="#">Conditions d'utilisation</a>
<a href="#">Confidentialité</a>
<a href="#">Mentions légales</a>
<a href="#">Préférences de cookies</a>
<a href="#">Informations sur l'entreprise</a>
<a href="#">Contactez-nous</a>
</div>
<p>&copy; 2023-2024 StreamFree Simulation.</p>
<div class="anycoder-badge">
Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">anycoder</a>
</div>
</footer>
<script>
/**
* DONNÉES SIMULÉES (MOCK DATA)
* Utilisation de vidéos open-source pour éviter le piratage.
* Images provenant de Picsum Photos.
*/
const categories = [
{ id: 'trending', title: 'Tendances actuelles' },
{ id: 'originals', title: 'Productions StreamFree' },
{ id: 'action', title: 'Films d\'action' },
{ id: 'scifi', title: 'Science-Fiction' }
];
// Vidéos Open Source (Big Buck Bunny, Sintel, etc.)
const videoSources = [
"https://media.w3.org/2010/05/sintel/trailer.mp4",
"https://media.w3.org/2010/05/bunny/trailer.mp4",
"https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/720/Big_Buck_Bunny_720_10s_1MB.mp4"
];
const moviesDB = [
// Tendances
{ title: "L'Odyssée Cosmique", category: 'trending', img: "https://picsum.photos/seed/cosmic/300/450", desc: "Un voyage épique à travers les galaxies.", video: videoSources[0] },
{ title: "La Dernière Frontière", category: 'trending', img: "https://picsum.photos/seed/frontier/300/450", desc: "La survie de l'humanité est en jeu.", video: videoSources[1] },
{ title: "Cyber Punk City", category: 'trending', img: "https://picsum.photos/seed/cyber/300/450", desc: "Dans un futur dominé par la technologie.", video: videoSources[2] },
{ title: "L'Enquête", category: 'trending', img: "https://picsum.photos/seed/detective/300/450", desc: "Un thriller psychologique intense.", video: videoSources[0] },
{ title: "Nature Sauvage", category: 'trending', img: "https://picsum.photos/seed/wild/300/450", desc: "Documentaire sur la faune.", video: videoSources[1] },
// Originals
{ title: "Chroniques du Temps", category: 'originals', img: "https://picsum.photos/seed/time/300/450", desc: "Série exclusive StreamFree.", video: videoSources[2] },
{ title: "Les Oubliés", category: 'originals', img: "https://picsum.photos/seed/forgotten/300/450", desc: "L'histoire d'un groupe perdu.", video: videoSources[0] },
{ title: "Arena Master", category: 'originals', img: "https://picsum.photos/seed/arena/300/450", desc: "Le combat ultime commence.", video: videoSources[1] },
// Action
{ title: "Rapide et Mortel", category: 'action', img: "https://picsum.photos/seed/fast/300/450", desc: "Poursuites effrénées.", video: videoSources[2] },
{ title: "Mission Omega", category: 'action', img: "https://picsum.photos/seed/omega/300/450", desc: "Une mission impossible.", video: videoSources[0] },
{ title: "Le Guerrier", category: 'action', img: "https://picsum.photos/seed/warrior/300/450", desc: "Honneur et combat.", video: videoSources[1] },
{ title: "Explosion City", category: 'action', img: "https://picsum.photos/seed/boom/300/450", desc: "Action pure.", video: videoSources[2] },
// Sci-Fi
{ title: "Mars Red", category: 'scifi', img: "https://picsum.photos/seed/mars/300/450", desc: "La colonisation a échoué.", video: videoSources[0] },
{ title: "AI Rebellion", category: 'scifi', img: "https://picsum.photos/seed/ai/300/450", desc: "Les machines prennent le pouvoir.", video: videoSources[1] },
{ title: "Deep Space", category: 'scifi', img: "https://picsum.photos/seed/space/300/450", desc: "Au-delà de l'univers connu.", video: videoSources[2] }
];
// État Global
let currentHeroMovie = moviesDB[0];
/**
* INITIALISATION
*/
document.addEventListener('DOMContentLoaded', () => {
setupHeaderScroll();
setupSearch();
loadHeroSection();
renderAllCategories();
});
/**
* GESTION DU HEADER
* Change la couleur du background au scroll
*/
function setupHeaderScroll() {
const header = document.getElementById('main-header');
window.addEventListener('scroll', () => {
if (window.scrollY > 50) {
header.classList.add('scrolled');
} else {
header.classList.remove('scrolled');
}
});
}
/**
* CHARGEMENT DU HERO
*/
function loadHeroSection() {
// Sélectionner un film aléatoire pour le Hero
const randomMovie = moviesDB[Math.floor(Math.random() * moviesDB.length)];
currentHeroMovie = randomMovie;
const heroSection = document.getElementById('hero-section');
const heroTitle = document.getElementById('hero-title');
const heroDesc = document.getElementById('hero-desc');
// Mise à jour de l'image de fond
heroSection.style.backgroundImage = `url('${randomMovie.img.replace('300/450', '1920/1080')}')`; // Image HD
heroTitle.textContent = randomMovie.title;
heroDesc.textContent = randomMovie.desc;
}
/**
* LECTURE DU FILM HERO
*/
function playHeroMovie() {
openPlayer(currentHeroMovie);
}
/**
* RENDU DES CATÉGORIES ET FILMS
*/
function renderAllCategories() {
const contentArea = document.getElementById('content-area');
contentArea.innerHTML = ''; // Reset
categories.forEach(cat => {
// Créer la section HTML
const section = document.createElement('section');
section.className = 'category-section';
const title = document.createElement('h3');
title.className = 'category-title';
title.textContent = cat.title;
const carouselContainer = document.createElement('div');
carouselContainer.className = 'carousel-container';
const carousel = document.createElement('div');
carousel.className = 'carousel';
carousel.id = `carousel-${cat.id}`;
// Filtrer les films pour cette catégorie
const moviesInCategory = moviesDB.filter(m => m.category === cat.id);
if (moviesInCategory.length > 0) {
moviesInCategory.forEach(movie => {
const card = createMovieCard(movie);
carousel.appendChild(card);
});
} else {
// Fallback si vide (afficher quelques films aléatoires)
moviesDB.slice(0, 5).forEach(movie => {
const card = createMovieCard(movie);
carousel.appendChild(card);
});
}
carouselContainer.appendChild(carousel);
section.appendChild(title);
section.appendChild(carouselContainer);
contentArea.appendChild(section);
});
}
/**
* CRÉATION D'UNE CARTE FILM
*/
function createMovieCard(movie) {
const card = document.createElement('div');
card.className = 'movie-card';
card.onclick = () => openPlayer(movie);
const img = document.createElement('img');
img.src = movie.img;
img.alt = movie.title;
img.loading = "lazy"; // Performance
const info = document.createElement('div');
info.className = 'card-info';
const title = document.createElement('div');
title.className = 'card-title';
title.textContent = movie.title;
const meta = document.createElement('div');
meta.className = 'card-meta';
meta.textContent = '98% Match';
info.appendChild(title);
info.appendChild(meta);
card.appendChild(img);
card.appendChild(info);
return card;
}
/**
* GESTION DU PLAYER VIDÉO (MODAL)
*/
const modal = document.getElementById('videoModal');
const videoContainer = document.getElementById('videoContainer');
const modalDetails = document.getElementById('modalDetails');
function openPlayer(movie) {
modal.classList.add('active');
// Injecter la balise vidéo HTML5
videoContainer.innerHTML = `
<video controls autoplay>
<source src="${movie.video}" type="video/mp4">
Votre navigateur ne supporte pas la balise vidéo.
</video>
`;
// Afficher les détails
modalDetails.innerHTML = `
<h2>${movie.title}</h2>
<p>${movie.desc}</p>
<div style="margin-top:10px; font-size: 0.9rem; color: #aaa;">
<span style="color:#46d369; font-weight:bold;">98% Match</span> &nbsp;|&nbsp;
<span>2023</span> &nbsp;|&nbsp;
<span>1h 45m</span> &nbsp;|&nbsp;
<span>HD</span>
</div>
`;
document.body.style.overflow = 'hidden'; // Empêcher le scroll arrière-plan
}
function closePlayer() {
modal.classList.remove('active');
videoContainer.innerHTML = ''; // Arrêter la vidéo
document.body.style.overflow = 'auto';
}
// Fermer la modal en cliquant en dehors
modal.addEventListener('click', (e) => {
if (e.target === modal) {
closePlayer();
}
});
/**
* BARRE DE RECHERCHE
*/
function setupSearch() {
const searchInput = document.getElementById('searchInput');
searchInput.addEventListener('input', (e) => {
const query = e.target.value.toLowerCase();
if (query.length > 0) {
filterMovies(query);
} else {
renderAllCategories(); // Retour à la normale
}
});
}
function filterMovies(query) {
const contentArea = document.getElementById('content-area');
contentArea.innerHTML = '';
// Filtrer la base de données
const filteredMovies = moviesDB.filter(m =>
m.title.toLowerCase().includes(query) ||
m.desc.toLowerCase().includes(query)
);
if (filteredMovies.length === 0) {
contentArea.innerHTML = '<div style="padding: 50px; text-align: center; color: #666;">Aucun résultat trouvé.</div>';
return;
}
// Créer une section spéciale "Résultats"
const section = document.createElement('section');
section.className = 'category-section';
const title = document.createElement('h3');
title.className = 'category-title';
title.textContent = `Résultats pour "${query}"`;
const carousel = document.createElement('div');
carousel.className = 'carousel';
// Flex wrap pour la recherche afin de tout monter en grille si besoin, ou scroll horizontal
carousel.style.display = 'flex';
carousel.style.flexWrap = 'wrap';
filteredMovies.forEach(movie => {
const card = createMovieCard(movie);
carousel.appendChild(card);
});
section.appendChild(title);
section.appendChild(carousel);
contentArea.appendChild(section);
}
</script>
</body>
</html>