anycoder-b62e8a1e / index.html
Mousco's picture
Upload folder using huggingface_hub
8d7d71b verified
<!DOCTYPE html>
<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>