-
-
- {/* Header */}
-
-
+export const Popup: React.FC
= ({ service, onClose }) => {
+ // Empêcher le scroll du body quand la popup est ouverte
+ useEffect(() => {
+ document.body.style.overflow = 'hidden';
+
+ return () => {
+ document.body.style.overflow = 'unset';
+ };
+ }, []);
+
+ return (
+
+
-
-
- {service.icon}
-
-
-
- {service.name}
-
-
- Service d'hébergement professionnel
-
-
- Haute disponibilité
- Open Source
- Communautaire
-
-
-
-
-
- {/* Content - Layout simplifié */}
-
- {/* Description */}
-
- 📋
- Description détaillée
-
-
-
- {service.description}
-
-
-
-
- ✓
-
-
-
99.9% Uptime
-
Disponibilité garantie
-
-
-
-
- 🔒
-
-
-
Sécurisé
-
SSL & Backups
-
-
-
-
-
- {/* Fonctionnalités en colonnes */}
-
- ⚡
- Fonctionnalités principales
-
-
- {service.features.map((feature, index) => (
-
- ))}
-
-
- {/* Call to action simplifié */}
-
-
+
+ {/* Contenu avec scroll vertical uniquement */}
+
+ {/* Header */}
+
+
+
+ {service.icon}
+
+
+
+ {service.name}
+
+
+ Service d'hébergement professionnel
+
+
+ Haute disponibilité
+ Open Source
+ Communautaire
+
+
+
+
- {/* Decorative elements - améliorés pour desktop */}
-
-
-
+ {/* Content - Forcer le fond blanc */}
+
+ {/* Description */}
+
+ 📋
+ Description détaillée
+
+
+
+ {service.description}
+
+
+
+
+ ✓
+
+
+
99.9% Uptime
+
Disponibilité garantie
+
+
+
+
+ 🔒
+
+
+
Sécurisé
+
SSL & Backups
+
+
+
+
+
+ {/* Fonctionnalités */}
+
+ ⚡
+ Fonctionnalités principales
+
+
+ {service.features.map((feature, index) => (
+
+ ))}
+
+
+ {/* Call to action */}
+
+
+
+
+ {/* Decorative elements */}
+
+
+
-
-);
+ );
+};
diff --git a/banquise-website/src/components/ui/ScrollToTopButton.tsx b/banquise-website/src/components/ui/ScrollToTopButton.tsx
new file mode 100644
index 0000000..a05463b
--- /dev/null
+++ b/banquise-website/src/components/ui/ScrollToTopButton.tsx
@@ -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 (
+
+ );
+};
diff --git a/banquise-website/src/config/constants.ts b/banquise-website/src/config/constants.ts
new file mode 100644
index 0000000..5a493bf
--- /dev/null
+++ b/banquise-website/src/config/constants.ts
@@ -0,0 +1,20 @@
+export const URLS = {
+ services: {
+ wiki: "https://wiki.la-banquise.fr",
+ gitea: "https://git.la-banquise.fr",
+ panel: "https://panel.la-banquise.fr",
+ auth: "https://auth.la-banquise.fr"
+ },
+ social: {
+ discord: "https://discord.gg/labanquise"
+ },
+ contact: {
+ email: "mailto:contact@la-banquise.fr"
+ }
+} as const;
+
+export const SITE_CONFIG = {
+ name: "La Banquise",
+ description: "Association d'hébergement et lab réseau pour tous les étudiants et associations de l'EPITA",
+ tagline: "Communauté • Hébergement"
+} as const;
diff --git a/banquise-website/src/index.css b/banquise-website/src/index.css
index 0c610c7..ca06f66 100644
--- a/banquise-website/src/index.css
+++ b/banquise-website/src/index.css
@@ -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;
+}
diff --git a/banquise-website/src/main.tsx b/banquise-website/src/main.tsx
index bef5202..e3f1654 100644
--- a/banquise-website/src/main.tsx
+++ b/banquise-website/src/main.tsx
@@ -3,6 +3,18 @@ import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
+// Ajouter les métadonnées SEO
+document.title = 'La Banquise - Hébergement et Communauté Tech';
+const metaDescription = document.createElement('meta');
+metaDescription.name = 'description';
+metaDescription.content = 'Association d\'hébergement et lab réseau pour tous les étudiants et associations de l\'EPITA. Services Wiki, Gitea, Panel de jeux.';
+document.head.appendChild(metaDescription);
+
+const metaViewport = document.createElement('meta');
+metaViewport.name = 'viewport';
+metaViewport.content = 'width=device-width, initial-scale=1.0';
+document.head.appendChild(metaViewport);
+
createRoot(document.getElementById('root')!).render(
diff --git a/banquise-website/src/styles/components.ts b/banquise-website/src/styles/components.ts
new file mode 100644
index 0000000..48fcabf
--- /dev/null
+++ b/banquise-website/src/styles/components.ts
@@ -0,0 +1,63 @@
+export const commonStyles = {
+ // Gradients
+ gradients: {
+ primary: "bg-gradient-to-r from-banquise-blue to-banquise-blue-light",
+ primaryBr: "bg-gradient-to-br from-banquise-blue to-banquise-blue-light",
+ card: "bg-gradient-to-br from-banquise-blue-dark/10 to-banquise-blue-dark/5",
+ cardHover: "hover:from-banquise-blue-dark/15 hover:to-banquise-blue-dark/8",
+ discord: "bg-gradient-to-r from-indigo-600 to-purple-600",
+ discordHover: "hover:from-indigo-500 hover:to-purple-500"
+ },
+
+ // Buttons
+ buttons: {
+ primary: "inline-flex items-center justify-center font-bold text-white border-0 rounded-2xl transition-all duration-300 hover:shadow-xl hover:-translate-y-1 hover:scale-105 active:scale-95",
+ discord: "group relative overflow-hidden px-4 lg:px-6 py-2.5 lg:py-3 text-white font-semibold text-sm lg:text-base rounded-xl transition-all duration-300 hover:shadow-xl hover:shadow-indigo-500/25 hover:-translate-y-1 hover:scale-105",
+ auth: "group relative overflow-hidden px-4 lg:px-6 py-2.5 lg:py-3 text-white font-semibold text-sm lg:text-base rounded-xl transition-all duration-300 hover:shadow-xl hover:-translate-y-1 hover:scale-105"
+ },
+
+ // Cards
+ cards: {
+ base: "backdrop-blur-lg rounded-2xl border border-banquise-blue-lightest/30 transition-all duration-300",
+ hover: "hover:shadow-xl hover:border-banquise-blue-lightest/50",
+ interactive: "cursor-pointer hover:-translate-y-4 hover:shadow-2xl active:scale-95"
+ },
+
+ // Text - Hiérarchie améliorée
+ text: {
+ heading: "font-heading font-bold tracking-tight",
+ // Titres principaux de section
+ headingXl: "text-3xl sm:text-4xl md:text-5xl text-banquise-gray font-heading font-bold tracking-tight",
+ headingLg: "text-2xl sm:text-3xl md:text-4xl text-banquise-gray font-heading font-bold tracking-tight",
+ headingMd: "text-xl sm:text-2xl md:text-3xl text-banquise-blue-dark font-heading font-bold tracking-tight",
+ headingSm: "text-lg sm:text-xl md:text-2xl text-banquise-blue-dark font-heading font-semibold tracking-tight",
+ // Sous-titres
+ subheading: "text-base sm:text-lg md:text-xl text-banquise-gray/90 font-medium leading-relaxed",
+ // Corps de texte
+ body: "text-sm sm:text-base md:text-lg text-banquise-blue-dark/90 leading-relaxed",
+ description: "text-banquise-gray/80 leading-relaxed",
+ muted: "text-banquise-gray/90 leading-relaxed",
+ // Texte sur fond sombre
+ lightHeading: "text-banquise-blue-lightest font-heading font-bold tracking-tight",
+ lightBody: "text-white/90 leading-relaxed"
+ },
+
+ // Layout
+ layout: {
+ section: "py-12 sm:py-16 md:py-20 w-full max-w-6xl mx-auto px-4 sm:px-6 md:px-8",
+ container: "max-w-6xl mx-auto",
+ divider: "w-20 h-1 bg-gradient-to-r from-banquise-blue-lightest to-banquise-blue mx-auto mb-6 sm:mb-8 rounded-full"
+ },
+
+ // Icons and decorative elements
+ icons: {
+ base: "w-16 h-16 sm:w-20 sm:h-20 lg:w-24 lg:h-24 rounded-2xl flex items-center justify-center text-3xl sm:text-4xl lg:text-5xl shadow-lg",
+ small: "w-10 h-10 rounded-lg flex items-center justify-center text-white"
+ },
+
+ // Navigation
+ nav: {
+ link: "px-4 lg:px-6 py-2.5 lg:py-3 text-white/90 hover:text-white font-medium text-sm lg:text-base rounded-xl transition-all duration-300 hover:bg-white/10 hover:backdrop-blur-sm relative group",
+ mobileItem: "group flex items-center p-4 text-white/90 hover:text-white no-underline rounded-2xl hover:bg-gradient-to-r hover:from-banquise-blue/20 hover:to-banquise-blue-light/20 transition-all duration-300 border border-transparent hover:border-banquise-blue-lightest/20"
+ }
+} as const;
diff --git a/banquise-website/src/types/index.ts b/banquise-website/src/types/index.ts
new file mode 100644
index 0000000..3c8eb7a
--- /dev/null
+++ b/banquise-website/src/types/index.ts
@@ -0,0 +1,15 @@
+export interface Service {
+ name: string;
+ url: string;
+ image: string;
+ description: string;
+ features: string[];
+ icon: string;
+}
+
+export interface AccordionItemProps {
+ title: string;
+ children: React.ReactNode;
+ isOpen: boolean;
+ onToggle: () => void;
+}