Some UI fix
This commit is contained in:
parent
f520aa2bb6
commit
7bc4f48f11
@ -6,6 +6,7 @@ import { TechFeaturesSection } from './components/sections/TechFeaturesSection';
|
||||
import { ServicesSection } from './components/sections/ServicesSection';
|
||||
import { AboutSection } from './components/sections/AboutSection';
|
||||
import { Popup } from './components/ui/Popup';
|
||||
import { ScrollToTopButton } from './components/ui/ScrollToTopButton';
|
||||
import { URLS } from './config/constants';
|
||||
|
||||
// Define Service interface directly in App
|
||||
@ -92,6 +93,9 @@ const App: React.FC = () => {
|
||||
|
||||
<Footer />
|
||||
|
||||
{/* Bouton de retour en haut */}
|
||||
<ScrollToTopButton />
|
||||
|
||||
{selectedService && (
|
||||
<Popup service={selectedService} onClose={() => setSelectedService(null)} />
|
||||
)}
|
||||
|
@ -3,19 +3,26 @@ import banquiseServer from '/src/assets/banquise_server.svg'
|
||||
|
||||
export const HeroSection: React.FC = () => (
|
||||
<section className="min-h-[calc(80vh-72px)] flex flex-col justify-center items-center text-center py-12 sm:py-16 md:py-20 w-full max-w-6xl mx-auto px-4 sm:px-6 md:px-8 relative z-3">
|
||||
<div className="mb-8 sm:mb-10 md:mb-12 w-32 h-32 sm:w-40 sm:h-40 md:w-48 md:h-48 rounded-full bg-gradient-to-br from-banquise-blue-dark/20 to-banquise-blue/10 p-4 sm:p-5 md:p-6 shadow-2xl animate-gentle-float backdrop-blur-sm border border-banquise-blue-lightest/30">
|
||||
<img src={banquiseServer} alt="Logo La Banquise" className="w-full h-full object-contain" style={{ filter: 'drop-shadow(0 10px 25px rgba(31, 93, 137, 0.3))' }} />
|
||||
<div className="mb-8 sm:mb-10 md:mb-12 w-32 h-32 sm:w-40 sm:h-40 md:w-48 md:h-48 rounded-full bg-gradient-to-br from-banquise-blue-dark/20 to-banquise-blue/10 p-4 sm:p-5 md:p-6 shadow-2xl backdrop-blur-sm border border-banquise-blue-lightest/30 relative group">
|
||||
<img
|
||||
src={banquiseServer}
|
||||
alt="Logo La Banquise"
|
||||
className="w-full h-full object-contain relative z-10 transition-transform duration-300 group-hover:scale-110"
|
||||
style={{
|
||||
filter: 'drop-shadow(0 10px 25px rgba(31, 93, 137, 0.3))'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<h1 className="text-banquise-gray text-3xl sm:text-4xl md:text-5xl lg:text-6xl mb-6 sm:mb-7 md:mb-8 font-extrabold leading-tight max-w-4xl font-heading px-2" style={{ textShadow: '0 2px 10px rgba(0, 0, 0, 0.3)' }}>
|
||||
<h1 className="text-banquise-gray text-3xl sm:text-4xl md:text-5xl lg:text-6xl mb-6 sm:mb-7 md:mb-8 font-extrabold leading-tight max-w-4xl font-heading px-2 relative z-10" style={{ textShadow: '0 2px 10px rgba(0, 0, 0, 0.3)' }}>
|
||||
Bienvenue sur La Banquise
|
||||
</h1>
|
||||
|
||||
<p className="text-banquise-gray text-lg sm:text-xl md:text-2xl mb-8 sm:mb-10 md:mb-12 max-w-3xl font-normal opacity-90 leading-relaxed px-2" style={{ textShadow: '0 1px 4px rgba(0, 0, 0, 0.2)' }}>
|
||||
<p className="text-banquise-gray text-lg sm:text-xl md:text-2xl mb-8 sm:mb-10 md:mb-12 max-w-3xl font-normal opacity-90 leading-relaxed px-2 relative z-10" style={{ textShadow: '0 1px 4px rgba(0, 0, 0, 0.2)' }}>
|
||||
Association d'hébergement et lab réseau pour tous les étudiants et associations de l'EPITA !
|
||||
</p>
|
||||
|
||||
<a href="#services" className="inline-flex items-center justify-center bg-gradient-to-r from-banquise-gray to-white text-banquise-blue-dark border-0 py-4 sm:py-5 px-8 sm:px-10 md:px-12 rounded-2xl text-base sm:text-lg font-bold no-underline shadow-xl transition-all duration-300 min-w-48 sm:min-w-56 md:min-w-64 hover:-translate-y-2 hover:shadow-2xl hover:scale-105 backdrop-blur-sm border border-banquise-blue-lightest/20 mx-4 group">
|
||||
<a href="#services" className="inline-flex items-center justify-center bg-gradient-to-r from-banquise-gray to-white text-banquise-blue-dark border-0 py-4 sm:py-5 px-8 sm:px-10 md:px-12 rounded-2xl text-base sm:text-lg font-bold no-underline shadow-xl transition-all duration-300 min-w-48 sm:min-w-56 md:min-w-64 hover:-translate-y-2 hover:shadow-2xl hover:scale-105 backdrop-blur-sm border border-banquise-blue-lightest/20 mx-4 group relative z-10">
|
||||
<span className="text-center text-banquise-blue-dark">Découvrir nos services</span>
|
||||
<span className="ml-2 sm:ml-3 text-lg sm:text-xl transition-transform duration-300 group-hover:translate-x-1 text-banquise-blue-dark">→</span>
|
||||
</a>
|
||||
|
146
banquise-website/src/components/ui/ParallaxBackground.tsx
Normal file
146
banquise-website/src/components/ui/ParallaxBackground.tsx
Normal file
@ -0,0 +1,146 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
export const ParallaxBackground: React.FC = () => {
|
||||
const [scrollY, setScrollY] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setScrollY(window.scrollY);
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', handleScroll);
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, []);
|
||||
|
||||
// Éléments flottants avec différentes vitesses de parallaxe
|
||||
const floatingElements = [
|
||||
// Serveurs et équipements
|
||||
{ icon: '🖥️', x: 10, y: 20, speed: 0.3, size: 'text-2xl', opacity: 0.1 },
|
||||
{ icon: '🖲️', x: 85, y: 15, speed: 0.2, size: 'text-xl', opacity: 0.08 },
|
||||
{ icon: '⚙️', x: 75, y: 45, speed: 0.4, size: 'text-3xl', opacity: 0.12 },
|
||||
{ icon: '🔧', x: 15, y: 60, speed: 0.25, size: 'text-lg', opacity: 0.06 },
|
||||
{ icon: '💾', x: 90, y: 70, speed: 0.35, size: 'text-2xl', opacity: 0.1 },
|
||||
|
||||
// Code et développement
|
||||
{ icon: '<>', x: 30, y: 35, speed: 0.15, size: 'text-xl', opacity: 0.08, isText: true },
|
||||
{ icon: '{ }', x: 60, y: 25, speed: 0.28, size: 'text-2xl', opacity: 0.1, isText: true },
|
||||
{ icon: '#!/bin', x: 5, y: 80, speed: 0.2, size: 'text-sm', opacity: 0.06, isText: true },
|
||||
{ icon: 'git', x: 80, y: 85, speed: 0.32, size: 'text-lg', opacity: 0.08, isText: true },
|
||||
|
||||
// Réseau et connectivité
|
||||
{ icon: '🌐', x: 45, y: 10, speed: 0.22, size: 'text-2xl', opacity: 0.09 },
|
||||
{ icon: '🔗', x: 25, y: 75, speed: 0.18, size: 'text-xl', opacity: 0.07 },
|
||||
{ icon: '📡', x: 70, y: 55, speed: 0.26, size: 'text-lg', opacity: 0.08 },
|
||||
|
||||
// Sécurité
|
||||
{ icon: '🔒', x: 55, y: 40, speed: 0.3, size: 'text-xl', opacity: 0.09 },
|
||||
{ icon: '🛡️', x: 35, y: 65, speed: 0.24, size: 'text-2xl', opacity: 0.1 },
|
||||
{ icon: '🔑', x: 85, y: 30, speed: 0.16, size: 'text-lg', opacity: 0.07 },
|
||||
|
||||
// Données et stockage
|
||||
{ icon: '💿', x: 20, y: 45, speed: 0.28, size: 'text-xl', opacity: 0.08 },
|
||||
{ icon: '📊', x: 65, y: 75, speed: 0.22, size: 'text-2xl', opacity: 0.09 },
|
||||
{ icon: '📈', x: 40, y: 20, speed: 0.34, size: 'text-lg', opacity: 0.07 },
|
||||
|
||||
// Éléments techniques supplémentaires
|
||||
{ icon: 'sudo', x: 12, y: 90, speed: 0.19, size: 'text-sm', opacity: 0.06, isText: true },
|
||||
{ icon: 'SSH', x: 78, y: 12, speed: 0.31, size: 'text-base', opacity: 0.08, isText: true },
|
||||
{ icon: 'API', x: 92, y: 50, speed: 0.27, size: 'text-lg', opacity: 0.09, isText: true },
|
||||
{ icon: 'TCP', x: 8, y: 30, speed: 0.23, size: 'text-base', opacity: 0.07, isText: true },
|
||||
{ icon: 'HTTP', x: 50, y: 80, speed: 0.29, size: 'text-sm', opacity: 0.06, isText: true },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 pointer-events-none overflow-hidden z-0">
|
||||
{/* Grille de fond subtile */}
|
||||
<div className="absolute inset-0 opacity-[0.02]">
|
||||
<div
|
||||
className="absolute inset-0 bg-gradient-to-br from-banquise-blue-dark/20 to-transparent"
|
||||
style={{
|
||||
backgroundImage: `
|
||||
linear-gradient(rgba(31, 93, 137, 0.03) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(31, 93, 137, 0.03) 1px, transparent 1px)
|
||||
`,
|
||||
backgroundSize: '50px 50px',
|
||||
transform: `translateY(${scrollY * 0.1}px)`
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Particules de code flottantes */}
|
||||
<div className="absolute inset-0">
|
||||
{floatingElements.map((element, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`absolute ${element.size} font-mono select-none transition-all duration-1000 ease-out`}
|
||||
style={{
|
||||
left: `${element.x}%`,
|
||||
top: `${element.y}%`,
|
||||
transform: `translateY(${scrollY * element.speed}px) rotate(${scrollY * 0.01}deg)`,
|
||||
opacity: element.opacity,
|
||||
color: element.isText ? '#a8daff' : 'inherit',
|
||||
textShadow: element.isText ? '0 0 10px rgba(168, 218, 255, 0.3)' : 'none',
|
||||
filter: 'blur(0.5px)',
|
||||
animation: `float-${index % 3} ${6 + (index % 4)}s ease-in-out infinite`
|
||||
}}
|
||||
>
|
||||
{element.icon}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Lignes de connexion animées */}
|
||||
<svg
|
||||
className="absolute inset-0 w-full h-full opacity-[0.03]"
|
||||
style={{
|
||||
transform: `translateY(${scrollY * 0.2}px)`
|
||||
}}
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id="lineGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stopColor="#a8daff" stopOpacity="0" />
|
||||
<stop offset="50%" stopColor="#a8daff" stopOpacity="0.5" />
|
||||
<stop offset="100%" stopColor="#a8daff" stopOpacity="0" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
{/* Lignes de connexion entre les éléments */}
|
||||
{[...Array(8)].map((_, i) => (
|
||||
<line
|
||||
key={i}
|
||||
x1={`${10 + i * 12}%`}
|
||||
y1={`${20 + i * 8}%`}
|
||||
x2={`${30 + i * 15}%`}
|
||||
y2={`${40 + i * 12}%`}
|
||||
stroke="url(#lineGradient)"
|
||||
strokeWidth="1"
|
||||
className="animate-pulse"
|
||||
style={{
|
||||
animationDelay: `${i * 0.5}s`,
|
||||
animationDuration: `${3 + i}s`
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</svg>
|
||||
|
||||
{/* Cercles de données en mouvement */}
|
||||
<div className="absolute inset-0">
|
||||
{[...Array(6)].map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="absolute rounded-full border border-banquise-blue-lightest/5 animate-ping"
|
||||
style={{
|
||||
left: `${15 + i * 15}%`,
|
||||
top: `${25 + i * 12}%`,
|
||||
width: `${40 + i * 20}px`,
|
||||
height: `${40 + i * 20}px`,
|
||||
transform: `translateY(${scrollY * (0.1 + i * 0.05)}px)`,
|
||||
animationDelay: `${i * 1.2}s`,
|
||||
animationDuration: `${4 + i}s`
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -17,107 +17,114 @@ interface PopupProps {
|
||||
|
||||
export const Popup: React.FC<PopupProps> = ({ service, onClose }) => (
|
||||
<div className="fixed inset-0 bg-black/60 flex justify-center items-center z-50 p-4 backdrop-blur-md animate-fadeIn">
|
||||
<div className="bg-white text-banquise-blue-dark rounded-3xl max-w-4xl w-full max-h-[90vh] overflow-y-auto shadow-2xl relative animate-slideUp border border-banquise-blue-lightest/20">
|
||||
<div className="bg-white text-banquise-blue-dark rounded-3xl max-w-4xl w-full max-h-[90vh] shadow-2xl relative animate-slideUp border border-banquise-blue-lightest/20 overflow-hidden">
|
||||
|
||||
{/* Header */}
|
||||
<div className="relative bg-gradient-to-r from-banquise-blue to-banquise-blue-light p-6 sm:p-8 text-white">
|
||||
{/* Bouton de fermeture fixe au-dessus du contenu */}
|
||||
<div className="absolute top-4 right-4 z-50">
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="absolute top-4 sm:top-6 right-4 sm:right-6 bg-white/20 hover:bg-white/30 border-0 text-xl sm:text-2xl cursor-pointer text-white flex items-center justify-center w-10 h-10 sm:w-12 sm:h-12 rounded-full transition-all duration-200 backdrop-blur-sm hover:scale-110 active:scale-95"
|
||||
className="bg-white/90 hover:bg-white border border-banquise-blue/20 text-xl cursor-pointer text-banquise-blue-dark flex items-center justify-center w-10 h-10 sm:w-12 sm:h-12 rounded-full transition-all duration-200 hover:scale-110 active:scale-95 shadow-lg backdrop-blur-sm"
|
||||
aria-label="Fermer la popup"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
|
||||
<div className="flex flex-col lg:flex-row items-center lg:items-start mb-4 pr-12">
|
||||
<div className="w-16 h-16 sm:w-20 sm:h-20 lg:w-24 lg:h-24 bg-white/20 rounded-3xl flex items-center justify-center text-3xl sm:text-4xl lg:text-5xl mb-4 lg:mb-0 lg:mr-8 backdrop-blur-sm">
|
||||
{service.icon}
|
||||
</div>
|
||||
<div className="text-center lg:text-left flex-1">
|
||||
<h2 className="font-heading text-2xl sm:text-3xl lg:text-4xl mt-0 mb-3 lg:mb-4 leading-tight font-bold text-white">
|
||||
{service.name}
|
||||
</h2>
|
||||
<div className="text-white/90 text-base sm:text-lg lg:text-xl font-medium">
|
||||
Service d'hébergement professionnel
|
||||
</div>
|
||||
<div className="mt-4 lg:mt-6 flex flex-wrap gap-2">
|
||||
<span className="bg-white/20 text-white px-3 py-1 rounded-full text-sm font-medium backdrop-blur-sm">Haute disponibilité</span>
|
||||
<span className="bg-white/20 text-white px-3 py-1 rounded-full text-sm font-medium backdrop-blur-sm">Open Source</span>
|
||||
<span className="bg-white/20 text-white px-3 py-1 rounded-full text-sm font-medium backdrop-blur-sm">Communautaire</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Content - Forcer le fond blanc */}
|
||||
<div className="p-6 sm:p-8 bg-white">
|
||||
{/* Description */}
|
||||
<h3 className="text-xl sm:text-2xl lg:text-3xl mb-4 lg:mb-6 text-banquise-blue-dark font-heading font-bold flex items-center">
|
||||
<span className="text-xl sm:text-2xl lg:text-3xl mr-3">📋</span>
|
||||
Description détaillée
|
||||
</h3>
|
||||
<div className="bg-gradient-to-br from-banquise-blue/5 to-banquise-blue-light/5 rounded-2xl p-4 lg:p-6 border border-banquise-blue/10 mb-8">
|
||||
<p className="text-banquise-blue-dark/90 leading-relaxed text-base sm:text-lg lg:text-xl mb-4">
|
||||
{service.description}
|
||||
</p>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 mt-6">
|
||||
<div className="flex items-center p-3 bg-white/60 rounded-xl border border-banquise-blue/10">
|
||||
<div className="w-10 h-10 bg-gradient-to-br from-banquise-blue to-banquise-blue-light rounded-lg flex items-center justify-center text-white mr-3">
|
||||
✓
|
||||
</div>
|
||||
<div>
|
||||
<div className="font-semibold text-banquise-blue-dark text-sm">99.9% Uptime</div>
|
||||
<div className="text-banquise-blue-dark/70 text-xs">Disponibilité garantie</div>
|
||||
</div>
|
||||
|
||||
{/* Contenu avec scroll vertical uniquement */}
|
||||
<div className="overflow-y-auto overflow-x-hidden max-h-[90vh] popup-content">
|
||||
{/* Header */}
|
||||
<div className="relative bg-gradient-to-r from-banquise-blue to-banquise-blue-light p-6 sm:p-8 text-white pr-16 sm:pr-20">
|
||||
<div className="flex flex-col lg:flex-row items-center lg:items-start mb-4">
|
||||
<div className="w-16 h-16 sm:w-20 sm:h-20 lg:w-24 lg:h-24 bg-white/20 rounded-3xl flex items-center justify-center text-3xl sm:text-4xl lg:text-5xl mb-4 lg:mb-0 lg:mr-8 backdrop-blur-sm">
|
||||
{service.icon}
|
||||
</div>
|
||||
<div className="flex items-center p-3 bg-white/60 rounded-xl border border-banquise-blue/10">
|
||||
<div className="w-10 h-10 bg-gradient-to-br from-blue-500 to-blue-600 rounded-lg flex items-center justify-center text-white mr-3">
|
||||
🔒
|
||||
<div className="text-center lg:text-left flex-1">
|
||||
<h2 className="font-heading text-2xl sm:text-3xl lg:text-4xl mt-0 mb-3 lg:mb-4 leading-tight font-bold text-white">
|
||||
{service.name}
|
||||
</h2>
|
||||
<div className="text-white/90 text-base sm:text-lg lg:text-xl font-medium">
|
||||
Service d'hébergement professionnel
|
||||
</div>
|
||||
<div>
|
||||
<div className="font-semibold text-banquise-blue-dark text-sm">Sécurisé</div>
|
||||
<div className="text-banquise-blue-dark/70 text-xs">SSL & Backups</div>
|
||||
<div className="mt-4 lg:mt-6 flex flex-wrap gap-2 justify-center lg:justify-start">
|
||||
<span className="bg-white/20 text-white px-3 py-1 rounded-full text-sm font-medium backdrop-blur-sm">Haute disponibilité</span>
|
||||
<span className="bg-white/20 text-white px-3 py-1 rounded-full text-sm font-medium backdrop-blur-sm">Open Source</span>
|
||||
<span className="bg-white/20 text-white px-3 py-1 rounded-full text-sm font-medium backdrop-blur-sm">Communautaire</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Fonctionnalités */}
|
||||
<h3 className="text-xl sm:text-2xl lg:text-3xl mb-4 lg:mb-6 text-banquise-blue-dark font-heading font-bold flex items-center">
|
||||
<span className="text-xl sm:text-2xl lg:text-3xl mr-3">⚡</span>
|
||||
Fonctionnalités principales
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 mb-8">
|
||||
{service.features.map((feature, index) => (
|
||||
<div key={index} className="flex items-start bg-banquise-blue/5 rounded-xl p-4 border border-banquise-blue/10 hover:bg-banquise-blue/10 transition-colors duration-200 group">
|
||||
<div className="w-6 h-6 bg-gradient-to-br from-banquise-blue to-banquise-blue-light rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0 group-hover:scale-110 transition-transform duration-200">
|
||||
<div className="w-2 h-2 bg-white rounded-full"></div>
|
||||
{/* Content - Forcer le fond blanc */}
|
||||
<div className="p-6 sm:p-8 bg-white">
|
||||
{/* Description */}
|
||||
<h3 className="text-xl sm:text-2xl lg:text-3xl mb-4 lg:mb-6 text-banquise-blue-dark font-heading font-bold flex items-center">
|
||||
<span className="text-xl sm:text-2xl lg:text-3xl mr-3">📋</span>
|
||||
Description détaillée
|
||||
</h3>
|
||||
<div className="bg-gradient-to-br from-banquise-blue/5 to-banquise-blue-light/5 rounded-2xl p-4 lg:p-6 border border-banquise-blue/10 mb-8">
|
||||
<p className="text-banquise-blue-dark/90 leading-relaxed text-base sm:text-lg lg:text-xl mb-4">
|
||||
{service.description}
|
||||
</p>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 mt-6">
|
||||
<div className="flex items-center p-3 bg-white/60 rounded-xl border border-banquise-blue/10">
|
||||
<div className="w-10 h-10 bg-gradient-to-br from-banquise-blue to-banquise-blue-light rounded-lg flex items-center justify-center text-white mr-3">
|
||||
✓
|
||||
</div>
|
||||
<div>
|
||||
<div className="font-semibold text-banquise-blue-dark text-sm">99.9% Uptime</div>
|
||||
<div className="text-banquise-blue-dark/70 text-xs">Disponibilité garantie</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center p-3 bg-white/60 rounded-xl border border-banquise-blue/10">
|
||||
<div className="w-10 h-10 bg-gradient-to-br from-blue-500 to-blue-600 rounded-lg flex items-center justify-center text-white mr-3">
|
||||
🔒
|
||||
</div>
|
||||
<div>
|
||||
<div className="font-semibold text-banquise-blue-dark text-sm">Sécurisé</div>
|
||||
<div className="text-banquise-blue-dark/70 text-xs">SSL & Backups</div>
|
||||
</div>
|
||||
</div>
|
||||
<span className="text-banquise-blue-dark/90 font-medium text-sm lg:text-base leading-relaxed">{feature}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Call to action */}
|
||||
<div className="pt-6 lg:pt-8 border-t border-banquise-blue/10">
|
||||
<a
|
||||
href={service.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="w-full inline-flex items-center justify-center bg-gradient-to-r from-banquise-blue to-banquise-blue-light text-white border-0 py-4 px-6 sm:px-8 rounded-2xl cursor-pointer no-underline font-bold tracking-wide shadow-lg transition-all duration-300 hover:shadow-xl hover:-translate-y-1 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-banquise-blue-light text-base lg:text-lg hover:scale-[1.02] active:scale-95"
|
||||
>
|
||||
<span className="mr-3 text-xl lg:text-2xl">🚀</span>
|
||||
<span>Accéder à {service.name}</span>
|
||||
</a>
|
||||
|
||||
<p className="text-center text-sm text-banquise-blue-dark/60 mt-4">
|
||||
Besoin d'aide ? Rejoignez notre <a href={URLS.social.discord} className="text-banquise-blue hover:text-banquise-blue-dark transition-colors duration-200 font-medium">Discord</a> pour obtenir du support
|
||||
</p>
|
||||
{/* Fonctionnalités */}
|
||||
<h3 className="text-xl sm:text-2xl lg:text-3xl mb-4 lg:mb-6 text-banquise-blue-dark font-heading font-bold flex items-center">
|
||||
<span className="text-xl sm:text-2xl lg:text-3xl mr-3">⚡</span>
|
||||
Fonctionnalités principales
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 mb-8">
|
||||
{service.features.map((feature, index) => (
|
||||
<div key={index} className="flex items-start bg-banquise-blue/5 rounded-xl p-4 border border-banquise-blue/10 hover:bg-banquise-blue/10 transition-colors duration-200 group">
|
||||
<div className="w-6 h-6 bg-gradient-to-br from-banquise-blue to-banquise-blue-light rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0 group-hover:scale-110 transition-transform duration-200">
|
||||
<div className="w-2 h-2 bg-white rounded-full"></div>
|
||||
</div>
|
||||
<span className="text-banquise-blue-dark/90 font-medium text-sm lg:text-base leading-relaxed">{feature}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Call to action */}
|
||||
<div className="pt-6 lg:pt-8 border-t border-banquise-blue/10">
|
||||
<a
|
||||
href={service.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="w-full inline-flex items-center justify-center bg-gradient-to-r from-banquise-blue to-banquise-blue-light text-white border-0 py-4 px-6 sm:px-8 rounded-2xl cursor-pointer no-underline font-bold tracking-wide shadow-lg transition-all duration-300 hover:shadow-xl hover:-translate-y-1 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-banquise-blue-light text-base lg:text-lg hover:scale-[1.02] active:scale-95"
|
||||
>
|
||||
<span className="mr-3 text-xl lg:text-2xl">🚀</span>
|
||||
<span>Accéder à {service.name}</span>
|
||||
</a>
|
||||
|
||||
<p className="text-center text-sm text-banquise-blue-dark/60 mt-4">
|
||||
Besoin d'aide ? Rejoignez notre <a href={URLS.social.discord} className="text-banquise-blue hover:text-banquise-blue-dark transition-colors duration-200 font-medium">Discord</a> pour obtenir du support
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Decorative elements */}
|
||||
<div className="absolute top-0 right-0 w-16 h-16 sm:w-24 sm:h-24 lg:w-32 lg:h-32 bg-banquise-blue-lightest/10 rounded-full -translate-y-8 translate-x-8 sm:-translate-y-12 sm:translate-x-12 lg:-translate-y-16 lg:translate-x-16 hidden sm:block"></div>
|
||||
<div className="absolute bottom-0 left-0 w-12 h-12 sm:w-16 sm:h-16 lg:w-24 lg:h-24 bg-banquise-blue/5 rounded-full translate-y-6 -translate-x-6 sm:translate-y-8 sm:-translate-x-8 lg:translate-y-12 lg:-translate-x-12 hidden sm:block"></div>
|
||||
<div className="absolute top-0 right-0 w-16 h-16 sm:w-24 sm:h-24 lg:w-32 lg:h-32 bg-banquise-blue-lightest/10 rounded-full -translate-y-8 translate-x-8 sm:-translate-y-12 sm:translate-x-12 lg:-translate-y-16 lg:translate-x-16 hidden sm:block pointer-events-none"></div>
|
||||
<div className="absolute bottom-0 left-0 w-12 h-12 sm:w-16 sm:h-16 lg:w-24 lg:h-24 bg-banquise-blue/5 rounded-full translate-y-6 -translate-x-6 sm:translate-y-8 sm:-translate-x-8 lg:translate-y-12 lg:-translate-x-12 hidden sm:block pointer-events-none"></div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
51
banquise-website/src/components/ui/ScrollToTopButton.tsx
Normal file
51
banquise-website/src/components/ui/ScrollToTopButton.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
|
||||
export const ScrollToTopButton: React.FC = () => {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const toggleVisibility = () => {
|
||||
// Afficher le bouton après avoir scrollé 300px
|
||||
setIsVisible(window.scrollY > 300);
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', toggleVisibility);
|
||||
return () => window.removeEventListener('scroll', toggleVisibility);
|
||||
}, []);
|
||||
|
||||
const scrollToTop = () => {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={scrollToTop}
|
||||
className={`fixed bottom-6 right-6 z-50 w-12 h-12 sm:w-14 sm:h-14 bg-gradient-to-r from-banquise-blue to-banquise-blue-light text-white rounded-full shadow-lg hover:shadow-xl transition-all duration-300 flex items-center justify-center group border border-banquise-blue-lightest/30 backdrop-blur-sm ${
|
||||
isVisible
|
||||
? 'opacity-100 translate-y-0 scale-100'
|
||||
: 'opacity-0 translate-y-4 scale-95 pointer-events-none'
|
||||
}`}
|
||||
aria-label="Retour en haut de page"
|
||||
>
|
||||
<svg
|
||||
className="w-5 h-5 sm:w-6 sm:h-6 transition-transform duration-300 group-hover:-translate-y-0.5"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2.5}
|
||||
d="M7 11l5-5m0 0l5 5m-5-5v12"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
{/* Effet de lueur au hover */}
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-banquise-blue-light to-banquise-blue rounded-full opacity-0 group-hover:opacity-75 transition-opacity duration-300 blur-sm"></div>
|
||||
</button>
|
||||
);
|
||||
};
|
@ -50,6 +50,64 @@
|
||||
50% { transform: translateY(-30px) rotate(-2deg); }
|
||||
}
|
||||
|
||||
/* Animations pour les éléments flottants */
|
||||
@keyframes float-0 {
|
||||
0%, 100% { transform: translateY(0px) rotate(0deg); }
|
||||
50% { transform: translateY(-10px) rotate(2deg); }
|
||||
}
|
||||
|
||||
@keyframes float-1 {
|
||||
0%, 100% { transform: translateY(0px) rotate(0deg); }
|
||||
33% { transform: translateY(-8px) rotate(-1deg); }
|
||||
66% { transform: translateY(-15px) rotate(1deg); }
|
||||
}
|
||||
|
||||
@keyframes float-2 {
|
||||
0%, 100% { transform: translateY(0px) rotate(0deg); }
|
||||
25% { transform: translateY(-12px) rotate(1deg); }
|
||||
75% { transform: translateY(-6px) rotate(-2deg); }
|
||||
}
|
||||
|
||||
/* Animation pour l'élément principal du hero */
|
||||
@keyframes gentle-float {
|
||||
0%, 100% { transform: translateY(0px) rotate(0deg); }
|
||||
50% { transform: translateY(-15px) rotate(1deg); }
|
||||
}
|
||||
|
||||
.animate-gentle-float {
|
||||
animation: gentle-float 6s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Effet de lueur pour les éléments techniques */
|
||||
@keyframes glow-pulse {
|
||||
0%, 100% {
|
||||
text-shadow: 0 0 5px rgba(168, 218, 255, 0.3),
|
||||
0 0 10px rgba(168, 218, 255, 0.2),
|
||||
0 0 15px rgba(168, 218, 255, 0.1);
|
||||
}
|
||||
50% {
|
||||
text-shadow: 0 0 10px rgba(168, 218, 255, 0.4),
|
||||
0 0 20px rgba(168, 218, 255, 0.3),
|
||||
0 0 30px rgba(168, 218, 255, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Animation des lignes de connexion */
|
||||
@keyframes data-flow {
|
||||
0% { stroke-dasharray: 0, 100; }
|
||||
50% { stroke-dasharray: 50, 100; }
|
||||
100% { stroke-dasharray: 100, 100; }
|
||||
}
|
||||
|
||||
/* Responsive pour les animations */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.animate-gentle-float,
|
||||
.animate-ping,
|
||||
.animate-pulse {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply animations */
|
||||
.animate-parallax-slow {
|
||||
animation: parallax-slow 20s ease-in-out infinite;
|
||||
@ -82,3 +140,46 @@
|
||||
.animate-float-very-slow {
|
||||
animation: float-very-slow 12s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Amélioration du scroll */
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* Empêcher le scroll horizontal global */
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* Styles pour les popups */
|
||||
.popup-content {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(31, 93, 137, 0.3) transparent;
|
||||
}
|
||||
|
||||
.popup-content::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.popup-content::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.popup-content::-webkit-scrollbar-thumb {
|
||||
background: rgba(31, 93, 137, 0.3);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.popup-content::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(31, 93, 137, 0.5);
|
||||
}
|
||||
|
||||
/* Animation pour le bouton scroll to top */
|
||||
@keyframes bounce-up {
|
||||
0%, 100% { transform: translateY(0px); }
|
||||
50% { transform: translateY(-4px); }
|
||||
}
|
||||
|
||||
.scroll-to-top:hover {
|
||||
animation: bounce-up 0.6s ease-in-out;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user