diff --git a/README.md b/README.md index a908d42..694c8a0 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,66 @@ -# website-front -test +# Website Front pour Banquise + +Ce projet est une application web React développée avec Vite, TypeScript et TailwindCSS. + +## Architecture du Projet + +``` +website-front/ +├── banquise-website/ # Application React principale +│ ├── public/ # Fichiers statiques +│ ├── src/ # Code source +│ │ ├── assets/ # Images et ressources +│ │ ├── App.tsx # Composant principal +│ │ └── main.tsx # Point d'entrée de l'application +│ ├── index.html # Template HTML principal +│ ├── package.json # Configuration des dépendances +│ ├── tsconfig.json # Configuration TypeScript +│ ├── vite.config.ts # Configuration Vite +│ └── tailwind.config.js # Configuration TailwindCSS +└── shell.nix # Configuration pour environnement Nix +``` + +## Technologies Utilisées + +- **React 18** - Bibliothèque d'interface utilisateur +- **TypeScript** - Langage de programmation typé +- **Vite** - Outil de build et serveur de développement +- **TailwindCSS** - Framework CSS utilitaire +- **React Router** - Navigation entre les pages +- **Zustand** - Gestion d'état +- **React Query** - Gestion des requêtes API +- **Framer Motion** - Animations + +## Pré-requis + +- Node.js (v16.0.0 ou supérieur) +- npm ou yarn + +## Installation + +```bash +# Se déplacer dans le dossier du projet +cd banquise-website + +# Installer les dépendances +npm install +# ou avec yarn +yarn +``` + +## Scripts Disponibles + +- `npm run dev` - Lance le serveur de développement +- `npm run build` - Compile le projet pour la production +- `npm run preview` - Prévisualise la version de production localement +- `npm run lint` - Vérifie la qualité du code avec ESLint + +## Déploiement + +### Compilation pour la Production + +```bash +npm run build +``` + +Cette commande générera un dossier `dist` dans le répertoire `banquise-website/` contenant tous les fichiers optimisés pour la production. \ No newline at end of file diff --git a/banquise-website/.gitignore b/banquise-website/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/banquise-website/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/banquise-website/README.md b/banquise-website/README.md new file mode 100644 index 0000000..da98444 --- /dev/null +++ b/banquise-website/README.md @@ -0,0 +1,54 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: + +```js +export default tseslint.config({ + extends: [ + // Remove ...tseslint.configs.recommended and replace with this + ...tseslint.configs.recommendedTypeChecked, + // Alternatively, use this for stricter rules + ...tseslint.configs.strictTypeChecked, + // Optionally, add this for stylistic rules + ...tseslint.configs.stylisticTypeChecked, + ], + languageOptions: { + // other options... + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + }, +}) +``` + +You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: + +```js +// eslint.config.js +import reactX from 'eslint-plugin-react-x' +import reactDom from 'eslint-plugin-react-dom' + +export default tseslint.config({ + plugins: { + // Add the react-x and react-dom plugins + 'react-x': reactX, + 'react-dom': reactDom, + }, + rules: { + // other rules... + // Enable its recommended typescript rules + ...reactX.configs['recommended-typescript'].rules, + ...reactDom.configs.recommended.rules, + }, +}) +``` diff --git a/banquise-website/build.sh b/banquise-website/build.sh new file mode 100755 index 0000000..734716c --- /dev/null +++ b/banquise-website/build.sh @@ -0,0 +1,2 @@ +npm install +npm run build diff --git a/banquise-website/eslint.config.js b/banquise-website/eslint.config.js new file mode 100644 index 0000000..092408a --- /dev/null +++ b/banquise-website/eslint.config.js @@ -0,0 +1,28 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' + +export default tseslint.config( + { ignores: ['dist'] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ['**/*.{ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, + }, +) diff --git a/banquise-website/index.html b/banquise-website/index.html new file mode 100644 index 0000000..ee5ab91 --- /dev/null +++ b/banquise-website/index.html @@ -0,0 +1,19 @@ + + + + + + + + + La Banquise - Services d'hébergement + + + + + + +
+ + + diff --git a/banquise-website/package.json b/banquise-website/package.json new file mode 100644 index 0000000..5bbfe07 --- /dev/null +++ b/banquise-website/package.json @@ -0,0 +1,44 @@ +{ + "name": "banquise-website", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "axios": "^1.6.5", + "clsx": "^2.1.0", + "framer-motion": "^10.18.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-icons": "^4.12.0", + "react-router-dom": "^6.22.0", + "@tanstack/react-query": "^5.17.9", + "tailwind-merge": "^2.2.0", + "zustand": "^4.4.7" + }, + "devDependencies": { + "@eslint/js": "^9.25.0", + "@tailwindcss/forms": "^0.5.7", + "@tailwindcss/typography": "^0.5.10", + "@types/react": "^18.2.58", + "@types/react-dom": "^18.2.19", + "@vitejs/plugin-react": "^4.4.1", + "autoprefixer": "^10.4.16", + "eslint": "^9.25.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.19", + "eslint-plugin-tailwindcss": "^3.14.0", + "globals": "^16.0.0", + "postcss": "^8.4.33", + "typescript": "~5.8.3", + "typescript-eslint": "^8.30.1", + "vite": "^6.3.5", + "vite-plugin-compression": "^0.5.1", + "tailwindcss": "^3.4.1" + } +} diff --git a/banquise-website/postcss.config.js b/banquise-website/postcss.config.js new file mode 100644 index 0000000..2e7af2b --- /dev/null +++ b/banquise-website/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/banquise-website/src/App.css b/banquise-website/src/App.css new file mode 100644 index 0000000..b82c161 --- /dev/null +++ b/banquise-website/src/App.css @@ -0,0 +1,1124 @@ +#root { + max-width: 100%; + margin: 0; + padding: 0; + text-align: center; + width: 100%; +} + +.app-container { + display: flex; + flex-direction: column; + min-height: 100vh; + width: 100%; +} + +/* Navigation */ +.navbar { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.8rem 2rem; + background-color: rgba(31, 93, 137, 0.95); /* #1F5D89 avec transparence */ + color: white; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + width: 100%; + box-sizing: border-box; + z-index: 10; + backdrop-filter: blur(8px); + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + position: sticky; + top: 0; +} + +.navbar-left { + display: flex; + align-items: center; +} + +.site-logo { + height: 2.2rem; + width: auto; + margin-right: 1rem; + filter: drop-shadow(0 0 5px rgba(168, 218, 255, 0.4)); +} + +.site-name { + font-size: 1.6rem; + font-weight: 700; + margin: 0; + color: #ffffff; + letter-spacing: 0.5px; + font-family: var(--font-heading); +} + +.navbar-right { + display: flex; + align-items: center; + gap: 12px; +} + +.discord-button { + display: flex; + align-items: center; + background-color: #40B4FF; + color: white; + border: none; + padding: 0.6rem 1.2rem; + border-radius: 6px; + cursor: pointer; + text-decoration: none; + font-weight: 600; + letter-spacing: 0.3px; + box-shadow: 0 2px 8px rgba(64, 180, 255, 0.4); + transition: all 0.2s ease; +} + +.discord-button:hover { + background-color: #2ba3f7; + color: #ffffff; + text-shadow: 0 0 1px rgba(255, 255, 255, 0.5); + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(64, 180, 255, 0.6); +} + +.discord-button:focus-visible { + outline: 3px solid #ffffff; + outline-offset: 2px; + background-color: #2ba3f7; +} + +.login-button { + display: flex; + align-items: center; + background-color: rgba(105, 183, 226, 0.9); /* #69B7E2 */ + color: white; + border: none; + padding: 0.6rem 1.2rem; + border-radius: 6px; + cursor: pointer; + text-decoration: none; + font-weight: 600; + letter-spacing: 0.3px; + box-shadow: 0 2px 8px rgba(105, 183, 226, 0.3); + transition: all 0.2s ease; +} + +.login-button:hover { + background-color: #69B7E2; + color: #ffffff; + text-shadow: 0 0 1px rgba(255, 255, 255, 0.5); + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(105, 183, 226, 0.5); +} + +.login-button:focus-visible { + outline: 3px solid #ffffff; + outline-offset: 2px; + background-color: #69B7E2; +} + +.login-icon { + margin-right: 0.5rem; +} + +.content { + flex: 1; + display: flex; + flex-direction: column; + overflow-x: hidden; + overflow-y: auto; +} + +.ocean { + position: relative; + flex: 1; + background: linear-gradient(180deg, #40B4FF 0%, #69B7E2 50%, #1F5D89 100%); + width: 100%; + min-height: calc(100vh - 72px); + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + overflow-x: hidden; +} + +.page-section { + width: 100%; + max-width: 1200px; + margin: 1rem auto; + padding: 2rem 2rem; + position: relative; + z-index: 3; + display: flex; + flex-direction: column; + align-items: center; + box-sizing: border-box; +} + +.hero-section { + min-height: calc(70vh - 72px); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + text-align: center; + padding-top: 2rem; + padding-bottom: 3rem; + margin-top: 0; +} + +.hero-title { + color: #F6F6F6; + font-size: 3.5rem; + margin-bottom: 1.5rem; + font-weight: 800; + text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); + line-height: 1.1; + max-width: 800px; +} + +.hero-subtitle { + color: #F6F6F6; + font-size: 1.5rem; + margin-bottom: 2.5rem; + max-width: 700px; + font-weight: 400; + opacity: 0.9; + text-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); +} + +.cta-button { + display: inline-flex; + align-items: center; + justify-content: center; + background-color: #F6F6F6; + color: #1F5D89; + border: none; + padding: 1rem 2.5rem; + border-radius: 30px; + font-size: 1.1rem; + font-weight: 600; + text-decoration: none; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15); + transition: all 0.3s ease; + min-width: 200px; +} + +.cta-button:hover { + transform: translateY(-3px); + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2); + background-color: #ffffff; +} + +.cta-icon { + margin-left: 0.75rem; + transition: transform 0.2s ease; +} + +.cta-button:hover .cta-icon { + transform: translateX(3px); +} + +.section-divider { + width: 80px; + height: 4px; + background: linear-gradient(90deg, #A5F0FF, #40B4FF); + margin: 0 auto 2rem; + border-radius: 2px; +} + +.section-title { + color: #F6F6F6; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + font-size: 2.5rem; + margin-bottom: 1rem; + text-align: center; + font-family: var(--font-heading); + font-weight: 700; + letter-spacing: -0.01em; +} + +.section-subtitle { + color: #F6F6F6; + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); + font-size: 1.25rem; + opacity: 0.9; + margin-bottom: 3.5rem; + max-width: 800px; + text-align: center; +} + +.services-section { + position: relative; + z-index: 2; + padding-top: 2rem; + padding-bottom: 4rem; + margin-top: 0; + margin-bottom: 1rem; +} + +.icebergs-container { + position: relative; + width: 100%; + max-width: 1000px; + height: auto; + min-height: 350px; + z-index: 2; + display: flex; + justify-content: center; + align-items: center; + margin: 2rem auto; + padding: 0; + gap: 5%; +} + +.iceberg { + cursor: pointer; + text-decoration: none; + width: 250px; + height: 200px; + display: flex; + align-items: center; + justify-content: center; + transition: transform 0.3s ease; + z-index: 3; + margin: 0; +} + +.iceberg:hover { + transform: translateY(-10px) !important; +} + +.float-1, .float-2, .float-3 { + animation: none; +} + +.iceberg img { + width: 100%; + height: auto; + max-width: 250px; + max-height: 200px; + object-fit: contain; + filter: drop-shadow(0 10px 15px rgba(0, 0, 0, 0.3)); +} + +.service-name { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + color: #1F5D89; + font-weight: 700; + font-size: 1.4rem; + background-color: rgba(255, 255, 255, 0.92); + padding: 12px 20px; + border-radius: 10px; + text-align: center; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15), 0 0 0 2px rgba(165, 240, 255, 0.5); /* #A5F0FF */ + z-index: 4; + font-family: var(--font-heading); + letter-spacing: -0.01em; + border: 1px solid rgba(165, 240, 255, 0.8); + backdrop-filter: blur(4px); + transition: all 0.3s ease; + min-width: 160px; + max-width: 90%; + width: auto; +} + +.iceberg:hover .service-name { + background-color: rgba(255, 255, 255, 0.97); + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2), 0 0 0 3px rgba(165, 240, 255, 0.7); + transform: translate(-50%, -55%); + color: #40B4FF; +} + +.float-1 { + animation: float1 5s ease-in-out infinite; +} + +.float-2 { + animation: float2 6s ease-in-out infinite; +} + +.float-3 { + animation: float3 7s ease-in-out infinite; +} + +@keyframes float1 { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-15px); } +} + +@keyframes float2 { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-20px); } +} + +@keyframes float3 { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-10px); } +} + +.about-section { + position: relative; + background-color: rgba(31, 93, 137, 0.15); + backdrop-filter: blur(10px); + margin: 1rem 0; + padding: 3rem 2rem; + z-index: 2; + border-top: 1px solid rgba(255, 255, 255, 0.1); + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + width: 100%; + box-sizing: border-box; +} + +.about-container { + max-width: 1000px; + margin: 0 auto; + display: flex; + flex-direction: column; + align-items: center; + width: 100%; +} + +/* Modern FAQ Accordion Styles */ +.accordion-group { + width: 100%; + display: flex; + flex-direction: column; + gap: 1rem; + margin-top: 1.5rem; +} + +.accordion-item { + background: rgba(31, 93, 137, 0.1); + border-radius: 12px; + overflow: hidden; + border: 1px solid rgba(165, 240, 255, 0.2); + transition: all 0.3s ease; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05); +} + +.accordion-item:hover { + background: rgba(31, 93, 137, 0.2); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1); +} + +.accordion-header { + padding: 1.2rem 1.5rem; + cursor: pointer; + display: flex; + align-items: center; + justify-content: space-between; + font-weight: 600; + color: #F6F6F6; + background: rgba(31, 93, 137, 0.2); + transition: all 0.2s ease; + font-size: 1.1rem; + user-select: none; +} + +.accordion-header:hover { + background: rgba(64, 180, 255, 0.2); +} + +.accordion-toggle-icon { + font-size: 1.2rem; + transition: transform 0.3s ease; + color: #A5F0FF; +} + +.accordion-item.active .accordion-toggle-icon { + transform: rotate(180deg); +} + +.accordion-content { + max-height: 0; + overflow: hidden; + transition: max-height 0.5s cubic-bezier(0, 1, 0, 1), padding 0.3s ease; + background: rgba(31, 93, 137, 0.05); + line-height: 1.6; + font-size: 1rem; + color: rgba(246, 246, 246, 0.9); +} + +.accordion-item.active .accordion-content { + max-height: 1000px; + transition: max-height 1s ease-in-out, padding 0.3s ease; + padding: 1.5rem; +} + +.accordion-content p { + margin-top: 0; +} + +.accordion-content p:last-child { + margin-bottom: 0; +} + +.accordion-content ul { + margin-top: 0.5rem; + margin-bottom: 0.5rem; + padding-left: 1.5rem; +} + +.accordion-content li { + margin-bottom: 0.5rem; +} + +.about-image-container { + max-width: 180px; + margin: 0 auto 2rem; + position: relative; + z-index: 2; +} + +.about-logo { + width: 100%; + height: auto; + border-radius: 50%; + padding: 1rem; + background: rgba(255, 255, 255, 0.05); + border: 2px solid rgba(165, 240, 255, 0.3); + box-shadow: 0 10px 25px rgba(31, 93, 137, 0.3); + animation: gentle-float 6s ease-in-out infinite; +} + +@keyframes gentle-float { + 0%, 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-10px); + } +} + +.about-intro { + text-align: center; + max-width: 800px; + margin: 0 auto 2rem; + color: #F6F6F6; + font-size: 1.1rem; + line-height: 1.6; +} + +.accordion-cta { + display: inline-flex; + align-items: center; + background-color: #40B4FF; + color: white; + border: none; + padding: 0.7rem 1.2rem; + border-radius: 6px; + margin-top: 0.5rem; + text-decoration: none; + font-weight: 600; + transition: all 0.2s ease; +} + +.accordion-cta:hover { + background-color: #2ba3f7; + transform: translateY(-2px); +} + +.accordion-cta-icon { + margin-left: 0.5rem; + font-size: 0.9rem; +} + +/* Media queries for responsive design */ +@media (max-width: 768px) { + .about-section { + padding: 2rem 1.2rem; + } + + .about-image-container { + max-width: 140px; + margin-bottom: 1.5rem; + } + + .accordion-header { + padding: 1rem 1.2rem; + font-size: 1rem; + } + + .accordion-item.active .accordion-content { + padding: 1.2rem; + } + + .accordion-toggle-icon { + font-size: 1.1rem; + } +} + +/* ...existing code... */ + +.about-text { + flex: 1; + min-width: 300px; + max-width: 600px; + color: white; + text-align: left; +} + +.about-text h3 { + font-size: 2rem; + margin-bottom: 1.5rem; + color: white; + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); +} + +.about-text p { + margin-bottom: 1.25rem; + line-height: 1.7; + font-size: 1.1rem; +} + +.about-image { + flex: 1; + min-width: 300px; + max-width: 500px; + display: flex; + justify-content: center; + align-items: center; +} + +.about-image img { + width: 100%; + height: auto; + border-radius: 12px; + box-shadow: 0 15px 30px rgba(0, 0, 0, 0.25); + transform: perspective(1000px) rotateY(-5deg); + transition: transform 0.5s ease; +} + +.about-image img:hover { + transform: perspective(1000px) rotateY(0); +} + +/* Statistiques */ +.stats-section { + background: linear-gradient(180deg, rgba(64, 180, 255, 0.2) 0%, rgba(31, 93, 137, 0) 100%); + padding: 4rem 2rem; + position: relative; + z-index: 2; +} + +.stats-container { + max-width: 1200px; + margin: 0 auto; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 2rem; +} + +.stat-card { + background: rgba(31, 93, 137, 0.1); + border-radius: 12px; + padding: 2rem; + text-align: center; + transition: transform 0.3s ease; +} + +.stat-card:hover { + transform: translateY(-5px); +} + +.stat-icon { + font-size: 2.5rem; + margin-bottom: 1rem; + color: #40B4FF; +} + +.stat-title { + font-size: 1.2rem; + margin-bottom: 0.5rem; + color: #F6F6F6; +} + +.stat-value { + font-size: 2rem; + font-weight: 700; + color: #A5F0FF; +} + +/* Fonctionnalités */ +.features-section { + background: linear-gradient(180deg, rgba(64, 180, 255, 0.2) 0%, rgba(31, 93, 137, 0) 100%); + padding: 4rem 2rem; + position: relative; + z-index: 2; +} + +.feature-card { + background: rgba(31, 93, 137, 0.1); + border-radius: 12px; + padding: 2rem; + transition: transform 0.3s ease; +} + +.feature-card:hover { + background: rgba(64, 180, 255, 0.15); +} + +.feature-icon { + font-size: 2rem; + margin-bottom: 1rem; + color: #A5F0FF; + background: rgba(31, 93, 137, 0.3); + padding: 1rem; + border-radius: 50%; +} + +.feature-title { + font-size: 1.2rem; + margin-bottom: 0.5rem; + color: #F6F6F6; +} + +.feature-description { + color: #F6F6F6; + line-height: 1.6; +} + +/* FAQ */ +.faq-section { + background: rgba(31, 93, 137, 0.05); + padding: 4rem 2rem; + position: relative; + z-index: 2; +} + +.faq-item { + background: rgba(31, 93, 137, 0.08); + border-radius: 8px; + margin-bottom: 1.5rem; + padding: 1.5rem; + transition: background 0.3s ease; +} + +.faq-item:hover { + background: rgba(31, 93, 137, 0.12); +} + +.faq-question { + font-size: 1.1rem; + margin-bottom: 0.5rem; + color: #F6F6F6; +} + +.faq-answer { + color: #F6F6F6; + line-height: 1.6; +} + +/* Pied de page */ +.footer { + background-color: #1F5D89; + color: white; + padding: 4rem 2rem 2rem; + position: relative; + z-index: 3; + border-top: 1px solid rgba(255, 255, 255, 0.1); + width: 100%; + box-sizing: border-box; +} + +.footer-content { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + max-width: 1200px; + margin: 0 auto; +} + +.footer-column { + flex: 1; + min-width: 250px; + margin-bottom: 2rem; + text-align: left; + padding: 0 1.5rem; +} + +.footer-column h4 { + font-size: 1.2rem; + margin-bottom: 1.5rem; + color: #A5F0FF; + position: relative; + padding-bottom: 0.75rem; +} + +.footer-column h4:after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + width: 40px; + height: 2px; + background-color: #A5F0FF; +} + +.footer-column ul { + list-style: none; + padding: 0; + margin: 0; +} + +.footer-column ul li { + margin-bottom: 0.8rem; +} + +.footer-column a { + color: rgba(246, 246, 246, 0.8); /* #F6F6F6 */ + text-decoration: none; + transition: all 0.2s; + display: inline-block; +} + +.footer-column a:hover { + color: #F6F6F6; + transform: translateX(3px); +} + +.footer-bottom { + border-top: 1px solid rgba(255, 255, 255, 0.1); + padding-top: 1.5rem; + margin-top: 2rem; + text-align: center; + font-size: 0.9rem; + color: rgba(255, 255, 255, 0.7); + max-width: 1200px; + margin-left: auto; + margin-right: auto; +} + +.popup-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.7); + display: flex; + justify-content: center; + align-items: center; + z-index: 100; + padding: 1rem; + backdrop-filter: blur(3px); + animation: fadeIn 0.2s ease-out; +} + +.popup-content { + background: linear-gradient(135deg, #F6F6F6 0%, #E8F7FF 100%); + color: #1F5D89; + border-radius: 12px; + padding: 2rem; + max-width: 500px; + width: 100%; + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3); + position: relative; + overflow: hidden; + animation: slideUp 0.3s ease-out; +} + +.popup-close { + position: absolute; + top: 15px; + right: 15px; + background: none; + border: none; + font-size: 1.5rem; + cursor: pointer; + color: #1F5D89; + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border-radius: 50%; + transition: background-color 0.2s; + padding: 0; +} + +.popup-close:hover { + background-color: rgba(64, 180, 255, 0.1); /* #40B4FF */ +} + +.popup-title { + font-family: var(--font-heading); + font-size: 1.8rem; + margin-top: 0; + margin-bottom: 1rem; + color: #1F5D89; + line-height: 1.2; +} + +.popup-description { + font-size: 1.1rem; + line-height: 1.5; + margin-bottom: 1.5rem; + color: #1F5D89; +} + +.popup-button { + display: inline-flex; + align-items: center; + background-color: #40B4FF; + color: white; + border: none; + padding: 0.8rem 1.5rem; + border-radius: 6px; + cursor: pointer; + text-decoration: none; + font-weight: 600; + letter-spacing: 0.3px; + box-shadow: 0 2px 8px rgba(64, 180, 255, 0.3); + transition: all 0.2s ease; +} + +.popup-button:hover { + background-color: #2ba3f7; + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(64, 180, 255, 0.4); +} + +.popup-button:focus-visible { + outline: 3px solid #69B7E2; + outline-offset: 2px; +} + +.popup-button-icon { + margin-right: 0.5rem; + font-size: 1.1em; +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes slideUp { + from { + transform: translateY(30px); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 1; + } +} + +.bubbles { + position: absolute; + width: 100%; + height: 100%; + overflow: hidden; + top: 0; + left: 0; + z-index: 1; + pointer-events: none; +} + +.bubble { + position: absolute; + bottom: -20px; + width: 40px; + height: 40px; + background: rgba(165, 240, 255, 0.2); /* #A5F0FF */ + border-radius: 50%; + opacity: 0.8; + animation: rise 10s infinite ease-in; +} + +.bubble:nth-child(1) { + width: 25px; + height: 25px; + left: 10%; + animation-duration: 8s; +} + +.bubble:nth-child(2) { + width: 30px; + height: 30px; + left: 20%; + animation-duration: 9s; + animation-delay: 1s; +} + +.bubble:nth-child(3) { + width: 35px; + height: 35px; + left: 35%; + animation-duration: 10s; + animation-delay: 2s; +} + +.bubble:nth-child(4) { + width: 28px; + height: 28px; + left: 50%; + animation-duration: 7s; + animation-delay: 0s; +} + +.bubble:nth-child(5) { + width: 22px; + height: 22px; + left: 65%; + animation-duration: 12s; + animation-delay: 3s; +} + +.bubble:nth-child(6) { + width: 32px; + height: 32px; + left: 80%; + animation-duration: 9s; + animation-delay: 1.5s; +} + +.bubble:nth-child(7) { + width: 20px; + height: 20px; + left: 90%; + animation-duration: 8s; + animation-delay: 2.5s; +} + +@keyframes rise { + 0% { + bottom: -100px; + transform: translateX(0); + opacity: 0.8; + } + 50% { + transform: translateX(40px); + opacity: 0.4; + } + 100% { + bottom: 1080px; + transform: translateX(-40px); + opacity: 0; + } +} + +.navbar-mobile-toggle { + display: none; + background: transparent; + border: none; + cursor: pointer; + padding: 5px; + z-index: 20; + width: 40px; + height: 40px; + position: relative; +} + +.navbar-mobile-toggle span { + display: block; + width: 25px; + height: 3px; + background-color: white; + margin: 5px auto; + transition: all 0.3s ease; +} + +.navbar-right { + display: flex; + align-items: center; + gap: 12px; +} + +@media (max-width: 768px) { + .navbar { + padding: 0.6rem 1rem; + } + + .navbar-mobile-toggle { + display: block; + } + + .navbar-right { + position: fixed; + top: 0; + right: -100%; + flex-direction: column; + background-color: rgba(12, 59, 93, 0.98); + height: 100vh; + width: 70%; + max-width: 300px; + padding-top: 70px; + transition: all 0.3s ease; + z-index: 15; + gap: 20px; + backdrop-filter: blur(10px); + box-shadow: -5px 0 15px rgba(0, 0, 0, 0.2); + visibility: hidden; /* Add this */ + opacity: 0; /* Add this */ + } + + .navbar-right.mobile-active { + right: 0; + visibility: visible; /* Add this */ + opacity: 1; /* Add this */ + } + + .navbar-mobile-toggle.active span:nth-child(1) { + transform: translateY(8px) rotate(45deg); + } + + .navbar-mobile-toggle.active span:nth-child(2) { + opacity: 0; + transform: scale(0); + } + + .navbar-mobile-toggle.active span:nth-child(3) { + transform: translateY(-8px) rotate(-45deg); + } + + /* Iceberg consistency fixes */ + .iceberg { + width: 220px; + height: 180px; + margin: 0 auto; + } + + .iceberg img { + width: 100%; + max-width: 220px; + max-height: 180px; + object-fit: contain; + } + + .service-name { + font-size: 1.2rem; + padding: 10px 16px; + width: auto; + min-width: 160px; + max-width: 90%; + } +} + +/* Desktop consistency for icebergs */ +.iceberg { + position: relative; + width: 250px; + height: 200px; + display: flex; + align-items: center; + justify-content: center; +} + +.iceberg img { + width: 100%; + height: auto; + max-width: 250px; + max-height: 200px; + object-fit: contain; +} diff --git a/banquise-website/src/App.tsx b/banquise-website/src/App.tsx new file mode 100644 index 0000000..a67b62c --- /dev/null +++ b/banquise-website/src/App.tsx @@ -0,0 +1,525 @@ +import { FiUser, FiDatabase, FiShield, FiChevronDown } from 'react-icons/fi' +import { FaDiscord, FaArrowRight, FaEnvelope, FaGithub, FaNetworkWired, FaServer, FaLaptopCode, FaCloudUploadAlt, FaExternalLinkAlt } from 'react-icons/fa' +import { FiX, FiExternalLink } from 'react-icons/fi' +import './App.css' +import icebergImage from './assets/iceberg.png' +import logoImage from './assets/banquise.png' +import { useEffect, useState, useMemo, useCallback, useRef } from 'react' + +import aboutImage from './assets/banquise.png' + +function App() { + const [selectedService, setSelectedService] = useState(null); + const [mobileMenuOpen, setMobileMenuOpen] = useState(false); + const mobileMenuRef = useRef(null); + + const services = useMemo(() => [ + { + name: "Notre Wiki", + url: "https://wiki.la-banquise.fr/en/home", + description: "Notre Wiki est une base de connaissances collaborative où vous trouverez toute la documentation relative à nos projets et services. Apprenez, contribuez et partagez vos connaissances avec la communauté La Banquise." + }, + { + name: "Gitea", + url: "https://git.la-banquise.fr/", + description: "Gitea est notre plateforme de gestion de code source, similaire à GitHub mais hébergée par nos soins. Créez des dépôts, collaborez sur des projets et participez au développement d'applications open-source dans un environnement sécurisé." + }, + { + name: "Panel de jeux", + url: "https://panel.la-banquise.fr/auth/login", + description: "Interface de connection à notre panel Pterodactyl, qui vous permet de gérer vos serveurs de jeux. Créez, gérez et configurez vos serveurs de jeux préférés en toute simplicité." + }, + ], []); + + const [icebergs, setIcebergs] = useState>([]) + + const [reducedMotion, setReducedMotion] = useState(false); + + useEffect(() => { + const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; + setReducedMotion(prefersReducedMotion); + + const startTime = performance.now(); + let count = 0; + while (performance.now() - startTime < 5) { + count++; + } + + if (count < 1000) { + setReducedMotion(true); + } + }, []); + + const positionIcebergs = useCallback(() => { + const newIcebergs = []; + + const positions = [ + { x: 25, y: 35, scale: 0.95, rotation: 0 }, + { x: 50, y: 25, scale: 1.1, rotation: 0 }, + { x: 75, y: 35, scale: 0.95, rotation: 0 }, + ]; + + const floatClasses = ['float-1', 'float-2', 'float-3', 'float-4', 'float-5']; + + for (let i = 0; i < services.length; i++) { + const position = positions[i % positions.length]; + + newIcebergs.push({ + id: i, + x: position.x, + y: position.y, + scale: position.scale, + rotation: position.rotation, + service: services[i], + floatClass: reducedMotion ? '' : floatClasses[i % floatClasses.length] + }); + } + + return newIcebergs; + }, [services, reducedMotion]); + + useEffect(() => { + setIcebergs(positionIcebergs()); + }, [positionIcebergs]); + + const renderBubbles = useMemo(() => { + if (reducedMotion) return null; + + return ( +
+
+
+
+
+
+
+
+
+ ); + }, [reducedMotion]); + + const handleIcebergClick = (event: React.MouseEvent, serviceId: number) => { + event.preventDefault(); + setSelectedService(serviceId); + }; + + const handleClosePopup = () => { + setSelectedService(null); + }; + + useEffect(() => { + const handleOutsideClick = (event: MouseEvent) => { + if (mobileMenuRef.current && !mobileMenuRef.current.contains(event.target as Node)) { + setMobileMenuOpen(false); + } + }; + + if (mobileMenuOpen) { + document.addEventListener('mousedown', handleOutsideClick); + } + + return () => { + document.removeEventListener('mousedown', handleOutsideClick); + }; + }, [mobileMenuOpen]); + + useEffect(() => { + if (mobileMenuOpen) { + document.body.style.overflow = 'hidden'; + } else { + document.body.style.overflow = 'auto'; + } + + return () => { + document.body.style.overflow = 'auto'; + }; + }, [mobileMenuOpen]); + + const [activeAccordion, setActiveAccordion] = useState(null); + + // FAQ items for the about section + const faqItems = useMemo(() => [ + { + question: "Qui sommes-nous ?", + answer: ( + <> +

