diff --git a/.gitignore b/.gitignore index 91dccb0..4c7caed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ # Ignore all Markdown files # *.md +.**claude** diff --git a/README.md b/README.md index 626cd3d..4fba3ad 100644 --- a/README.md +++ b/README.md @@ -1,291 +1,222 @@ # OmégaKube — Site Web -Site vitrine officiel d'OmégaKube — plateforme de création d'expériences Role Play immersives avec bots Discord personnalisés et maps Fortnite. - -## 📋 Vue d'ensemble du projet - -Le projet **OmégaKube Website** est un site web moderne et responsive présentant les services de l'entreprise. Il s'agit d'une application web statique basée sur HTML, CSS et JavaScript vanilla, avec un système de composants réutilisables. - -### Services présentés -- **Bots Discord personnalisés** — Création de bots RP avancés -- **Maps Fortnite immersives** — Design d'expériences gaming uniques -- **Expériences RP surMesure** — Solutions complètes pour communautés gaming +Site vitrine officiel d'OmégaKube — plateforme de création d'expériences Role Play immersives : bots Discord personnalisés, maps Fortnite UEFN, graphisme et consulting. --- -## 🏗️ Architecture du projet +## 🏗️ Architecture ``` website/ -├── index.html # Page d'accueil principale -├── assets/ # Ressources statiques +├── index.html # Page d'accueil +├── .htaccess # Config Apache (404, redirections) +├── pages/ +│ ├── services.html # Nos services +│ ├── realisations.html # Portfolio complet +│ ├── faq.html # Questions fréquentes +│ ├── mentions-legales.html +│ ├── cgv.html +│ └── 404.php # Page 404 (CSS/JS inline, fonctionne depuis n'importe quel chemin) +├── components/ +│ ├── header.html # Navbar (data-include) +│ ├── footer.html # Footer + réseaux sociaux (data-include) +│ ├── background.html # Fond géométrique animé +│ ├── contact.html # Formulaire de contact réutilisable +│ └── favicons.html +├── assets/ │ ├── css/ -│ │ └── main.css # Feuille de styles globale (thème, animations, layout) +│ │ ├── main.css # Styles globaux (thème dark/light, composants) +│ │ ├── 404.css # Styles page 404 +│ │ └── legal.css # Styles pages légales │ ├── js/ -│ │ ├── main.js # Script principal (chargement, thème, composants) -│ │ ├── home.js # Logique spécifique à la page d'accueil -│ │ └── pages/ # Scripts pour pages spécifiques -│ ├── images/ # Images et assets visuels -│ ├── fonts/ # Polices personnalisées (OmegaLarge, OmegaSmall) -│ ├── data/ # Données JSON (services, projets, etc.) -│ └── php/ # Scripts PHP backend (formulaires, envois email) -├── components/ # Composants réutilisables (système d'include) -│ ├── header.html # Navigation + logo -│ ├── footer.html # Pied de page -│ ├── background.html # Animation de fond géométrique -│ ├── favicons.html # Favicon et meta tags -│ ├── index/ # Composants spécifiques à l'accueil -│ │ └── ... (hero, about, services, contact) -│ └── services/ # Composants de la page services -├── pages/ # Pages du site -│ ├── services.html # Détail des services -│ ├── realisations.html # Portfolio/réalisations -│ ├── cgv.html # Conditions Générales de Vente -│ ├── mentions-legales.html # Mentions légales -│ ├── 404.php # Page erreur 404 -│ └── test*.html # Pages de test -├── .htaccess # Configuration serveur Apache -├── .git/ # Versionning Git -└── README.md # Ce fichier +│ │ ├── main.js # Script partagé : thème, includes, social links, feather +│ │ ├── home.js # Accueil : portfolio, team carousel, partners, easter egg +│ │ └── pages/ +│ │ ├── realisations.js # Portfolio + modal projet + galerie +│ │ ├── services.js # Onglets services +│ │ ├── services-process.js # Animation timeline processus +│ │ ├── legal.js # Pages légales +│ │ └── 404.js # Easter egg page 404 (Game of Life) +│ ├── data/ +│ │ ├── projects.json # ⭐ Projets (images, stats, tech, social) +│ │ ├── team.json # ⭐ Membres de l'équipe +│ │ ├── partners.json # ⭐ Partenaires +│ │ ├── services.json # Détail des services +│ │ └── faq.json # Questions / réponses FAQ +│ ├── images/ +│ │ ├── projects/ # Images des projets +│ │ │ ├── kuby/ # imgk-1.png, ... +│ │ │ ├── victorias-vice-1/ # imgvv1-1.jpg, ... +│ │ │ ├── vicy/ +│ │ │ ├── site-omega/ +│ │ │ └── branding-omega-kube/ +│ │ ├── team/ # Photos membres : {id_discord}.png +│ │ ├── partners/ # Logos partenaires : {name}.png +│ │ └── favicon/ +│ ├── fonts/ # OmegaLarge, OmegaSmall, Montserrat +│ └── php/ +│ └── send_mail.php # Formulaire de contact (JSON POST) ``` -### Système de composants - -Le projet utilise un **système de composants custom** basé sur `data-include`: - -```html - -
- -``` - -**Avantages:** -- Pas de dépendance Build (HTML pur) -- Réutilisabilité des composants -- Maintenabilité accrue - --- -## 🎨 Technologie & Stack +## ⚙️ Configuration rapide + +### 1. Réseaux sociaux — un seul endroit + +Dans `assets/js/main.js`, modifier l'objet `window.OK_SOCIAL` : + +```js +window.OK_SOCIAL = { + discord: 'https://discord.gg/FwvNkvu5dy', + fortnite: 'https://www.fortnite.com/@omega_kube_team' + twitter: 'https://x.com/Omegakube', + instagram: 'https://www.instagram.com/omegakube/', + youtube: 'https://www.youtube.com/@OmegaKube', + tiktok: 'https://www.tiktok.com/@omegakube', + facebook: '', + bluesky: '', + email: 'contact@omegakube.fr' +}; +``` + +Tous les liens du site (footer, contact, modals) se mettent à jour automatiquement. + +--- + +### 2. Ajouter / modifier un projet + +Éditer `assets/data/projects.json` : + +```json +{ + "id": 6, + "category": "bot", // "bot" | "map" | "graphisme" + "title": "Nom du projet", + "desc": "Description complète...", + "gradient": "linear-gradient(135deg, #5E2040, #8b3a62)", + "year": "2025", + "duration": "2 mois", + "images": "assets/images/projects/nom-du-projet/", + "files": [ + "trailer.mp4", // vidéo locale + "https://youtube.com/watch?v=VIDEO_ID", // URL YouTube complète + "yt:VIDEO_ID", // shortcode YouTube + "img-1.png", + "img-2.jpg" + ], + "features": ["Feature 1", "Feature 2"], + "tech": [ + { "name": "Python", "icon": "code" } + ], + "stats": [ + { "icon": "users", "value": "500+", "label": "Utilisateurs" } + ], + "social": { + "discord": "https://discord.gg/...", + "twitter": "", + "instagram": "" + } +} +``` + +Déposer les images dans `assets/images/projects/nom-du-projet/`. + +--- + +### 3. Ajouter un membre de l'équipe + +Éditer `assets/data/team.json`. Photo optionnelle : `assets/images/team/{id_discord}.png`. + +```json +{ + "id": "123456789", // ID Discord = nom du fichier photo + "name": "Pseudo", + "role": "Rôle", + "avatar": "P", // Lettre fallback si pas de photo + "bio": "...", + "stats": [...], + "skills": ["Skill 1"], + "social": { + "discord": "", + "twitter": "", + "github": "" + } +} +``` + +--- + +### 4. Ajouter un partenaire + +Éditer `assets/data/partners.json`. Logo optionnel : `assets/images/partners/{name}.png`. + +```json +{ + "name": "nom-slug", // = nom du fichier logo + "displayName": "Nom Affiché", + "description": "Courte description", + "longDesc": "Description complète pour la modal", + "gradient": "linear-gradient(...)", + "since": "2025", + "services": ["Service rendu"], + "stats": [ + { "icon": "users", "value": "100+", "label": "Membres" } + ], + "social": { + "discord": "", + "website": "", + "twitter": "" + } +} +``` + +--- + +### 5. FAQ + +Éditer `assets/data/faq.json` — ajouter des catégories ou questions : + +```json +{ + "id": "ma-categorie", + "icon": "help-circle", // icône Feather Icons + "title": "Ma catégorie", + "questions": [ + { "q": "La question ?", "a": "La réponse." } + ] +} +``` + +--- + +## 🌐 Déploiement + +- **Serveur** : PHP requis uniquement pour `404.php` et `send_mail.php` +- **Contact** : configurer l'adresse email dans `assets/php/send_mail.php` (`$to`) +- **Apache** : le `.htaccess` gère la 404 et désactive le listing de dossiers +- **Thème** : dark par défaut, toggle persisté en `localStorage` + +--- + +## 🥚 Easter Eggs + +- **PC** : taper le Konami Code `↑ ↑ ↓ ↓ ← → ← → B A` +- **Mobile** : 10 taps rapides sur le logo navbar ou le logo footer +- **Page 404** : 10 taps sur le "404" → Game of Life de Conway + +--- + +## 🛠️ Stack technique | Technologie | Usage | |---|---| -| **HTML5** | Structure sémantique | -| **CSS3** | Styling, animations, variables CSS | -| **JavaScript (Vanilla)** | Interactivité, système de composants | -| **Feather Icons** | Bibliothèque d'icônes légères | -| **PHP** | Backend pour formulaires/emails | -| **Apache HTTP Server** | Serveur web | -| **Git** | Contrôle de version | - -### Système de thème - -Design **dark-first** avec toggle light/dark: -- CSS Custom Properties pour les couleurs -- Thème stoké en `data-theme` sur `` -- Variables principales: - - `--bg-deep`, `--bg-secondary`, `--bg-tertiary` - - `--accent-primary`, `--accent-secondary` - - Colors du thème changent automatiquement - -### Polices personnalisées - -- **OmegaLarge** — Titres et éléments grands -- **OmegaSmall** — Textes courants -- **Montserrat-Bold et Montserrat-BoldItalic/** — Polices par defaut pour le moment -- Localisées dans `assets/fonts/` - ---- - -## 🚀 Setup & Installation - -### Prérequis - -- **Serveur web** (Apache, Nginx, PHP 7.4+. Ou tout simplement Wamp pour Windows ou Lamp pour Linux) -- **Git** pour le versioning -- **Navigateur moderne** (Chrome, Firefox, Safari, Edge) -- Aucune dépendance externe à installer - -### Installation locale - -#### 1. **Cloner le projet** -```bash -cd e:\votre _repertoire_de_dev -git clone https://gitlab.com/Omega_Kube/website.git -cd website -``` - -#### 2. **Configurer le serveur local** - -**Option A - Avec PHP intégré (développement rapide):** -```bash -php -S localhost:8000 -# Accédez à http://localhost:8000 -``` - -**Option B - Avec Apache:** -1. Placer le dossier dans votre `htdocs` ou `www` -2. Configurer le VirtualHost si nécessaire -3. S'assurer que le fichier `.htaccess` est présent et actif - -**Option C - Avec un serveur Live Server (VS Code):** -- Installer l'extension "Live Server" -- Clic-droit → "Open with Live Server" - -**Option D - Démarrer le serveur Wamp ou Lamp:** -- Placer le dossier dans votre `www` -- Crée un alias vers votre dossier de programation ou le déplacer dans votre `www` - -#### 3. **Tester le projet** -- Ouvrir http://localhost:8000 (ou votre serveur) -- Vérifier que tous les composants se chargent -- Tester le toggle dark/light -- Vérifier les liens de navigation - ---- - -## 📝 Guide de développement - -### Structure des fichiers CSS - -**`assets/css/main.css`** — Point d'entrée unique: - -```css -/* Variables & Thèmes */ -:root { --bg-deep: #1a0f1f; ... } - -/* Layout & Composants */ -.hero { } -.about { } -.btn { } -/* ... */ - -/* Animations & Responsive */ -@media (max-width: 768px) { } -``` - -### Ajouter une nouvelle page - -1. **Créer le fichier HTML** dans `pages/`: -```bash -pages/ma-page.html -``` - -2. **Inclure les composants** (header, footer): -```html -
-
- -
-
-``` - -3. **Ajouter le lien** dans le header: -```html - -
  • Ma Page
  • -``` - -4. **Si JS nécessaire**, créer `assets/js/pages/ma-page.js` - -### Ajouter un composant - -1. **Créer le fichier** dans `components/`: -```bash -components/mon-composant.html -``` - -2. **L'inclure** n'importe où: -```html -
    -``` - -### Modifier les styles globaux - -- **Couleurs** → Modifier les variables CSS dans `assets/css/main.css` (section `:root`) -- **Polices** → Uploader dans `assets/fonts/`, puis ajouter `@font-face` -- **Animations** → Ajouter dans `assets/css/main.css` (respect du système de thème) - -### Intégrer le backend PHP - -**Exemple: Formulaire de contact** - -1. **Créer le formulaire** dans un composant: -```html - -
    - - - -
    -``` - -2. **Créer le script PHP** (`assets/php/send-message.php`): -```php - -``` - ---- - -## 🔧 Maintenance & Dépannage - -### Le site ne charge pas les composants - -**Vérifications:** -- [ ] Le fichier `assets/js/main.js` contient le code d'inclusion -- [ ] Les chemins dans `data-include` sont corrects (relatifs à la racine) -- [ ] Les fichiers HTML existent et n'ont pas d'erreur de syntaxe - -### Les styles ne s'appliquent pas - -- [ ] Vérifier que `assets/css/main.css` est lié dans le `` -- [ ] Rafraîchir le cache du navigateur (Ctrl+Shift+R ou Ctrl+F5) -- [ ] Vérifier les media-queries pour le responsive - -### Les icônes Feather ne s'affichent pas - -- [ ] S'assurer que la CDN Feather Icons est incluse -- [ ] Vérifier les noms d'icônes sur [feathericons.com](https://feathericons.com) - -### Le toggle dark/light ne fonctionne pas - -- [ ] Vérifier que `home.js` est chargé -- [ ] S'assurer que les variables CSS sont correctement définies -- [ ] Vérifier la balise `` ou `` - ---- - -## 📋 Checklist pour nouveaux développeurs - -Avant de commencer: - -- [ ] Cloner le projet en local -- [ ] Lancer un serveur local (PHP , Live Server ou Wamp/Lamp) -- [ ] Vérifier que le site s'affiche correctement -- [ ] Consulter la structure des fichiers -- [ ] Comprendre le système de composants `data-include` -- [ ] Tester le dark/light mode -- [ ] Vérifier les liens de navigation - ---- - -## 🔗 Ressources utiles - -- **Feather Icons**: https://feathericons.com -- **CSS Variables**: https://developer.mozilla.org/en-US/docs/Web/CSS/--* -- **Responsive Design**: https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design -- **Git Guide**: https://git-scm.com/doc +| HTML5 / CSS3 | Structure et styles, thème dark/light | +| JavaScript ES6+ | Logique, composants, données JSON | +| PHP | Formulaire de contact, page 404 | +| Feather Icons | Icônes (CDN) | +| Montserrat | Police secondaire | +| OmegaLarge / OmegaSmall | Polices custom OmégaKube | --- @@ -305,6 +236,6 @@ Pour contribuer au projet: Consulter [pages/mentions-legales.html](pages/mentions-legales.html) et [pages/cgv.html](pages/cgv.html). --- -**Version du site web**: 1.5.1.4 -**Dernière mise à jour**: Mars 2026 +**Version du site web**: 1.5.2.16 +**Dernière mise à jour**: Avril 2026 **Mainteneur**: KIRITO_KMA / L'équipe OmégaKube diff --git a/assets/css/main.css b/assets/css/main.css index f523b60..6223a08 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -1130,7 +1130,7 @@ section { position: absolute; inset: 0; background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary)); - opacity: 0.4; + /* opacity retiré — géré par portfolio-content gradient */ } .portfolio-content { @@ -1140,7 +1140,9 @@ section { flex-direction: column; justify-content: flex-end; padding: 2rem; - background: linear-gradient(180deg, transparent 0%, var(--bg-deep) 100%); + /* Gradient sombre uniquement en bas pour lisibilité du texte sans masquer l'image */ + background: linear-gradient(180deg, transparent 55%, rgba(10,10,15,0.92) 100%); + z-index: 2; } .portfolio-tag { @@ -1169,9 +1171,7 @@ section { } .portfolio-item p { - color: var(--text-muted); - font-size: 0.9rem; - margin-top: 0.5rem; + display: none; /* Description masquée dans les cartes — visible uniquement dans la modal */ } /* Portfolio Detail */ @@ -2118,13 +2118,12 @@ footer { overflow: hidden; } +/* Pas d'overlay sur le bento — juste gradient bas pour lisibilité texte */ .bento-project .bento-image::before { - content: ''; - position: absolute; - inset: 0; - background: linear-gradient(135deg, rgba(139, 58, 98, 0.3), rgba(45, 27, 51, 0.5)); + display: none; } +/* Gradient sombre en bas pour le texte */ .bento-project .bento-image::after { content: ''; position: absolute; @@ -2132,7 +2131,9 @@ footer { left: 0; right: 0; height: 50%; - background: linear-gradient(to top, var(--bg-deep), transparent); + background: linear-gradient(to top, rgba(10,10,15,0.9) 0%, transparent 100%); + z-index: 2; + pointer-events: none; } .bento-image-content { @@ -2140,7 +2141,7 @@ footer { bottom: 2rem; left: 2rem; right: 2rem; - z-index: 1; + z-index: 3; } .bento-image-content .portfolio-tag { @@ -2462,19 +2463,43 @@ footer { } .project-gallery-slides { - display: flex; + position: relative; width: 100%; height: 100%; - transition: transform 0.5s ease; } .project-gallery-slide { - min-width: 100%; + position: absolute; + inset: 0; + width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; - position: relative; + opacity: 0; + pointer-events: none; + transition: opacity 0.35s ease, transform 0.35s ease; + transform: translateX(100%); + will-change: transform, opacity; +} + +/* Slide à gauche de la courante */ +.project-gallery-slide.slide-left { + transform: translateX(-100%); + opacity: 0; +} + +/* Slide à droite de la courante */ +.project-gallery-slide.slide-right { + transform: translateX(100%); + opacity: 0; +} + +/* Slide active — visible */ +.project-gallery-slide.active { + opacity: 1; + transform: translateX(0) !important; + pointer-events: auto; } .project-gallery-slide::before { @@ -2700,12 +2725,12 @@ footer { position: absolute; inset: 0; background: transparent; - z-index: 1; + z-index: 3; transition: background 0.3s ease; } .portfolio-item:hover::before { - background: rgba(139, 58, 98, 0.1); + background: rgba(139, 58, 98, 0.08); } .portfolio-item:active { @@ -4171,13 +4196,85 @@ footer { width: 100%; height: 100%; object-fit: cover; - z-index: 1; + z-index: 1; /* au-dessus du gradient .portfolio-bg */ display: block; } -/* .portfolio-bg conserve son gradient en fallback derrière l'image */ +/* .portfolio-bg — override pour les cartes avec image */ .portfolio-bg { position: absolute; inset: 0; overflow: hidden; + /* gradient retiré ici — défini dans la règle principale */ + background: none; } + +/* ═══════════════════════════════════════════════════════════════════════════ + BENTO + PORTFOLIO — image de couverture réelle + ═══════════════════════════════════════════════════════════════════════════ */ + +.bento-cover-img { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + object-fit: cover; + z-index: 1; /* au-dessus du gradient de fond */ + display: block; +} + +/* bento-image-content — z-index géré dans la règle principale ligne ~2141 */ + +/* ═══════════════════════════════════════════════════════════════════════════ + GALLERY — iframe YouTube + ═══════════════════════════════════════════════════════════════════════════ */ + +.yt-wrapper { + position: absolute; + inset: 0; + width: 100%; + height: 100%; +} + +.gallery-slide-yt-iframe { + width: 100%; + height: 100%; + border: none; + display: block; +} + +/* ═══════════════════════════════════════════════════════════════════════════ + GALLERY — bouton mute vidéo + ═══════════════════════════════════════════════════════════════════════════ */ + +.gallery-mute-btn { + position: absolute; + bottom: 3rem; /* au-dessus des dots */ + right: 1rem; + z-index: 10; + width: 38px; + height: 38px; + background: rgba(0, 0, 0, 0.6); + border: 1px solid rgba(255,255,255,0.2); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + color: white; + transition: background 0.2s ease; + backdrop-filter: blur(4px); +} + +.gallery-mute-btn:hover { + background: rgba(139, 58, 98, 0.8); + border-color: var(--accent-primary); +} + +/* Icône son coupé = visible par défaut (muted=true au départ) */ +.gallery-mute-btn .icon-muted { display: block; } +.gallery-mute-btn .icon-unmuted { display: none; } + +/* Quand le son est activé */ +.gallery-mute-btn.unmuted .icon-muted { display: none; } +.gallery-mute-btn.unmuted .icon-unmuted { display: block; } diff --git a/assets/data/partners.json b/assets/data/partners.json index b628b9d..47158df 100644 --- a/assets/data/partners.json +++ b/assets/data/partners.json @@ -1,50 +1,113 @@ [ { "name": "victorias-vice", - "displayName": "Victoria's Vice", + "displayName": "Victoria's Vice 2", "description": "Serveur RP whitelist Fortnite sur thème italien. L'une de nos collaborations les plus abouties.", "longDesc": "Victoria's Vice est un serveur RP whitelist Fortnite immersif basé sur une esthétique italienne unique. OmégaKube a développé l'intégralité de la map UEFN, le bot RP Vicy et l'identité visuelle du projet.", "gradient": "linear-gradient(135deg, #5E2040, #8b3a62)", - "url": "#", - "discord": "#", "since": "2025", - "services": ["Map UEFN", "Bot Discord", "Branding"], + "services": [ + "Map UEFN", + "Bot Discord", + "Branding" + ], "stats": [ - { "icon": "users", "value": "70", "label": "Joueurs max" }, - { "icon": "home", "value": "30+", "label": "Bâtiments" }, - { "icon": "play", "value": "30+", "label": "Sessions" } - ] + { + "icon": "users", + "value": "70", + "label": "Joueurs max" + }, + { + "icon": "home", + "value": "30+", + "label": "Bâtiments" + }, + { + "icon": "play", + "value": "30+", + "label": "Sessions" + } + ], + "social": { + "discord": "https://discord.gg/8D564jm2SD", + "twitter": "", + "instagram": "", + "youtube": "https://www.youtube.com/@VictoriasVice", + "tiktok": "", + "website": "#" + } }, { - "name": "partenaire-2", - "displayName": "Partenaire 2", - "description": "Description courte du partenaire.", - "longDesc": "Description longue du partenaire à renseigner.", + "name": "red-dust-redemption", + "displayName": "Red Dust Redemption", + "description": "Serveur RP whitelist sur le thème far-west.", + "longDesc": "Serveur RP whitelist sur le thème du far-west.", "gradient": "linear-gradient(135deg, var(--accent-primary), var(--accent-secondary))", - "url": "#", - "discord": "#", "since": "2025", - "services": ["Service 1", "Service 2"], + "services": [ + "Sessions RP Red Dust Redemption" + ], "stats": [ - { "icon": "star", "value": "?", "label": "Stat 1" }, - { "icon": "zap", "value": "?", "label": "Stat 2" }, - { "icon": "heart", "value": "?", "label": "Stat 3" } - ] + { + "icon": "star", + "value": "?", + "label": "Stat 1" + }, + { + "icon": "zap", + "value": "?", + "label": "Stat 2" + }, + { + "icon": "heart", + "value": "?", + "label": "Stat 3" + } + ], + "social": { + "discord": "#", + "twitter": "", + "instagram": "", + "youtube": "", + "tiktok": "", + "website": "#" + } }, { - "name": "partenaire-3", - "displayName": "Partenaire 3", - "description": "Description courte du partenaire.", + "name": "rickroll", + "displayName": "Rick Astley", + "description": "Official Video 4K Remaster", "longDesc": "Description longue du partenaire à renseigner.", "gradient": "linear-gradient(135deg, #1a3a5e, #3a5e8b)", - "url": "#", - "discord": "#", "since": "2025", - "services": ["Service 1", "Service 2"], + "services": [ + "Service 1", + "Service 2" + ], "stats": [ - { "icon": "star", "value": "?", "label": "Stat 1" }, - { "icon": "zap", "value": "?", "label": "Stat 2" }, - { "icon": "heart", "value": "?", "label": "Stat 3" } - ] + { + "icon": "star", + "value": "?", + "label": "Stat 1" + }, + { + "icon": "zap", + "value": "?", + "label": "Stat 2" + }, + { + "icon": "heart", + "value": "?", + "label": "Stat 3" + } + ], + "social": { + "discord": "#", + "twitter": "", + "instagram": "", + "youtube": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", + "tiktok": "", + "website": "#" + } } -] +] \ No newline at end of file diff --git a/assets/data/projects.json b/assets/data/projects.json index 28897f1..85a1e73 100644 --- a/assets/data/projects.json +++ b/assets/data/projects.json @@ -55,7 +55,18 @@ "label": "Semaines de dev" } ], - "images": "assets/images/projects/kuby/" + "images": "assets/images/projects/kuby/", + "files": [ + "imgk-1.png", + "https://www.youtube.com/watch?v=dQw4w9WgXcQ" + ], + "social": { + "discord": "", + "instagram": "", + "tiktok": "", + "youtube": "", + "twitter": "" + } }, { "id": 2, @@ -113,7 +124,26 @@ "label": "Mois de dev" } ], - "images": "assets/images/projects/victorias-vice/" + "images": "assets/images/projects/victorias-vice-1/", + "files": [ + "imgvv1-1.jpg", + "imgvv1-2.jpg", + "imgvv1-3.jpg", + "imgvv1-4.jpg", + "imgvv1-5.jpg", + "imgvv1-6.jpg", + "imgvv1-7.jpg", + "imgvv1-8.jpg", + "TrailerOfficielVV1.mp4", + "yt:xiCdHA-Z7uM" + ], + "social": { + "discord": "https://discord.gg/8D564jm2SD", + "instagram": "", + "tiktok": "", + "youtube": "", + "twitter": "" + } }, { "id": 3, @@ -171,7 +201,18 @@ "label": "Uptime" } ], - "images": "assets/images/projects/vicy/" + "images": "assets/images/projects/vicy/", + "files": [ + "imgvicy-1.png", + "yt:dQw4w9WgXcQ" + ], + "social": { + "discord": "https://discord.gg/8D564jm2SD", + "instagram": "", + "tiktok": "", + "youtube": "", + "twitter": "" + } }, { "id": 4, @@ -222,7 +263,15 @@ "label": "Illustrator" } ], - "images": "assets/images/projects/branding-omega-kube/" + "images": "assets/images/projects/branding-omega-kube/", + "files": ["logo.png"], + "social": { + "discord": "https://discord.gg/FwvNkvu5dy", + "instagram": "", + "tiktok": "", + "youtube": "", + "twitter": "" + } }, { "id": 5, @@ -270,6 +319,164 @@ "label": "Systèmes" } ], - "images": "assets/images/projects/site-omega/" - } + "images": "assets/images/projects/site-omega/", + "files": [ + "imgso-1.png", + "imgso-2.png", + "imgso-3.png", + "imgso-4.png", + "imgso-5.png", + "imgso-6.png", + "imgso-7.png", + "imgso-8.png", + "imgso-9.jpg" + ], + "social": { + "discord": "", + "instagram": "", + "tiktok": "", + "youtube": "", + "twitter": "" + } + }, + { + "id": 6, + "category": "map", + "title":"Victoria's Vice 2", + "desc": "Suite de Victoria's Vice, avec une map plus grande, plus de bâtiments, plus de systèmes et une immersion encore plus poussée dans l'univers italien.", + "gradient": "linear-gradient(135deg, #5E2040, #8b3a62)", + "year": "2026", + "duration": "en cour...", + "features": [ + "économie réaliste", + "50+ bâtiments", + "Système jour/nuit", + "Serveur Whitelist", + "Métiers légaux variés", + "Bot RP Vicy exclusif" + ], + "tech": [ + { + "name": "Fortnite Creative", + "icon": "map" + }, + { + "name": "UEFN", + "icon": "layers" + }, + { + "name": "Verse", + "icon": "cpu" + }, + { + "name": "Texturing", + "icon": "image" + } + ], + "stats": [ + { + "icon": "play", + "value": "en cour...", + "label": "Sessions" + }, + { + "icon": "home", + "value": "en cour...", + "label": "Bâtiments" + }, + { + "icon": "users", + "value": "en cour...", + "label": "Joueurs max" + }, + { + "icon": "calendar", + "value": "en cour...", + "label": "Mois de dev" + } + ], + "images": "assets/images/projects/victorias-vice-2/", + "files": [ + "imgvv2-1.jpg", + "imgvv2-2.jpg", + "imgvv2-3.jpg", + "https://www.youtube.com/watch?v=Lx-1FWOJN9E" + ], + "social": { + "discord": "https://discord.gg/AM3e58cZvX", + "instagram": "", + "tiktok": "", + "youtube": "", + "twitter": "" + } + }, + { + "id": 7, + "category": "bot", + "title": "Beta", + "desc": "En cour de développement chez Omega Kube.", + "gradient": "linear-gradient(135deg, #000000, #434343)", + "year": "2026", + "duration": "en cour...", + "features": [ + "en cour..." + ], + "tech": [ + { + "name": "Python", + "icon": "code" + }, + { + "name": "Discord.py", + "icon": "message-circle" + }, + { + "name": "MySQL", + "icon": "database" + }, + { + "name": "Pillow", + "icon": "image" + }, + { + "name": "Autre tech", + "icon": "tool" + } + ], + "stats": [ + { + "icon": "users", + "value": "en cour...", + "label": "Utilisateurs" + }, + { + "icon": "terminal", + "value": "en cour...", + "label": "Commandes" + }, + { + "icon": "credit-card", + "value": "en cour...", + "label": "RP menés" + }, + { + "icon": "activity", + "value": "en cour...", + "label": "Uptime" + } + ], + "images": "assets/images/projects/beta/", + "files": [ + "imgb-1.png", + "imgb-2.png", + "yt:dQw4w9WgXcQ" + ], + "social": { + "discord": "https://discord.gg/FwvNkvu5dy", + "instagram": "", + "tiktok": "", + "youtube": "", + "twitter": "" + } + } ] \ No newline at end of file diff --git a/assets/data/team.json b/assets/data/team.json index 35d8ce8..73e0460 100644 --- a/assets/data/team.json +++ b/assets/data/team.json @@ -6,11 +6,37 @@ "avatar": "N", "bio": "Nixfix donne vie aux identités visuelles des projets RP. Passionné de design graphique, il excelle aussi bien dans la création de logos que dans la gestion de projets. Son style unique allie une esthétique gaming affirmée à un véritable professionnalisme, afin de proposer des visuels percutants et cohérents.", "stats": [ - { "value": "6", "label": "Ans d'exp." }, - { "value": "15+", "label": "Projets" }, - { "value": "★★★", "label": "Expert" } + { + "value": "6", + "label": "Ans d'exp." + }, + { + "value": "15+", + "label": "Projets" + }, + { + "value": "★★★", + "label": "Expert" + } ], - "skills": ["Polyvalent", "Gestion de projets", "Illustrator", "After Effects", "Figma", "UEFN", "Photoshop"] + "skills": [ + "Polyvalent", + "Gestion de projets", + "Illustrator", + "After Effects", + "Figma", + "UEFN", + "Photoshop", + "Verse" + ], + "social": { + "discord": "", + "twitter": "", + "instagram": "", + "youtube": "", + "tiktok": "", + "github": "" + } }, { "id": "353942721997832195", @@ -19,76 +45,146 @@ "avatar": "M", "bio": "Je suis un développeur UEFN et Builder Minecraft polyvalent avec une solide expérience dans la création de systèmes pour divers Serveurs RP. J'ai travaillé sur des projets de plus ou moins grande envergure sur diverses plateformes de jeux. J'ai aussi une certaine expérience en gestion de projet et je me montre polyvalent pour beaucoup de tâches", "stats": [ - { "value": "6", "label": "Ans d'exp." }, - { "value": "25+", "label": "Systèmes" }, - { "value": "∞", "label": "Fan de Louis de Funès" } + { + "value": "6", + "label": "Ans d'exp." + }, + { + "value": "25+", + "label": "Systèmes" + }, + { + "value": "∞", + "label": "Fan de Louis de Funès" + } ], - "skills": ["Polyvalent", "Gestion de projets", "UEFN", "Builder Minecraft"] + "skills": [ + "Polyvalent", + "Gestion de projets", + "UEFN", + "Builder Minecraft" + ], + "social": { + "discord": "", + "twitter": "", + "instagram": "", + "youtube": "", + "tiktok": "", + "github": "" + } }, { "id": "971446412690722826", "name": "Gameur", - "role": "Développeur Principal", + "role": "Agent - Développeur Principal", "avatar": "G", "bio": "Avec plus de 3 ans d'expérience dans le self-hosting, j'ai créé des bots pour des communautés de toutes tailles, allant de petits serveurs à des projets d'envergure. Mon expertise couvre la création de commandes personnalisées, l'intégration d'API tierces et la gestion de bases de données pour offrir des fonctionnalités avancées et une expérience utilisateur fluide.", "stats": [ - { "value": "3", "label": "Ans d'exp." }, - { "value": "50+", "label": "Projets" }, - { "value": "★★★★", "label": "Intermédiaire - Avançé" } + { + "value": "3", + "label": "Ans d'exp." + }, + { + "value": "50+", + "label": "Projets" + }, + { + "value": "★★★★", + "label": "Intermédiaire - Avançé" + } ], - "skills": ["Python", "Discord.py", "API REST", "Docker", "self-hosting", "Linux", "Gestion de projets"] - }, - { - "id": "1324439906046574693", - "name": "Lowei", - "role": "Développeur Backend", - "avatar": "L", - "bio": "Salut ! Je suis un développeur backend passionné par la création de systèmes robustes, performants et dans l'automatisation de tâches. N'hésite pas à checker mes réseaux ci-dessous !", - "stats": [ - { "value": "5", "label": "Ans d'exp." }, - { "value": "20+", "label": "Systèmes" }, - { "value": "∞", "label": "Disponibilité" } + "skills": [ + "Python", + "Discord.py", + "API REST", + "Docker", + "self-hosting", + "Linux", + "Gestion de projets" ], - "skills": ["Fortnite Creative", "UEFN", "Level Design", "3D", "Lighting", "Scripting"] + "social": { + "discord": "", + "twitter": "", + "instagram": "", + "youtube": "", + "tiktok": "", + "github": "" + } }, { "id": "561485865562406914", "name": "KIRITO_KMA", - "role": "All Master & Développeur", + "role": "Agent - All Master & Développeur", "avatar": "K", "bio": "Au-delà des horizons et par-delà les temps", "stats": [ - { "value": "4", "label": "Ans d'exp." }, - { "value": "50+", "label": "Projets menés" }, - { "value": "1000%", "label": "Maîtrise du shifoumi" } + { + "value": "4", + "label": "Ans d'exp." + }, + { + "value": "50+", + "label": "Projets menés" + }, + { + "value": "1000%", + "label": "Maîtrise du shifoumi" + } ], - "skills": ["Dev Full-Stack", "SEO", "Map-Maker", "Bot Discord", "Scénariste", "Shifoumi", "RedStone Minecraft"] + "skills": [ + "Dev Full-Stack", + "SEO", + "Map-Maker", + "Bot Discord", + "Scénariste", + "Shifoumi", + "RedStone Minecraft" + ], + "social": { + "discord": "", + "twitter": "", + "instagram": "", + "youtube": "", + "tiktok": "", + "github": "" + } }, { - "id": "983747660265693258", - "name": "Mr Reiko", - "role": "Développeur UEFN", - "avatar": "R", - "bio": "Lucas est l'architecte invisible derrière les systèmes les plus robustes d'OmégaKube. Spécialisé dans les bases de données et les API, il conçoit des systèmes d'économie capables de gérer des millions de transactions sans ralentissement.", + "id": "1324439906046574693", + "name": "Lowei", + "role": "Agent - Développeur Backend", + "avatar": "L", + "bio": "Salut ! Je suis un développeur backend passionné par la création de systèmes robustes, performants et dans l'automatisation de tâches. N'hésite pas à checker mes réseaux ci-dessous !", "stats": [ - { "value": "8", "label": "Ans d'exp." }, - { "value": "30+", "label": "Systèmes" }, - { "value": "99.9%", "label": "Uptime" } + { + "value": "5", + "label": "Ans d'exp." + }, + { + "value": "20+", + "label": "Systèmes" + }, + { + "value": "∞", + "label": "Disponibilité" + } ], - "skills": ["Javascript", "HTML", "C++", "Verse", "Python", "UEFN", "Blender"] - }, - { - "id": "1013376581458210986", - "name": "Kayrix", - "role": "Développer UEFN", - "avatar": "K", - "bio": "Je suis polyvalent et curieux, je cherche à toucher à tout sur l'UEFN. En parallèle, je suis en études de cinéma d'animation 3D et jeux vidéo, avec des compétences en modélisation 3D, animation et environnements sur Unreal Engine. Je développe aussi mes propres projets RP depuis un moment, ce qui m'a permis d'acquérir une bonne expérience, tout en restant dans une démarche d'apprentissage et d'amélioration continue.", - "stats": [ - { "value": "5", "label": "Ans d'exp." }, - { "value": "40+", "label": "Scénarios" }, - { "value": "∞", "label": "Créativité" } + "skills": [ + "Python", + "HTML", + "CSS", + "C, C++", + "Java", + "Blender" ], - "skills": ["UEFN", "Maya", "Polyvalent", "Gestion de projets"] + "social": { + "discord": "", + "twitter": "", + "instagram": "", + "youtube": "", + "tiktok": "", + "github": "" + } }, { "id": "1151495567256584253", @@ -97,10 +193,34 @@ "avatar": "K", "bio": "Kuby est le gardien de la qualité du moindre octets au quetta-octets chez OmégaKube. Aucune commande ne lui échappe. Il execute méticuleusement chaque instructions, chaque commande, chaque interaction pour garantir une expérience sans accroc aux utilisateurs finaux.", "stats": [ - { "value": "2", "label": "Yotta d'exp sur Discord" }, - { "value": "500+", "label": "Commande réalisées" }, - { "value": "0", "label": "Vulnerabilités" } + { + "value": "2", + "label": "Yotta d'exp sur Discord" + }, + { + "value": "500+", + "label": "Commande réalisées" + }, + { + "value": "0", + "label": "Vulnerabilités" + } ], - "skills": ["Moderation", "Events", "Documentation", "Serveur Discord", "Administration","Bot"] + "skills": [ + "Moderation", + "Events", + "Documentation", + "Serveur Discord", + "Administration", + "Bot" + ], + "social": { + "discord": "", + "twitter": "", + "instagram": "", + "youtube": "", + "tiktok": "", + "github": "" + } } -] +] \ No newline at end of file diff --git a/assets/images/partners/red-dust-redemption.png b/assets/images/partners/red-dust-redemption.png new file mode 100644 index 0000000..5c090b6 Binary files /dev/null and b/assets/images/partners/red-dust-redemption.png differ diff --git a/assets/images/partners/rickroll.png b/assets/images/partners/rickroll.png new file mode 100644 index 0000000..5618c62 Binary files /dev/null and b/assets/images/partners/rickroll.png differ diff --git a/assets/images/partners/victorias-vice.png b/assets/images/partners/victorias-vice.png new file mode 100644 index 0000000..5fcf3f5 Binary files /dev/null and b/assets/images/partners/victorias-vice.png differ diff --git a/assets/images/projects/beta/imgb-1.png b/assets/images/projects/beta/imgb-1.png new file mode 100644 index 0000000..281729a Binary files /dev/null and b/assets/images/projects/beta/imgb-1.png differ diff --git a/assets/images/projects/beta/imgb-2.png b/assets/images/projects/beta/imgb-2.png new file mode 100644 index 0000000..72101e0 Binary files /dev/null and b/assets/images/projects/beta/imgb-2.png differ diff --git a/assets/images/projects/branding-omega-kube/logo.png b/assets/images/projects/branding-omega-kube/logo.png new file mode 100644 index 0000000..c870bcf Binary files /dev/null and b/assets/images/projects/branding-omega-kube/logo.png differ diff --git a/assets/images/projects/kuby/imgk-1.png b/assets/images/projects/kuby/imgk-1.png new file mode 100644 index 0000000..9c3656e Binary files /dev/null and b/assets/images/projects/kuby/imgk-1.png differ diff --git a/assets/images/projects/kuby/imgk-1bis.png b/assets/images/projects/kuby/imgk-1bis.png new file mode 100644 index 0000000..6187ffb Binary files /dev/null and b/assets/images/projects/kuby/imgk-1bis.png differ diff --git a/assets/images/projects/site-omega/imgso-1.png b/assets/images/projects/site-omega/imgso-1.png new file mode 100644 index 0000000..7201c61 Binary files /dev/null and b/assets/images/projects/site-omega/imgso-1.png differ diff --git a/assets/images/projects/site-omega/imgso-2.png b/assets/images/projects/site-omega/imgso-2.png new file mode 100644 index 0000000..01f0ba9 Binary files /dev/null and b/assets/images/projects/site-omega/imgso-2.png differ diff --git a/assets/images/projects/site-omega/imgso-3.png b/assets/images/projects/site-omega/imgso-3.png new file mode 100644 index 0000000..eab1c1b Binary files /dev/null and b/assets/images/projects/site-omega/imgso-3.png differ diff --git a/assets/images/projects/site-omega/imgso-4.png b/assets/images/projects/site-omega/imgso-4.png new file mode 100644 index 0000000..a2ccde9 Binary files /dev/null and b/assets/images/projects/site-omega/imgso-4.png differ diff --git a/assets/images/projects/site-omega/imgso-5.png b/assets/images/projects/site-omega/imgso-5.png new file mode 100644 index 0000000..b83e70b Binary files /dev/null and b/assets/images/projects/site-omega/imgso-5.png differ diff --git a/assets/images/projects/site-omega/imgso-6.png b/assets/images/projects/site-omega/imgso-6.png new file mode 100644 index 0000000..b76bcb7 Binary files /dev/null and b/assets/images/projects/site-omega/imgso-6.png differ diff --git a/assets/images/projects/site-omega/imgso-7.png b/assets/images/projects/site-omega/imgso-7.png new file mode 100644 index 0000000..dcc4d6d Binary files /dev/null and b/assets/images/projects/site-omega/imgso-7.png differ diff --git a/assets/images/projects/site-omega/imgso-8.png b/assets/images/projects/site-omega/imgso-8.png new file mode 100644 index 0000000..49767d3 Binary files /dev/null and b/assets/images/projects/site-omega/imgso-8.png differ diff --git a/assets/images/projects/site-omega/imgso-9.jpg b/assets/images/projects/site-omega/imgso-9.jpg new file mode 100644 index 0000000..10f1acd Binary files /dev/null and b/assets/images/projects/site-omega/imgso-9.jpg differ diff --git a/assets/images/projects/victorias-vice-1/TrailerOfficielVV1.mp4 b/assets/images/projects/victorias-vice-1/TrailerOfficielVV1.mp4 new file mode 100644 index 0000000..3caa9b1 Binary files /dev/null and b/assets/images/projects/victorias-vice-1/TrailerOfficielVV1.mp4 differ diff --git a/assets/images/projects/victorias-vice-1/imgvv1-1.jpg b/assets/images/projects/victorias-vice-1/imgvv1-1.jpg new file mode 100644 index 0000000..f897ac2 Binary files /dev/null and b/assets/images/projects/victorias-vice-1/imgvv1-1.jpg differ diff --git a/assets/images/projects/victorias-vice-1/imgvv1-2.jpg b/assets/images/projects/victorias-vice-1/imgvv1-2.jpg new file mode 100644 index 0000000..8eeeb6b Binary files /dev/null and b/assets/images/projects/victorias-vice-1/imgvv1-2.jpg differ diff --git a/assets/images/projects/victorias-vice-1/imgvv1-3.jpg b/assets/images/projects/victorias-vice-1/imgvv1-3.jpg new file mode 100644 index 0000000..856dc3f Binary files /dev/null and b/assets/images/projects/victorias-vice-1/imgvv1-3.jpg differ diff --git a/assets/images/projects/victorias-vice-1/imgvv1-4.jpg b/assets/images/projects/victorias-vice-1/imgvv1-4.jpg new file mode 100644 index 0000000..14cb339 Binary files /dev/null and b/assets/images/projects/victorias-vice-1/imgvv1-4.jpg differ diff --git a/assets/images/projects/victorias-vice-1/imgvv1-5.jpg b/assets/images/projects/victorias-vice-1/imgvv1-5.jpg new file mode 100644 index 0000000..5752188 Binary files /dev/null and b/assets/images/projects/victorias-vice-1/imgvv1-5.jpg differ diff --git a/assets/images/projects/victorias-vice-1/imgvv1-6.jpg b/assets/images/projects/victorias-vice-1/imgvv1-6.jpg new file mode 100644 index 0000000..b2d2a19 Binary files /dev/null and b/assets/images/projects/victorias-vice-1/imgvv1-6.jpg differ diff --git a/assets/images/projects/victorias-vice-1/imgvv1-7.jpg b/assets/images/projects/victorias-vice-1/imgvv1-7.jpg new file mode 100644 index 0000000..e41c425 Binary files /dev/null and b/assets/images/projects/victorias-vice-1/imgvv1-7.jpg differ diff --git a/assets/images/projects/victorias-vice-1/imgvv1-8.jpg b/assets/images/projects/victorias-vice-1/imgvv1-8.jpg new file mode 100644 index 0000000..1093c63 Binary files /dev/null and b/assets/images/projects/victorias-vice-1/imgvv1-8.jpg differ diff --git a/assets/images/projects/victorias-vice-2/imgvv2-1.jpg b/assets/images/projects/victorias-vice-2/imgvv2-1.jpg new file mode 100644 index 0000000..a4c7b2d Binary files /dev/null and b/assets/images/projects/victorias-vice-2/imgvv2-1.jpg differ diff --git a/assets/images/projects/victorias-vice-2/imgvv2-2.jpg b/assets/images/projects/victorias-vice-2/imgvv2-2.jpg new file mode 100644 index 0000000..6f1346a Binary files /dev/null and b/assets/images/projects/victorias-vice-2/imgvv2-2.jpg differ diff --git a/assets/images/projects/victorias-vice-2/imgvv2-3.jpg b/assets/images/projects/victorias-vice-2/imgvv2-3.jpg new file mode 100644 index 0000000..ff467a4 Binary files /dev/null and b/assets/images/projects/victorias-vice-2/imgvv2-3.jpg differ diff --git a/assets/images/projects/vicy/imgvicy-1.png b/assets/images/projects/vicy/imgvicy-1.png new file mode 100644 index 0000000..9b78325 Binary files /dev/null and b/assets/images/projects/vicy/imgvicy-1.png differ diff --git a/assets/js/home.js b/assets/js/home.js index 2d8eb16..65f6d33 100644 --- a/assets/js/home.js +++ b/assets/js/home.js @@ -12,16 +12,16 @@ document.addEventListener('DOMContentLoaded', () => { const categoryLabels = { bot: 'Bot Discord', map: 'Fortnite Map', graphisme: 'Graphisme' }; homePortfolioGrid.innerHTML = first3.map((p, i) => { - const imgSrc = (p.images || '') + '1.png'; + const firstFile = Array.isArray(p.files) && p.files.length > 0 ? p.files[0] : null; + const imgSrc = firstFile ? (p.images || '') + firstFile : null; return `
    - ${p.title} + ${imgSrc ? `${p.title}` : ''}
    ${categoryLabels[p.category] || p.category}

    ${p.title}

    -

    ${p.desc.substring(0, 80)}${p.desc.length > 80 ? '…' : ''}

    `; @@ -32,13 +32,24 @@ document.addEventListener('DOMContentLoaded', () => { if (window.feather && feather.replace) try { feather.replace(); } catch(e) {} }, 80); - // Délégation : attend que openProjectModal soit défini par realisations.js + // Délégation globale sur document — fonctionne même si realisations.js + // se charge après home.js (ordre des scripts defer non garanti) homePortfolioGrid.addEventListener('click', e => { const item = e.target.closest('.portfolio-item[data-project-id]'); if (!item) return; const id = item.getAttribute('data-project-id'); if (typeof window.openProjectModal === 'function') { window.openProjectModal(id); + } else { + // Retry : realisations.js pas encore initialisé, on attend + const wait = setInterval(() => { + if (typeof window.openProjectModal === 'function') { + clearInterval(wait); + window.openProjectModal(id); + } + }, 50); + // Abandon après 3 secondes + setTimeout(() => clearInterval(wait), 3000); } }); }) @@ -163,16 +174,10 @@ document.addEventListener('DOMContentLoaded', () => { `).join(''); const links = document.getElementById('partner-modal-links'); - links.innerHTML = ''; - if (p.url && p.url !== '#') { - links.innerHTML += ` Site web`; - } - if (p.discord && p.discord !== '#') { - links.innerHTML += ` - - Discord - `; - } + // Réseaux sociaux depuis le champ social du partenaire + links.innerHTML = typeof window.renderSocialLinks === 'function' + ? window.renderSocialLinks(p.social) + : ''; if (window.feather) feather.replace(); partnerModalOverlay.classList.add('active'); document.body.style.overflow = 'hidden'; @@ -302,13 +307,13 @@ document.addEventListener('DOMContentLoaded', () => { // Modal const modalOverlay = document.getElementById('team-modal-overlay'); const modalClose = document.getElementById('team-modal-close'); - const modalAvatar = document.getElementById('modal-avatar'); - const modalName = document.getElementById('modal-name'); - const modalRole = document.getElementById('modal-role'); - const modalBio = document.getElementById('modal-bio'); - const modalStats = document.getElementById('modal-stats'); - const modalSkills = document.getElementById('modal-skills'); - const modalSocial = document.getElementById('modal-social'); + const modalAvatar = document.getElementById('team-modal-avatar'); + const modalName = document.getElementById('team-modal-name'); + const modalRole = document.getElementById('team-modal-role'); + const modalBio = document.getElementById('team-modal-bio'); + const modalStats = document.getElementById('team-modal-stats'); + const modalSkills = document.getElementById('team-modal-skills'); + const modalSocial = document.getElementById('team-modal-social'); function openMemberModal(index) { const m = members[index]; @@ -330,14 +335,11 @@ document.addEventListener('DOMContentLoaded', () => { `).join(''); modalSkills.innerHTML = (m.skills || []).map(s => `${s}`).join(''); - modalSocial.innerHTML = ` - - - - - - - `; + // Réseaux sociaux depuis le JSON du membre (+ fallback discord global) + const socialHtml = typeof window.renderSocialLinks === 'function' + ? window.renderSocialLinks(m.social, (window.OK_SOCIAL || {}).discord) + : ''; + modalSocial.innerHTML = socialHtml; modalOverlay.classList.add('active'); document.body.style.overflow = 'hidden'; } diff --git a/assets/js/main.js b/assets/js/main.js index e34b113..2a8e6bd 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1,5 +1,58 @@ // OmégaKube - shared scripts +// ═══════════════════════════════════════════════════════════════════════════ +// CONFIGURATION GLOBALE — liens réseaux sociaux +// Modifier ici pour mettre à jour partout sur le site +// ═══════════════════════════════════════════════════════════════════════════ +window.OK_SOCIAL = { + discord: 'https://discord.gg/FwvNkvu5dy', + fortnite: 'https://www.fortnite.com/@omega_kube_team', + twitter: 'https://x.com/Omegakube', + instagram: 'https://www.instagram.com/omegakube/', + youtube: 'https://www.youtube.com/@OmegaKube', + tiktok: 'https://www.tiktok.com/@omegakube', + facebook: '#', + bluesky: '#', + email: 'contact@omegakube.fr' +}; + +// SVGs des réseaux — utilisé partout dans les modals +const SVG_ICONS = { + discord: '', + fortnite: '', + twitter: '', + instagram: '', + youtube: '', + tiktok: '', + github: '', + website: '', +}; + +/** + * Génère le HTML des liens sociaux pour les modals + * @param {Object} social - objet {discord, twitter, instagram, ...} + * @param {string} [discordFallback] - lien discord global si pas de lien perso + * @returns {string} HTML des icônes sociales + */ +window.renderSocialLinks = function(social, discordFallback) { + const S = social || {}; + const G = window.OK_SOCIAL || {}; + const entries = [ + { key: 'discord', url: S.discord || discordFallback || G.discord }, + { key: 'fortnite', url: S.fortnite || G.fortnite }, + { key: 'twitter', url: S.twitter }, + { key: 'instagram', url: S.instagram }, + { key: 'youtube', url: S.youtube }, + { key: 'tiktok', url: S.tiktok }, + { key: 'github', url: S.github }, + { key: 'website', url: S.website }, + ]; + return entries + .filter(e => e.url && e.url !== '#' && e.url !== '') + .map(e => `${SVG_ICONS[e.key] || ''}`) + .join(''); +}; + // Feather icons loader (centralized) // loads https://unpkg.com/feather-icons when needed and exposes window.ensureFeather() const FEATHER_URL = 'https://unpkg.com/feather-icons'; @@ -86,6 +139,27 @@ document.addEventListener('DOMContentLoaded', async () => { // wait for includes to be loaded so subsequent initialization can bind to elements inside them await loadIncludes(); + // Hydrate les liens sociaux (data-social) avec les URLs de OK_SOCIAL + (function hydrateSocialLinks() { + const S = window.OK_SOCIAL || {}; + const map = { + 'discord': S.discord, + 'twitter': S.twitter, + 'instagram': S.instagram, + 'youtube': S.youtube, + 'tiktok': S.tiktok, + 'facebook': S.facebook, + 'bluesky': S.bluesky, + 'email-link': S.email ? 'mailto:' + S.email : '#', + }; + document.querySelectorAll('[data-social]').forEach(el => { + const key = el.getAttribute('data-social'); + if (map[key] && map[key] !== '#') { + el.setAttribute('href', map[key]); + } + }); + })(); + // Déclenche les reveals maintenant que tous les includes sont dans le DOM setTimeout(() => { document.querySelectorAll('.reveal:not(.active)').forEach(el => { diff --git a/assets/js/pages/realisations.js b/assets/js/pages/realisations.js index 6904fb4..86769b3 100644 --- a/assets/js/pages/realisations.js +++ b/assets/js/pages/realisations.js @@ -57,19 +57,24 @@ document.addEventListener('DOMContentLoaded', async () => { } function renderProjects() { + if (!portfolioGrid) return; // pas sur la page réalisations const filtered = getFilteredProjects(); const projects = getProjectsForPage(filtered, currentPage); - portfolioGrid.innerHTML = projects.map(project => ` -
    -
    -
    - ${getCategoryLabel(project.category)} -

    ${project.title}

    -

    ${project.desc.substring(0, 80)}...

    + portfolioGrid.innerHTML = projects.map(project => { + const prefix = isRoot ? '' : '../'; + const firstFile = Array.isArray(project.files) && project.files.length > 0 ? project.files[0] : null; + const coverImg = firstFile ? `${project.title}` : ''; + return ` +
    +
    ${coverImg}
    +
    + ${getCategoryLabel(project.category)} +

    ${project.title}

    +
    -
    - `).join(''); + `; + }).join(''); // activate reveals & icons setTimeout(() => { @@ -83,6 +88,7 @@ document.addEventListener('DOMContentLoaded', async () => { } function renderPagination() { + if (!paginationContainer) return; // pas sur la page réalisations const filtered = getFilteredProjects(); const totalPages = getTotalPages(filtered); @@ -183,35 +189,75 @@ document.addEventListener('DOMContentLoaded', async () => {
    `).join(''); - // Gallery : charger les images du dossier via convention de nommage - // images/projects/{slug}/1.png, 2.png... avec fallback gradient - const imgPath = project.images || ''; - const imgExtensions = ['png', 'jpg', 'jpeg', 'webp']; - - // On tente de charger jusqu'à 6 images numérotées depuis le dossier - const maxImages = 6; - let slidesHtml = ''; - - // Toujours créer au moins 1 slide gradient (fallback) - // Les images réelles se chargent avec onerror pour masquer si absentes - for (let i = 1; i <= maxImages; i++) { - slidesHtml += ` - `; - } - gallerySlides.innerHTML = slidesHtml; + // Gallery : utilise project.files (noms réels) avec fallback gradient si vide + const imgPath = (isRoot ? '' : '../') + (project.images || ''); + const files = Array.isArray(project.files) ? project.files : []; - // reset gallery state + if (files.length > 0) { + // Images réelles nommées explicitement dans le JSON + // Supporte : fichier local, mp4 local, URL YouTube, shortcode yt:VIDEO_ID + gallerySlides.innerHTML = files.map((filename, i) => { + const isLocalVideo = /\.(mp4|webm|ogg)$/i.test(filename); + + // Détecte YouTube : URL complète ou shortcode yt:ID + const ytMatch = filename.match(/(?:yt:|youtube\.com\/watch\?v=|youtu\.be\/)([\w-]+)/); + + if (ytMatch) { + const videoId = ytMatch[1]; + return ` + `; + } + + if (isLocalVideo) { + return ` + `; + } + + return ` + `; + }).join(''); + } else { + // Fallback : une slide gradient unique + gallerySlides.innerHTML = ` + `; + } + + // reset gallery + affichage immédiat galleryIndex = 0; updateGallery(); updateGalleryDots(); if (modalOverlay) modalOverlay.classList.add('active'); + // Réseaux sociaux du projet + const projectSocialEl = document.getElementById('modal-project-social'); + if (projectSocialEl) { + projectSocialEl.innerHTML = typeof window.renderSocialLinks === 'function' + ? window.renderSocialLinks(project.social) + : ''; + } + if (window.feather && feather.replace) { try { feather.replace(); } catch (e) {} } @@ -223,88 +269,100 @@ document.addEventListener('DOMContentLoaded', async () => { // Gallery helpers let galleryIndex = 0; - function getVisibleSlides() { + function getAllSlides() { if (!gallerySlides) return []; - // Retourne uniquement les slides qui ont une image chargée OU qui sont la première (fallback gradient) - const all = Array.from(gallerySlides.children); - const withImg = all.filter(s => s.classList.contains('has-image')); - return withImg.length > 0 ? withImg : [all[0]].filter(Boolean); + return Array.from(gallerySlides.children).filter(s => !s.classList.contains('no-image')); } function updateGallery() { - const visible = getVisibleSlides(); - const all = gallerySlides ? Array.from(gallerySlides.children) : []; - // Cache toutes les slides non visibles - all.forEach(s => { - if (!visible.includes(s)) { s.style.display = 'none'; } - else { s.style.display = ''; } - }); - // Positionne les slides visibles - visible.forEach((s, i) => { - s.style.transform = `translateX(${(i - galleryIndex) * 100}%)`; + const slides = getAllSlides(); + if (!slides.length) return; + if (galleryIndex >= slides.length) galleryIndex = 0; + if (galleryIndex < 0) galleryIndex = slides.length - 1; + slides.forEach((s, i) => { + // Le CSS gère tout via .active — on ne touche JAMAIS à style.transform s.classList.toggle('active', i === galleryIndex); + // Juste la direction (gauche/droite) via une classe data + if (i < galleryIndex) { + s.classList.add('slide-left'); + s.classList.remove('slide-right'); + } else if (i > galleryIndex) { + s.classList.add('slide-right'); + s.classList.remove('slide-left'); + } else { + s.classList.remove('slide-left', 'slide-right'); + } }); - // Clamp index - if (galleryIndex >= visible.length) galleryIndex = Math.max(0, visible.length - 1); } function updateGalleryDots() { const galleryDots = document.getElementById('gallery-dots'); if (!galleryDots) return; - // Attend que les images se chargent avant de créer les dots - setTimeout(() => { - const visible = getVisibleSlides(); - galleryDots.innerHTML = visible.map((_, i) => - `` - ).join(''); - galleryDots.querySelectorAll('.gallery-dot').forEach(dot => { - dot.addEventListener('click', () => { - galleryIndex = parseInt(dot.dataset.idx); - updateGallery(); - galleryDots.querySelectorAll('.gallery-dot').forEach((d, i) => d.classList.toggle('active', i === galleryIndex)); - }); + const slides = getAllSlides(); + galleryDots.innerHTML = slides.map((_, i) => + `` + ).join(''); + galleryDots.querySelectorAll('.gallery-dot').forEach(dot => { + dot.addEventListener('click', () => { + galleryIndex = parseInt(dot.dataset.idx); + updateGallery(); + galleryDots.querySelectorAll('.gallery-dot').forEach((d, i) => + d.classList.toggle('active', i === galleryIndex)); }); - }, 300); + }); + } + + function syncDots() { + const galleryDots = document.getElementById('gallery-dots'); + if (!galleryDots) return; + galleryDots.querySelectorAll('.gallery-dot').forEach((d, i) => + d.classList.toggle('active', i === galleryIndex)); } function prevSlide() { - const visible = getVisibleSlides(); - galleryIndex = galleryIndex <= 0 ? visible.length - 1 : galleryIndex - 1; + galleryIndex = galleryIndex <= 0 ? getAllSlides().length - 1 : galleryIndex - 1; updateGallery(); + syncDots(); } function nextSlide() { - const visible = getVisibleSlides(); - galleryIndex = galleryIndex >= visible.length - 1 ? 0 : galleryIndex + 1; + galleryIndex = galleryIndex >= getAllSlides().length - 1 ? 0 : galleryIndex + 1; updateGallery(); + syncDots(); } - // Event bindings - filterTabs.forEach(tab => tab.addEventListener('click', (e) => { - filterTabs.forEach(t => t.classList.remove('active')); - tab.classList.add('active'); - currentFilter = tab.dataset.filter || 'all'; - currentPage = 1; - renderProjects(); - renderPagination(); - })); + // Event bindings — uniquement sur la page réalisations + if (filterTabs.length) { + filterTabs.forEach(tab => tab.addEventListener('click', (e) => { + filterTabs.forEach(t => t.classList.remove('active')); + tab.classList.add('active'); + currentFilter = tab.dataset.filter || 'all'; + currentPage = 1; + renderProjects(); + renderPagination(); + })); + } - paginationContainer.addEventListener('click', (e) => { - const btn = e.target.closest('button[data-page]'); - if (!btn) return; - const page = Number(btn.getAttribute('data-page')); - goToPage(page); - }); + if (paginationContainer) { + paginationContainer.addEventListener('click', (e) => { + const btn = e.target.closest('button[data-page]'); + if (!btn) return; + const page = Number(btn.getAttribute('data-page')); + goToPage(page); + }); + } - portfolioGrid.addEventListener('click', (e) => { - const item = e.target.closest('.portfolio-item'); - if (!item) return; - const id = item.getAttribute('data-project-id'); - openProjectModal(id); - }); + if (portfolioGrid) { + portfolioGrid.addEventListener('click', (e) => { + const item = e.target.closest('.portfolio-item'); + if (!item) return; + const id = item.getAttribute('data-project-id'); + openProjectModal(id); + }); + } if (modalClose) modalClose.addEventListener('click', closeProjectModal); if (modalOverlay) modalOverlay.addEventListener('click', (e) => { if (e.target === modalOverlay) closeProjectModal(); }); - window.addEventListener('keydown', (e) => { if (e.key === 'Escape' && modalOverlay.classList.contains('active')) closeProjectModal(); }); + window.addEventListener('keydown', (e) => { if (e.key === 'Escape' && modalOverlay && modalOverlay.classList.contains('active')) closeProjectModal(); }); if (galleryPrev) galleryPrev.addEventListener('click', prevSlide); if (galleryNext) galleryNext.addEventListener('click', nextSlide); @@ -331,9 +389,16 @@ document.addEventListener('DOMContentLoaded', async () => { const featuresHtml = (p.features || []).slice(0, 6).map(f => `${f}`).join(''); const divider = i < featured.length - 1 ? '
    ' : ''; + const prefix = isRoot ? '' : '../'; + const firstFile = Array.isArray(p.files) && p.files.length > 0 ? p.files[0] : null; + const bentoCover = firstFile + ? `${p.title}` + : ''; + return `
    + ${bentoCover}
    ${categoryLabels[p.category] || p.category}

    ${p.title}

    diff --git a/components/contact.html b/components/contact.html index 3b7fc64..fd17b60 100644 --- a/components/contact.html +++ b/components/contact.html @@ -10,13 +10,13 @@

    Discutons ensemble

    Vous avez un serveur à développer, une map à créer ou besoin d'un bot personnalisé ? Notre équipe est prête à donner vie à vos idées.

    diff --git a/index.html b/index.html index da7508d..fa2a2e1 100644 --- a/index.html +++ b/index.html @@ -170,16 +170,16 @@
    - +
    A
    - - +

    Alexandre

    +

    Développeur Principal

    - - - - +

    Bio du membre...

    +
    +
    +
    @@ -272,18 +272,18 @@

    Discutons ensemble

    Vous avez un serveur à développer, une map à créer ou besoin d'un bot personnalisé ? Notre équipe est prête à donner vie à vos idées.

    @@ -448,6 +448,7 @@
    + diff --git a/pages/faq.html b/pages/faq.html index 7648292..c8978b4 100644 --- a/pages/faq.html +++ b/pages/faq.html @@ -32,7 +32,7 @@ Nous contacter - + Rejoindre notre Discord diff --git a/pages/realisations.html b/pages/realisations.html index 4a3ad6a..7cc9279 100644 --- a/pages/realisations.html +++ b/pages/realisations.html @@ -146,6 +146,7 @@
    + @@ -158,7 +159,7 @@

    Votre projet pourrait être le prochain dans notre portfolio

    - + Démarrer un projet