Test « Cas Pratique »

Retropicalls – Nos Réalisations tailwind.config = { theme: { extend: { fontFamily: { ‘display’: [‘Raleway’, ‘sans-serif’], ‘body’: [‘inherit’, ‘sans-serif’], }, colors: { ‘retro-black’: ‘#000000’, ‘retro-white’: ‘#ffffff’, ‘retro-accent’: ‘#ff3300’, ‘retro-gray’: ‘#9ca3af’, } } } } /* ——————————————————- */ /* STYLES GLOBAUX */ /* ——————————————————- */ body, html { margin: 0; padding: 0; background-color: #000000; color: #ffffff; overflow-x: hidden; /* Le curseur par défaut est masqué pour laisser place au custom-cursor */ cursor: none; } .force-full-width-container { width: 100vw; position: relative; left: 50%; right: 50%; margin-left: -50vw; margin-right: -50vw; background-color: #000; padding-top: 0; z-index: 10; } /* ——————————————————- */ /* ELEMENTS D’INTERFACE */ /* ——————————————————- */ /* Curseur Personnalisé (Custom Cursor) */ .custom-cursor { position: fixed; top: 0; left: 0; width: 20px; height: 20px; border: 2px solid #ff3300; border-radius: 50%; pointer-events: none; z-index: 9999; transform: translate(-50%, -50%); mix-blend-mode: difference; transition: background-color 0.3s, border-color 0.3s; } /* Conteneur Image : Fixe à droite, AU PREMIER PLAN (z-index 50) */ .project-preview-layer { position: fixed; top: 50%; /* Marge de 4rem à droite pour le desktop */ right: 4rem; /* Cache complètement à droite pour l’animation */ transform: translateY(-50%) translateX(100%); width: 315px; height: 385px; pointer-events: none; z-index: 50; display: flex; justify-content: center; align-items: center; visibility: hidden; opacity: 0; } .preview-content { width: 100%; height: 100%; overflow: hidden; border-radius: 4px; box-shadow: 0 20px 50px rgba(0,0,0,0.5); } .preview-content img, .preview-content video { width: 100%; height: 100%; object-fit: cover; opacity: 0.75; transition: opacity 0.3s; } /* ——————————————————- */ /* STRUCTURE LAYOUT */ /* ——————————————————- */ .category-section { position: relative; display: flex; flex-direction: column; border-top: 1px solid rgba(255,255,255,0.1); background-color: transparent; z-index: 10; /* Fixe l’espace blanc du haut */ margin-top: 0 !important; } @media (min-width: 1024px) { .category-section { flex-direction: row; align-items: flex-start; } .category-header { position: sticky; top: 0; width: 40%; height: auto; min-height: 40vh; display: flex; flex-direction: column; justify-content: center; padding: 4rem; z-index: 20; background-color: #000; } .category-content { width: 60%; padding-top: 5vh; padding-bottom: 5vh; background-color: #000; } } .category-header h2 { color: #ffffff !important; font-size: 4rem; } /* Items de la liste (Liens) */ a.client-item { display: block; text-decoration: none; position: relative; padding: 2rem 3rem; border-bottom: 1px solid rgba(255,255,255,0.1); /* Important pour le survol: Le curseur est géré par le custom-cursor, donc on met le curseur par défaut à ‘none’ sur l’item */ cursor: none; transition: padding-left 0.3s ease, background-color 0.3s ease; z-index: 10; } /* Pour le cas où le custom-cursor est désactivé sur mobile */ @media (max-width: 1024px) { a.client-item { cursor: pointer; } } a.client-item:hover { background-color: rgba(255, 255, 255, 0.05); padding-left: 4rem; } a.client-item h3 { font-family: ‘Raleway’, sans-serif; font-weight: 800; font-size: 3rem; text-transform: uppercase; line-height: 1; color: transparent; -webkit-text-stroke: 1px rgba(255,255,255,0.5); transition: all 0.3s ease; } a.client-item:hover h3 { color: #fff; -webkit-text-stroke: 0px; } /* Services */ .client-tag { font-family: ‘inherit’, sans-serif; font-size: 0.9rem; color: #9ca3af; margin-top: 0.5rem; display: block; transition: transform 0.4s ease, color 0.3s ease; /* Poids de police 400 demandé (normal) */ font-weight: 400; letter-spacing: 0.5px; } a.client-item:hover .client-tag { transform: translateX(10px); color: #ffffff; font-weight: 600; } /* Mobile */ @media (max-width: 1024px) { .force-full-width-container { margin-top: 0; } .category-section { min-height: auto; margin-top: 0 !important; } /* Ajustement Mobile – Titres de catégorie (H2) */ .category-header h2 { font-size: 3rem; font-weight: 900 !important; /* Extra Bold */ } /* Ajustement Mobile – Titres des sous-catégories (H3) */ a.client-item h3 { font-size: 1.75rem; color: #fff; -webkit-text-stroke: 0px; } /* Ajustement Mobile – Détails du service (tag) */ .client-tag { font-weight: 400 !important; } .category-header { width: 100%; padding: 2rem; min-height: auto; border-bottom: 1px solid rgba(255,255,255,0.1); } .category-content { width: 100%; padding: 0; } a.client-item:hover { padding-left: 1.5rem; } a.client-item { padding: 1.5rem; } /* Le custom cursor et la preview sont désactivés sur mobile */ .custom-cursor, .project-preview-layer { display: none; } } // ———————————————————– // ANIMATIONS JS // ———————————————————– const items = document.querySelectorAll(‘.client-item’); const previewLayer = document.getElementById(‘preview-layer’); const previewContent = previewLayer.querySelector(‘.preview-content’); const cursor = document.getElementById(‘cursor’); // Gestion du mouvement curseur document.addEventListener(‘mousemove’, (e) => { const x = e.clientX; const y = e.clientY; gsap.set(cursor, { left: x, top: y }); }); items.forEach(item => { item.addEventListener(‘mouseenter’, () => { // S’assure que le custom cursor n’est pas actif sur mobile avant de faire l’animation (car il est en display: none) if (window.innerWidth >= 1024) { // Curseur s’agrandit légèrement gsap.to(cursor, { scale: 2, backgroundColor: ‘#ffffff’, mixBlendMode: ‘difference’, duration: 0.3 }); } const src = item.getAttribute(‘data-src’); const type = item.getAttribute(‘data-type’); if(src) { // Supprime le contenu précédent previewContent.innerHTML =  »; if (type === ‘image’) { const img = document.createElement(‘img’); img.src = src; img.onerror = function() { this.onerror = null; this.src = ‘https://placehold.co/450×550/ff3300/ffffff?text=Image+Indisponible’; }; previewContent.appendChild(img); } else if (type === ‘video’) { const video = document.createElement(‘video’); video.src = src; video.autoplay = true; video.muted = true; video.loop = true; video.playsinline = true; previewContent.appendChild(video); } previewLayer.style.visibility = ‘visible’; // Apparition de la couche de preview avec animation gsap.to(previewLayer, { opacity: 1, x: ‘0%’, // Amène l’image de sa position initiale (translateX(100%)) à 0 (visible) rotate: ‘0deg’, scale: 1, duration: 0.6, ease: « power3.out », overwrite: true }); gsap.fromTo(previewContent, { scale: 0.95, rotate: -2 }, { scale: 1, rotate: 0, duration: 0.6, ease: « power3.out », overwrite: true } ); } }); item.addEventListener(‘mouseleave’, () => { if (window.innerWidth >= 1024) { // Reset curseur gsap.to(cursor, { scale: 1, backgroundColor: ‘transparent’, duration: 0.3 }); } // Disparition de la couche de preview gsap.to(previewLayer, { opacity: 0, x: ‘100%’, // Replie l’image complètement hors de la zone visible (vers la droite) rotate: ‘2deg’, scale: 0.95, duration: 0.4, ease: « power2.in », overwrite: true, onComplete: () => { if(gsap.getProperty(previewLayer, « opacity ») === 0) { previewLayer.style.visibility = ‘hidden’; previewContent.innerHTML =  »; } } }); }); });