La Banquise est une initiative d'étudiants de l'EPITA Lyon dont l'objectif est de rendre plus accessible l'hébergement de services informatiques. Fondée en 2023, notre association à but non lucratif vise à permettre à ceux qui le souhaitent de se former sur des technologies d'hébergement et de réseau.

+

Notre équipe est composée d'étudiants passionnés par l'informatique, le réseau et le partage de connaissances. Nous mettons notre expertise au service des étudiants et des associations de l'EPITA.

+ + ) + }, + { + question: "Comment candidater pour rejoindre La Banquise ?", + answer: ( + <> +

Pour rejoindre notre équipe, rien de plus simple :

+
    +
  • Rejoignez notre serveur Discord
  • +
  • Présentez-vous et expliquez votre motivation dans un ticket
  • +
  • Précisez vos compétences ou les domaines qui vous intéressent
  • +
  • Un membre de notre équipe vous contactera pour un échange
  • +
+

Nous recherchons des personnes motivées, peu importe votre niveau technique actuel !

+ + Rejoindre le Discord + + + ) + }, + { + question: "Quels sont nos objectifs ?", + answer: ( + <> +

Nos principaux objectifs sont :

+
    +
  • Former les étudiants aux technologies d'hébergement et de réseau
  • +
  • Fournir des services informatiques de qualité aux étudiants et associations de l'EPITA
  • +
  • Promouvoir le partage de connaissances et l'entraide
  • +
  • Créer un environnement d'apprentissage pratique par l'expérience
  • +
  • Maintenir une infrastructure robuste et sécurisée
  • +
+ + ) + }, + { + question: "Comment utiliser nos services ?", + answer: ( + <> +

Pour accéder à nos services :

+
    +
  1. Créez un compte sur notre plateforme d'authentification
  2. +
  3. Connectez-vous au service souhaité avec vos identifiants
  4. +
  5. Consultez notre Wiki pour obtenir de l'aide sur l'utilisation de chaque service
  6. +
+

Si vous rencontrez des difficultés, n'hésitez pas à demander de l'aide sur notre Discord.

+ + Créer un compte + + + ) + }, + { + question: "Comment contribuer au projet ?", + answer: ( + <> +

Il existe plusieurs façons de contribuer au projet La Banquise :

+
    +
  • Rejoindre l'équipe en tant que membre actif
  • +
  • Contribuer au code source de nos projets via Gitea
  • +
  • Rédiger ou améliorer la documentation sur notre Wiki
  • +
  • Proposer de nouvelles idées de services ou d'améliorations
  • +
  • Aider d'autres utilisateurs sur notre Discord
  • +
+

Toutes les contributions sont les bienvenues, même les plus modestes !

+ + ) + }, + ], []); + + const toggleAccordion = (index: number) => { + setActiveAccordion(activeAccordion === index ? null : index); + }; + + return ( +
+ Passer au contenu principal + +
+ +
+ +
+
+ {renderBubbles} + +
+
+
+
+
+
+
+ +
+ Logo La Banquise +
+

Association La Banquise

+

+ Association d'hébergement et lab réseau pour tous les étudiants et associations de l'EPITA +

+ +
+ +
+
+

Notre infrastructure

+

+ Des services robustes et sécurisés pour répondre à vos besoins +

+ +
+
+
+ +
+

Serveurs performants

+

+ Infrastructure optimisée pour assurer des performances élevées et une disponibilité maximale de vos applications +

+
+ +
+
+ +
+

Stockage sécurisé

+

+ Solutions de stockage distribuées avec redondance pour garantir l'intégrité et la durabilité de vos données +

+
+ +
+
+ +
+

Réseau optimisé

+

+ Architecture réseau à haute disponibilité avec une faible latence pour vos applications critiques +

+
+ +
+
+ +
+

Sécurité renforcée

+

+ Protection contre les menaces avec systèmes de sécurité modernes et mises à jour régulières +

+
+
+
+ +
+
+

Nos services

+

+ Explorez notre écosystème de services conçus pour répondre à vos besoins. +

+ + +
+ +
+
+

À propos de nous

+

+ Découvrez notre mission et posez-nous vos questions +

+ +
+
+ Logo La Banquise +
+ +

+ La Banquise est une association étudiante dédiée à l'hébergement de services et à la formation sur les technologies réseau, au service de la communauté EPITA. +

+ +
+ {faqItems.map((item, index) => ( +
+
toggleAccordion(index)} + role="button" + aria-expanded={activeAccordion === index} + aria-controls={`accordion-content-${index}`} + tabIndex={0} + onKeyPress={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + toggleAccordion(index); + } + }} + > + {item.question} +
+
+ {item.answer} +
+
+ ))} +
+
+
+ + {selectedService !== null && ( +
+
e.stopPropagation()}> + + +

{services[selectedService].description}

+ + + Accéder au service + +
+
+ )} + +
+
const banquise = new ServerInfra();
+
banquise.deploy('wiki');
+
banquise.deploy('gitea');
+
banquise.optimize();
+
banquise.monitor();
+
+ + +
+
+ + +
+ ); +} + +export default App; diff --git a/banquise-website/src/assets/banquise.png b/banquise-website/src/assets/banquise.png new file mode 100644 index 0000000..39c3011 Binary files /dev/null and b/banquise-website/src/assets/banquise.png differ diff --git a/banquise-website/src/assets/iceberg.png b/banquise-website/src/assets/iceberg.png new file mode 100644 index 0000000..3b97360 Binary files /dev/null and b/banquise-website/src/assets/iceberg.png differ diff --git a/banquise-website/src/index.css b/banquise-website/src/index.css new file mode 100644 index 0000000..29d7987 --- /dev/null +++ b/banquise-website/src/index.css @@ -0,0 +1,103 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* Système typographique moderne */ +:root { + --font-heading: 'Space Grotesk', sans-serif; + --font-body: 'Inter', system-ui, sans-serif; + + font-family: var(--font-body); + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* Hiérarchie typographique */ +h1, h2, h3, h4, h5, h6, .site-name, .welcome-title { + font-family: var(--font-heading); + font-weight: 600; + line-height: 1.2; + letter-spacing: -0.025em; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; + font-weight: 700; +} + +h2 { + font-size: 2.4em; + font-weight: 600; +} + +h3 { + font-size: 1.8em; + font-weight: 600; +} + +p, span, div, a, button, input { + font-family: var(--font-body); +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} + +a:hover { + color: #535bf2; +} + +body { + margin: 0; + padding: 0; + display: flex; + min-width: 320px; + min-height: 100vh; + width: 100%; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: var(--font-body); + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} + +button:hover { + border-color: #646cff; +} + +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/banquise-website/src/main.tsx b/banquise-website/src/main.tsx new file mode 100644 index 0000000..bef5202 --- /dev/null +++ b/banquise-website/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import App from './App.tsx' + +createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/banquise-website/src/vite-env.d.ts b/banquise-website/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/banquise-website/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/banquise-website/tailwind.config.js b/banquise-website/tailwind.config.js new file mode 100644 index 0000000..0bdb22b --- /dev/null +++ b/banquise-website/tailwind.config.js @@ -0,0 +1,21 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: [ + "./index.html", + "./src/**/*.{js,ts,jsx,tsx}", + ], + theme: { + extend: { + colors: { + // Vous pouvez personnaliser vos couleurs ici + }, + fontFamily: { + // Personnalisation des polices + } + }, + }, + plugins: [ + require('@tailwindcss/forms'), + require('@tailwindcss/typography'), + ], +} diff --git a/banquise-website/tsconfig.app.json b/banquise-website/tsconfig.app.json new file mode 100644 index 0000000..c9ccbd4 --- /dev/null +++ b/banquise-website/tsconfig.app.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src"] +} diff --git a/banquise-website/tsconfig.json b/banquise-website/tsconfig.json new file mode 100644 index 0000000..1ffef60 --- /dev/null +++ b/banquise-website/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/banquise-website/tsconfig.node.json b/banquise-website/tsconfig.node.json new file mode 100644 index 0000000..9728af2 --- /dev/null +++ b/banquise-website/tsconfig.node.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/banquise-website/vite.config.ts b/banquise-website/vite.config.ts new file mode 100644 index 0000000..350511a --- /dev/null +++ b/banquise-website/vite.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import viteCompression from 'vite-plugin-compression' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [ + react(), + viteCompression({ + verbose: false, + algorithm: 'gzip', + ext: '.gz', + }), + ], + build: { + minify: 'esbuild', + cssMinify: true, + rollupOptions: { + output: { + manualChunks: { + react: ['react', 'react-dom'], + router: ['react-router-dom'], + }, + }, + }, + }, +}) diff --git a/la-banquise/assets/iceberg.svg b/la-banquise/assets/iceberg.svg deleted file mode 100644 index f8a610e..0000000 --- a/la-banquise/assets/iceberg.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/la-banquise/index.html b/la-banquise/index.html deleted file mode 100644 index 9ce3aed..0000000 --- a/la-banquise/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - La Banquise - - - - -

La Banquise

- - - - - - - - - \ No newline at end of file diff --git a/la-banquise/script.js b/la-banquise/script.js deleted file mode 100644 index 5bb84d8..0000000 --- a/la-banquise/script.js +++ /dev/null @@ -1,22 +0,0 @@ -const tile = document.querySelectorAll(".grid-container > *")[0]; -const parent = tile.parentNode; -tile.remove(); - -const tiles = [ - { name: "Notre wiki", href: "https://wiki.la-banquise.fr" }, - { name: "Notre git", href: "https://git.la-banquise.fr" }, - { name: "Panel jeux", href: "https://panel.la-banquise.fr" }, - { name: "Discord", href: "https://discord.gg/QQWwzX5ptY" }, - { name: "Login", href: "https://auth.la-banquise.fr" }, - { name: "Change password", href: "https://ssp.la-banquise.fr" }, -] - -tiles.forEach((info) => { - const newTile = tile.cloneNode(true); - newTile.querySelectorAll(".item-name").forEach((el) => { - el.innerText = info.name; - }); - newTile.href = info.href; - parent.appendChild(newTile); -}); - diff --git a/la-banquise/style.css b/la-banquise/style.css deleted file mode 100644 index 2feae16..0000000 --- a/la-banquise/style.css +++ /dev/null @@ -1,136 +0,0 @@ -@import url('https://fonts.googleapis.com/css2?family=League+Spartan:wght@100..900&family=Roboto:ital,wght@0,100..900;1,100..900&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap'); - -* { - margin: 0; - padding: 0; - box-sizing: border-box; - font-family: Roboto, sans-serif; -} - -body { - margin: 0; - padding: 30px; - min-height: 100vh; - background: linear-gradient(45deg, #001e6c, #5dadc2, #001e6c); - background-size: 400% 400%; - animation: gradient 100s ease infinite; -} - -@keyframes gradient { - 0% { - background-position: 0% 50%; - } - - 50% { - background-position: 100% 50%; - } - - 100% { - background-position: 0% 50%; - } -} - -h1.title { - display: flex; - justify-content: center; -} - -.hidden { - visibility: hidden; -} - -/* Style de la vague en bas de page */ -.wave { - position: absolute; - bottom: 0; - left: 0; - width: 100%; - overflow: hidden; - line-height: 0; -} - -.wave svg { - position: relative; - display: block; - width: calc(100% + 1.3px); - height: 150px; -} - -.wave .shape-fill { - fill: rgba(255, 255, 255, 0.2); -} - -.title { - font-size: 2.5rem; - margin-bottom: 2rem; -} - -/* En-tête du site */ -header { - text-align: center; - color: #fff; - padding: 1rem; -} - -/* Container en flexbox pour agencer les éléments dans une "grid" */ -.grid-container { - flex: 1; - display: flex; - flex-wrap: wrap; - justify-content: center; - align-items: stretch; - gap: 20px; - padding: 1rem; -} - -/* Chaque élément de la grid */ -.grid-item { - background: rgba(255, 255, 255, 0); - padding: 2px; - border-radius: 8px; - color: #fff; - text-align: center; - /* Permet de s'étendre sur au moins 300px et de grandir si besoin */ - flex: 0 1 calc(10% - 40px); - /* 3 items par ligne avec 20px de gap */ - max-width: calc(10% - 40px); - box-shadow: 0 4px 6px rgba(0, 0, 0, 0); - transition: transform 0.3s; -} - -.grid-item:hover { - transform: scale(1.05); - background: rgba(255, 255, 255, 0.1); - box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2); -} - -.grid-item img, -.grid-item object { - max-width: 100%; - height: auto; - display: block; - margin: 0 auto 10px; - /* Pour donner une vue isométrique */ - transform: rotateX(0deg) rotateZ(0deg); - transform-origin: center; -} - -.grid-item p { - font-size: 1.5rem; - margin-top: 0rem; - font-weight: bold; -} - -@media (max-width: 900px) { - .grid-item { - flex: 0 1 calc(25% - 40px); - max-width: calc(25% - 40px); - } -} - -@media (max-width: 600px) { - .grid-item { - flex: 0 1 calc(50% - 40px); - max-width: calc(50% - 40px); - } -} \ No newline at end of file