diff --git a/assets/app.js b/assets/app.js index f5efc7a..2cabd8c 100644 --- a/assets/app.js +++ b/assets/app.js @@ -1,10 +1,20 @@ -import './styles/app.css'; import React from 'react'; -import { createRoot } from 'react-dom/client'; -import Home from './components/Home.jsx'; // <-- Ajoute .jsx ici ! +import ReactDOM from 'react-dom/client'; +import { BrowserRouter, Routes, Route } from 'react-router-dom'; +// Au lieu de './components/Home' +import Home from './components/Home.jsx'; +import ConstruireTrajectoire from './components/ConstruireTrajectoire.jsx'; +import './styles/app.css'; -const container = document.getElementById('root'); -if (container) { - const root = createRoot(container); - root.render(); +const rootElement = document.getElementById('root'); // ou l'ID de ton conteneur Twig +if (rootElement) { + const root = ReactDOM.createRoot(rootElement); + root.render( + + + } /> + } /> + + + ); } \ No newline at end of file diff --git a/assets/components/CompetencesEvoluer.jsx b/assets/components/CompetencesEvoluer.jsx new file mode 100644 index 0000000..6aa9edd --- /dev/null +++ b/assets/components/CompetencesEvoluer.jsx @@ -0,0 +1,53 @@ +import React from 'react'; +import '../styles/competences-evoluer.css'; + +const COMPETENCES_DATA = [ + { + id: 1, + title: "Compétences professionnelles", + content: "Gestion de projet. Communication. Coordination. Recherche appliquée. Organisation. Développement commercial. Leadership. Gestion durable. Développement durable. Pensée stratégique." + }, + { + id: 2, + title: "Compétences humaines", + content: "Confiance. Autonomie. Résilience. Adaptabilité. Intelligence émotionnelle. Leadership. Collaboration. Prise de décision. Gestion du changement." + }, + { + id: 3, + title: "Vision systémique", + intro: "Comprendre les liens entre :", + content: "les individus, les organisations, l'économie, les territoires, les communautés, les projets, et les enjeux de transition." + } +]; + +export default function CompetencesEvoluer() { + return ( +
+
+ + {/* Trait vert au-dessus */} + +
+ ); +} \ No newline at end of file diff --git a/assets/components/ConstruireTrajectoire.jsx b/assets/components/ConstruireTrajectoire.jsx new file mode 100644 index 0000000..b3a7113 --- /dev/null +++ b/assets/components/ConstruireTrajectoire.jsx @@ -0,0 +1,76 @@ +import React from 'react'; +import heroTrajectoireImg from '../img/img-traject-banner.jpg'; +import HuitTrajectoires from './HuitTrajectoires'; +import HumanEmploymentModel from './HumanEmploymentModel'; +import MethodologieEtapes from './MethodologieEtapes'; +import LearningByDoing from './LearningByDoing'; +import ExemplesProjets from './ExemplesProjets'; +import '../styles/trajectoire.css'; + +export default function ConstruireTrajectoire() { + return ( +
+ {/* 1. Hero */} +
+
+
+
+

+ Construire sa
+ trajectoire. +

+
+

Parfois, nous savons exactement où nous voulons aller.

+

Parfois, nous savons simplement que nous ne pouvons plus rester là où nous sommes.

+

Depuis plus de vingt ans, gaea21 accompagne les personnes dans ces moments de transition, d'évolution et de construction.

+

Non pas en leur proposant une solution unique.

+
+ +
+
+
+ + {/* 2. Questionnaire Intro */} +
+
+ + Trouvons ensemble la trajectoire qui vous correspond + +

+ Répondez à quelques questions. +

+
+ + Commencer + +
+
+
+ + {/* 3. Les 8 Trajectoires */} + + + {/* 4. Approche Human Employment Model */} + + + {/* 5. Méthodologie en 6 Étapes */} + + + {/* 6. Learning by Doing */} + + + {/* 7. Exemples de projets */} + +
+ ); +} \ No newline at end of file diff --git a/assets/components/ExemplesProjets.jsx b/assets/components/ExemplesProjets.jsx new file mode 100644 index 0000000..beb6333 --- /dev/null +++ b/assets/components/ExemplesProjets.jsx @@ -0,0 +1,65 @@ +import React from 'react'; +import '../styles/exemples-projets.css'; + +const PROJETS_DATA = [ + { + id: 1, + title: "Répertoire Vert", + description: "Développer l'économie locale durable." + }, + { + id: 2, + title: "Green Index", + description: "Construire des outils d'évaluation et de transition." + }, + { + id: 3, + title: "Recherche appliquée", + description: "Transformer les connaissances en solutions concrètes." + }, + { + id: 4, + title: "Développement commercial", + description: "Créer des liens entre projets, entreprises et opportunités." + }, + { + id: 5, + title: "Innovation territoriale", + description: "Contribuer à la transformation des territoires." + }, + { + id: 6, + title: "Programmes de développement international", + description: "Participer à des initiatives liées à l'agriculture durable, à la création d'emplois, à la recherche et au développement territorial." + } +]; + +export default function ExemplesProjets() { + return ( +
+
+ + {/* Surtitre */} + Quelques exemples de projets + + {/* Grille des 6 projets avec .map() */} +
+ {PROJETS_DATA.map((projet) => ( +
+

{projet.title}

+

{projet.description}

+
+ ))} +
+ + {/* Bouton d'action CTA */} +
+ + Découvrez les projets + +
+ +
+
+ ); +} \ No newline at end of file diff --git a/assets/components/Header.jsx b/assets/components/Header.jsx index afb153b..e5ebfad 100644 --- a/assets/components/Header.jsx +++ b/assets/components/Header.jsx @@ -1,117 +1,75 @@ -// 1. IMPORTATION DES MODULES ET ASSETS import React, { useState } from 'react'; - -// Import du logo gaea21 via Webpack Encore (gestion du hashing et du chemin public) +import { Link } from 'react-router-dom'; import logo from '../img/logo_gaea21.png'; -/** - * 2. COMPOSANT PRINCIPAL : Header - * - * Rôle fonctionnel : - * - Fournit la barre de navigation principale (Navbar) fixée ou relative en haut de page. - * - Gère l'affichage responsive : menu étendu sur desktop, tiroir repliable (drawer) sur mobile. - * - Propose un bouton d'action principal (« Participer ») pour convertir le visiteur. - */ export default function Header() { - /** - * ÉTAT LOCAL (State) : isOpen - * - false : le menu mobile est fermé - * - true : le menu mobile est ouvert (déroulé/visible) - */ const [isOpen, setIsOpen] = useState(false); + const closeMenu = () => { + setIsOpen(false); + }; + return ( - /* - Balise sémantique HTML5
: - - navbar-container : gère le fond, la bordure inférieure éventuelle, - la hauteur fixe et le z-index pour rester au-dessus du contenu de la page. - */
- - {/* - Conteneur interne centré : - - navbar-content : applique un flexbox (justify-content: space-between, align-items: center) - et borne la largeur maximale avec un padding latéral propre. - */}
- - {/* ========================================================= - A. LOGO DE LA MARQUE - ========================================================= */} - + {/* Logo gaea21 ramenant à l'accueil */} + Logo gaea21 - + - {/* ========================================================= - B. BOUTON BURGER (Affiché uniquement sur écrans mobiles) - ========================================================= */} + {/* Bouton burger mobile */} - {/* ========================================================= - C. MENU DE NAVIGATION (DESKTOP & TIROIR MOBILE) - ========================================================= */} - {/* - La classe 'open' est ajoutée conditionnellement pour déclencher - l'apparition du tiroir de navigation en version mobile. - */} + {/* Navigation principale */}
diff --git a/assets/components/Home.jsx b/assets/components/Home.jsx index 796203f..d99342c 100644 --- a/assets/components/Home.jsx +++ b/assets/components/Home.jsx @@ -1,82 +1,35 @@ -// 1. IMPORTATION DES DÉPENDANCES ET COMPOSANTS ENFANTS -import React from 'react'; - -// Barre de navigation supérieure (Logo, Liens, Boutons d'action) +import React, { useState } from 'react'; import Header from './Header'; - -// Section d'accroche principale (Titre fort, boutons d'appel à l'action, visuel héroïque) import Hero from './Hero'; - -// Cartes des profils cibles ("Qui êtes-vous ?") : Individus, Entreprises, Institutions, etc. import ProfileCards from './ProfileCards'; - -// Section explicative de la méthodologie ("Comment ça fonctionne ?") en 6 étapes + chiffres clés import Methodology from './Methodology'; - -// Section de preuve d'impact chiffrée avec fond immersif et carrousel import Impact from './Impact'; - -// Section actualités : événements, articles, publications et formulaire de newsletter intermédiaire import ActualitySection from './ActualitySection'; - -// Section opportunités et carrières ("Construire des trajectoires, pas seulement des emplois") import CareersSection from './CareersSection'; - -// Pied de page complet (Navigation secondaire, réseaux sociaux, newsletter pleine largeur, mentions légales) import Footer from './Footer'; +import ConstruireTrajectoire from './ConstruireTrajectoire'; -/** - * 2. COMPOSANT RACINE DE LA PAGE D'ACCUEIL : Home - * - * Rôle architectural : - * - Sert de page principale (Page Component / Container) orchestrant la disposition verticale - * de toutes les sections de la page d'accueil de gaea21. - * - Assure une hiérarchie sémantique HTML5 claire pour le référencement (SEO) et l'accessibilité. - */ export default function Home() { + const [view, setView] = useState('home'); + return ( - /* - CONTENEUR GLOBAL DE PAGE : - - relative : sert de référentiel de positionnement pour d'éventuels éléments absolus. - - min-h-screen : garantit que la page couvre au minimum 100% de la hauteur de la fenêtre (évite les fonds blancs coupés). - - bg-white : couleur de fond par défaut pour l'ensemble du site. - - overflow-x-hidden : masque tout débordement horizontal causé par des animations, des bannières pleine largeur ou des marges négatives. - */
- - {/* - A. EN-TÊTE DU SITE - Balise
contenant la navigation principale fixée ou relative en haut de page. - */} -
- - {/* - B. CONTENU PRINCIPAL DE LA PAGE - La balise sémantique HTML5
délimite le cœur informationnel unique de la page d'accueil. - */} +
- {/* Bannière d'introduction */} - - - {/* Sélection des parcours utilisateurs */} - - - {/* Présentation du modèle "Learning by Doing" */} - - - {/* Statistiques d'impact et résultats sur 20 ans */} - - - {/* Actualités, publications et veille */} - - - {/* Opportunités professionnelles et développement de compétences */} - - - {/* Pied de page et liens institutionnels */} -
+ {view === 'trajectoire' ? ( + + ) : ( + <> + + + + + + +
+ + )}
-
); } \ No newline at end of file diff --git a/assets/components/HuitTrajectoires.jsx b/assets/components/HuitTrajectoires.jsx new file mode 100644 index 0000000..c7cb838 --- /dev/null +++ b/assets/components/HuitTrajectoires.jsx @@ -0,0 +1,80 @@ +import React from 'react'; +import heroTrajectoireImg from '../img/img-traject-banner.png'; +import HuitTrajectoires from './HuitTrajectoires'; +import HumanEmploymentModel from './HumanEmploymentModel'; +import MethodologieEtapes from './MethodologieEtapes'; +import LearningByDoing from './LearningByDoing'; +import ExemplesProjets from './ExemplesProjets'; +import CompetencesEvoluer from './CompetencesEvoluer'; +import '../styles/trajectoire.css'; + +export default function ConstruireTrajectoire() { + return ( +
+ {/* 1. Hero */} +
+
+
+
+

+ Construire sa
+ trajectoire. +

+
+

Parfois, nous savons exactement où nous voulons aller.

+

Parfois, nous savons simplement que nous ne pouvons plus rester là où nous sommes.

+

Depuis plus de vingt ans, gaea21 accompagne les personnes dans ces moments de transition, d'évolution et de construction.

+

Non pas en leur proposant une solution unique.

+
+ +
+
+
+ + {/* 2. Questionnaire Intro */} +
+
+ + Trouvons ensemble la trajectoire qui vous correspond + +

+ Répondez à quelques questions. +

+ +
+
+ + {/* 3. Les 8 Trajectoires */} + + + {/* 4. Approche Human Employment Model */} + + + {/* 5. Méthodologie en 6 Étapes */} + + + {/* 6. Learning by Doing */} + + + {/* 7. Exemples de projets */} + + + {/* 8. Des compétences pour évoluer */} + +
+ ); +} \ No newline at end of file diff --git a/assets/components/HumanEmploymentModel.jsx b/assets/components/HumanEmploymentModel.jsx new file mode 100644 index 0000000..a8150a7 --- /dev/null +++ b/assets/components/HumanEmploymentModel.jsx @@ -0,0 +1,70 @@ +import React from 'react'; +import '../styles/human-employment.css'; +import hemImg from '../img/human-model-banner.png'; // Adapte le nom de ton image + +const PILLIERS_DATA = [ + { + id: 1, + title: "La personne", + items: ["Ses aspirations.", "Ses motivations.", "Ses besoins.", "Ses valeurs."] + }, + { + id: 2, + title: "Les compétences", + items: ["Celles qu'elle possède déjà.", "Celles qu'elle doit développer."] + }, + { + id: 3, + title: "L'expérience", + items: ["Les projets.", "Les réalisations.", "Les responsabilités."] + }, + { + id: 4, + title: "Le réseau", + items: ["Ses aspirations.", "Ses motivations.", "Ses besoins.", "Ses valeurs."] + } +]; + +export default function HumanEmploymentModel() { + return ( +
+
+ + {/* Paragraphe descriptif */} +

+ Chaque parcours est unique et ne peut pas se réduire à un simple intitulé de poste. + Nous considérons que les trajectoires durables se construisent lorsque quatre dimensions essentielles s'articulent. +

+ + {/* Grille forcée sur 4 colonnes */} +
+ {PILLIERS_DATA.map((p) => ( +
+

{p.title}

+
    + {p.items.map((it, idx) => ( +
  • {it}
  • + ))} +
+
+ ))} +
+ + {/* Phrase d'accroche */} +

+ C’est cette approche que nous appelons le Human Employment Model. +

+ + {/* Cadre de l'image */} +
+ Human Employment Model Table +
+ +
+
+ ); +} \ No newline at end of file diff --git a/assets/components/LearningByDoing.jsx b/assets/components/LearningByDoing.jsx new file mode 100644 index 0000000..6c731a4 --- /dev/null +++ b/assets/components/LearningByDoing.jsx @@ -0,0 +1,40 @@ +import React from 'react'; +import '../styles/learning-by-doing.css'; +import plantBannerImg from '../img/learning-by-doing.png'; // ou learning-by-doing.png + +export default function LearningByDoing() { + return ( +
+
+ + {/* Trait vert au-dessus */} + +
+ ); +} \ No newline at end of file diff --git a/assets/components/MethodologieEtapes.jsx b/assets/components/MethodologieEtapes.jsx new file mode 100644 index 0000000..d5c3e64 --- /dev/null +++ b/assets/components/MethodologieEtapes.jsx @@ -0,0 +1,87 @@ +import React from 'react'; +import '../styles/methodologie-etapes.css'; + +// Import des 6 icônes +import iconSearch from '../img/Search.png'; +import iconUser from '../img/User Account.png'; +import iconWrench from '../img/Frame 715.png'; +import iconPlant from '../img/Tree Planting.png'; +import iconElectrical from '../img/Electrical.png'; +import iconCycle from '../img/Frame 719.png'; + +const ETAPES_DATA = [ + { + step: "01", + title: "Comprendre", + description: "Identifier votre situation, vos aspirations, vos compétences et vos besoins.", + icon: iconSearch, + hasCircleBg: false // L'icône est brute, on lui applique le cercle CSS + }, + { + step: "02", + title: "Structurer", + description: "Construire une trajectoire réaliste, progressive et durable.", + icon: iconUser, + hasCircleBg: false + }, + { + step: "03", + title: "Expérimenter", + description: "Développer des compétences à travers des projets réels.", + icon: iconWrench, + hasCircleBg: true // Frame 715 contient déjà son cercle de fond + }, + { + step: "04", + title: "Développer", + description: "Renforcer son autonomie, ses capacités d'action et son leadership.", + icon: iconPlant, + hasCircleBg: false + }, + { + step: "05", + title: "Connecter", + description: "S'inscrire dans un écosystème bienveillant et activer son réseau.", + icon: iconElectrical, + hasCircleBg: false + }, + { + step: "06", + title: "Évoluer", + description: "Mesurer l'impact de sa transition et pérenniser son parcours.", + icon: iconCycle, + hasCircleBg: true // Frame 719 contient déjà son cercle de fond + } +]; + +export default function MethodologieEtapes() { + return ( +
+
+
+ {ETAPES_DATA.map((item) => ( +
+ + {/* Conteneur cercle + badge numéro */} +
+
+ {item.title} +
+ {item.step} +
+ + {/* Titre et description */} +

{item.title}

+

{item.description}

+ +
+ ))} +
+
+
+ ); +} \ No newline at end of file diff --git a/assets/img/Electrical.png b/assets/img/Electrical.png new file mode 100644 index 0000000..3571c60 Binary files /dev/null and b/assets/img/Electrical.png differ diff --git a/assets/img/Frame 715.png b/assets/img/Frame 715.png new file mode 100644 index 0000000..7e2119d Binary files /dev/null and b/assets/img/Frame 715.png differ diff --git a/assets/img/Frame 719.png b/assets/img/Frame 719.png new file mode 100644 index 0000000..22355fa Binary files /dev/null and b/assets/img/Frame 719.png differ diff --git a/assets/img/Search.png b/assets/img/Search.png new file mode 100644 index 0000000..ddc0128 Binary files /dev/null and b/assets/img/Search.png differ diff --git a/assets/img/Tree Planting.png b/assets/img/Tree Planting.png new file mode 100644 index 0000000..8cf31e9 Binary files /dev/null and b/assets/img/Tree Planting.png differ diff --git a/assets/img/User Account.png b/assets/img/User Account.png new file mode 100644 index 0000000..ef23d84 Binary files /dev/null and b/assets/img/User Account.png differ diff --git a/assets/img/bureau.png b/assets/img/bureau.png new file mode 100644 index 0000000..9bc77f1 Binary files /dev/null and b/assets/img/bureau.png differ diff --git a/assets/img/human-model-banner.png b/assets/img/human-model-banner.png new file mode 100644 index 0000000..2d22395 Binary files /dev/null and b/assets/img/human-model-banner.png differ diff --git a/assets/img/img-traject-banner.png b/assets/img/img-traject-banner.png new file mode 100644 index 0000000..9cd36f7 Binary files /dev/null and b/assets/img/img-traject-banner.png differ diff --git a/assets/img/learning-by-doing.png b/assets/img/learning-by-doing.png new file mode 100644 index 0000000..2590fd3 Binary files /dev/null and b/assets/img/learning-by-doing.png differ diff --git a/assets/img/route.png b/assets/img/route.png new file mode 100644 index 0000000..0fc31ea Binary files /dev/null and b/assets/img/route.png differ diff --git a/assets/styles/competences-evoluer.css b/assets/styles/competences-evoluer.css new file mode 100644 index 0000000..0f88804 --- /dev/null +++ b/assets/styles/competences-evoluer.css @@ -0,0 +1,102 @@ +/* ========================================================================== + SECTION COMPÉTENCES POUR ÉVOLUER (FIGMA) + ========================================================================== */ + +.competences-section { + width: 100%; + background-color: #F4F1EA; + /* Fond beige Figma */ + padding: 5rem 2rem 6rem 2rem; + box-sizing: border-box; +} + +.competences-container { + max-width: 1140px; + margin: 0 auto; +} + +/* Trait vert olive */ +.competences-green-line { + width: 48px; + height: 4px; + background-color: #556B2F; + border-radius: 2px; + margin-bottom: 0.75rem; +} + +/* Surtitre */ +.competences-tag-top { + display: block; + font-size: 0.95rem; + font-weight: 600; + color: #7b8337; + margin-bottom: 0.6rem; +} + +/* Titre principal */ +.competences-main-title { + font-size: 2.25rem; + font-weight: 800; + color: #0f172a; + letter-spacing: -0.02em; + margin: 0 0 3rem 0; + line-height: 1.25; +} + +/* Grille de 3 cartes */ +.competences-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 2rem; +} + +/* Carte blanche */ +.competence-card { + background-color: #ffffff; + border-radius: 14px; + padding: 2.25rem 2rem; + min-height: 220px; + box-sizing: border-box; + box-shadow: 0 4px 14px rgba(0, 0, 0, 0.03); + display: flex; + flex-direction: column; +} + +.competence-card-title { + font-size: 1.05rem; + font-weight: 700; + color: #111827; + margin: 0 0 1.25rem 0; + line-height: 1.35; +} + +.competence-card-intro { + font-size: 0.84rem; + color: #4b5563; + margin: 0 0 0.5rem 0; + line-height: 1.5; +} + +.competence-card-text { + font-size: 0.84rem; + line-height: 1.6; + color: #4b5563; + margin: 0; +} + +/* Responsive */ +@media (max-width: 900px) { + .competences-grid { + grid-template-columns: 1fr; + gap: 1.5rem; + } + + .competences-section { + padding: 3.5rem 1.25rem 4rem 1.25rem; + } + + .competences-main-title { + font-size: 1.8rem; + margin-bottom: 2rem; + } +} \ No newline at end of file diff --git a/assets/styles/exemples-projets.css b/assets/styles/exemples-projets.css new file mode 100644 index 0000000..be35a37 --- /dev/null +++ b/assets/styles/exemples-projets.css @@ -0,0 +1,107 @@ +/* ========================================================================== + SECTION EXEMPLES DE PROJETS (FIGMA) + ========================================================================== */ + +.projets-section { + width: 100%; + background-color: #ffffff; + padding: 1rem 2rem 5rem 2rem; + box-sizing: border-box; +} + +.projets-container { + max-width: 1140px; + margin: 0 auto; +} + +/* Surtitre vert olive */ +.projets-tag-top { + display: block; + font-size: 0.95rem; + font-weight: 600; + color: #7b8337; + margin-bottom: 2rem; +} + +/* Grille 3 colonnes x 2 lignes */ +.projets-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 1.5rem; + margin-bottom: 2.5rem; +} + +/* Carte blanche avec bordure grise douce */ +.projet-card { + background-color: #ffffff; + border: 1px solid #d1d5db; + border-radius: 14px; + padding: 1.75rem 1.5rem; + min-height: 125px; + display: flex; + flex-direction: column; + justify-content: flex-start; + box-sizing: border-box; + transition: transform 0.2s ease, border-color 0.2s ease; +} + +.projet-card:hover { + transform: translateY(-2px); + border-color: #8c8f3e; +} + +.projet-card-title { + font-size: 1rem; + font-weight: 700; + color: #0f172a; + margin: 0 0 0.75rem 0; + line-height: 1.3; +} + +.projet-card-desc { + font-size: 0.82rem; + line-height: 1.5; + color: #4b5563; + margin: 0; +} + +/* Alignement du bouton à gauche comme sur la maquette */ +.projets-action { + display: flex; + justify-content: flex-start; +} + +.btn-decouvrir-projets { + background-color: #7b8337; + color: #ffffff; + font-size: 0.85rem; + font-weight: 600; + padding: 0.55rem 1.6rem; + border-radius: 9999px; + text-decoration: none; + display: inline-block; + transition: background-color 0.2s ease, transform 0.15s ease; +} + +.btn-decouvrir-projets:hover { + background-color: #6a712f; + transform: translateY(-1px); +} + +/* Responsive */ +@media (max-width: 900px) { + .projets-grid { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (max-width: 600px) { + .projets-grid { + grid-template-columns: 1fr; + gap: 1rem; + } + + .projets-section { + padding: 1rem 1.25rem 3.5rem 1.25rem; + } +} \ No newline at end of file diff --git a/assets/styles/human-employment.css b/assets/styles/human-employment.css new file mode 100644 index 0000000..e47a1c2 --- /dev/null +++ b/assets/styles/human-employment.css @@ -0,0 +1,114 @@ +/* ========================================================================== + SECTION HUMAN EMPLOYMENT MODEL (FIGMA) + ========================================================================== */ + +.hem-wrapper { + width: 100%; + background-color: #ffffff; + padding: 1rem 2rem 5rem 2rem; + box-sizing: border-box; +} + +.hem-inner { + max-width: 1240px; + margin: 0 auto; + display: flex; + flex-direction: column; +} + +/* Texte d'intro gris */ +.hem-description { + font-size: 0.85rem; + line-height: 1.55; + color: #6b7280; + max-width: 780px; + margin: 0 0 2.5rem 0; +} + +/* Grille 4 colonnes alignées */ +.hem-cards-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 1.5rem; + width: 100%; + margin-bottom: 3.5rem; + box-sizing: border-box; +} + +/* Chaque carte beige */ +.hem-card { + background-color: #F4F1EA; + border-radius: 12px; + padding: 1.75rem 1.4rem; + box-sizing: border-box; + min-height: 160px; +} + +.hem-card-title { + font-size: 0.95rem; + font-weight: 700; + color: #4B6A4A; + margin: 0 0 1rem 0; +} + +.hem-card-list { + list-style: none; + padding: 0; + margin: 0; + display: flex; + flex-direction: column; + gap: 0.35rem; +} + +.hem-card-list li { + font-size: 0.8rem; + color: #9A9595; + line-height: 1.45; +} + +/* Phrase centrale */ +.hem-phrase { + text-align: center; + font-size: 0.95rem; + color: #111827; + margin: 0 0 2rem 0; +} + +.hem-phrase strong { + font-weight: 700; +} + +/* Image arrondie */ +.hem-banner-container { + width: 100%; + max-width: 1000px; + margin: 0 auto; + border-radius: 20px; + overflow: hidden; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); +} + +.hem-banner-img { + width: 100%; + height: 480px; + object-fit: cover; + display: block; +} + +/* Responsive : passage en 2 colonnes uniquement sur smartphone / écran très étroit */ +@media (max-width: 720px) { + .hem-cards-grid { + grid-template-columns: repeat(2, 1fr); + gap: 1rem; + } + + .hem-banner-img { + height: 280px; + } +} + +@media (max-width: 480px) { + .hem-cards-grid { + grid-template-columns: 1fr; + } +} \ No newline at end of file diff --git a/assets/styles/learning-by-doing.css b/assets/styles/learning-by-doing.css new file mode 100644 index 0000000..f65041f --- /dev/null +++ b/assets/styles/learning-by-doing.css @@ -0,0 +1,92 @@ +/* ========================================================================== + SECTION LEARNING BY DOING (FIGMA) + ========================================================================== */ + +.lbd-section { + width: 100%; + background-color: #ffffff; + padding: 5rem 2rem 6rem 2rem; + box-sizing: border-box; +} + +.lbd-container { + max-width: 1140px; + margin: 0 auto; +} + +/* Ligne verte d'accentuation en haut */ +.lbd-green-line { + width: 48px; + height: 4px; + background-color: #556B2F; + border-radius: 2px; + margin-bottom: 0.75rem; +} + +/* Surtitre */ +.lbd-tag-top { + display: block; + font-size: 0.95rem; + font-weight: 600; + color: #7b8337; + margin-bottom: 0.6rem; +} + +/* Titre principal */ +.lbd-main-title { + font-size: 2.25rem; + font-weight: 800; + color: #0f172a; + letter-spacing: -0.02em; + margin: 0 0 1.25rem 0; + line-height: 1.25; +} + +/* Paragraphe */ +.lbd-description { + font-size: 0.86rem; + line-height: 1.6; + color: #4b5563; + max-width: 820px; + margin: 0 0 3rem 0; +} + +/* Conteneur de la bannière avec coins arrondis */ +.lbd-image-wrapper { + width: 100%; + border-radius: 20px; + overflow: hidden; + box-shadow: 0 6px 24px rgba(0, 0, 0, 0.08); +} + +.lbd-banner-img { + width: 100%; + height: 440px; + object-fit: cover; + display: block; +} + +/* Responsive */ +@media (max-width: 900px) { + .lbd-main-title { + font-size: 1.85rem; + } + + .lbd-banner-img { + height: 320px; + } +} + +@media (max-width: 640px) { + .lbd-section { + padding: 3.5rem 1.25rem 4rem 1.25rem; + } + + .lbd-main-title { + font-size: 1.55rem; + } + + .lbd-banner-img { + height: 220px; + } +} \ No newline at end of file diff --git a/assets/styles/methodologie-etapes.css b/assets/styles/methodologie-etapes.css new file mode 100644 index 0000000..1a98ec5 --- /dev/null +++ b/assets/styles/methodologie-etapes.css @@ -0,0 +1,106 @@ +/* ========================================================================== + SECTION MÉTHODOLOGIE EN 6 ÉTAPES (FIGMA) + ========================================================================== */ + +.etapes-section { + width: 100%; + background-color: #ffffff; + padding: 4rem 2rem 6rem 2rem; + box-sizing: border-box; +} + +.etapes-container { + max-width: 1140px; + margin: 0 auto; +} + +/* Grille 3 colonnes x 2 lignes */ +.etapes-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + row-gap: 4rem; + column-gap: 3rem; + justify-items: center; +} + +/* Bloc d'une étape */ +.etape-item { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + max-width: 280px; +} + +/* Cercle beige avec liseré */ +.etape-circle-wrapper { + position: relative; + width: 104px; + height: 104px; + margin-bottom: 1.5rem; +} + +.etape-circle { + width: 100%; + height: 100%; + background-color: #F4F1EA; + border: 1.5px solid #d5dec3; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + box-shadow: 0 4px 14px rgba(0, 0, 0, 0.03); +} + +/* Badge vert foncé avec numéro */ +.etape-badge { + position: absolute; + top: -2px; + right: -2px; + background-color: #435227; + color: #ffffff; + font-size: 0.72rem; + font-weight: 700; + width: 26px; + height: 26px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + border: 2px solid #ffffff; +} + +/* Textes */ +.etape-title { + font-size: 1.15rem; + font-weight: 700; + color: #111827; + margin: 0 0 0.6rem 0; +} + +.etape-desc { + font-size: 0.82rem; + line-height: 1.5; + color: #6b7280; + margin: 0; +} + +/* Responsive */ +@media (max-width: 900px) { + .etapes-grid { + grid-template-columns: repeat(2, 1fr); + row-gap: 3rem; + column-gap: 2rem; + } +} + +@media (max-width: 580px) { + .etapes-grid { + grid-template-columns: 1fr; + row-gap: 2.5rem; + } + + .etapes-section { + padding: 3rem 1.5rem 4rem 1.5rem; + } +} \ No newline at end of file diff --git a/assets/styles/trajectoire.css b/assets/styles/trajectoire.css new file mode 100644 index 0000000..e3d60a0 --- /dev/null +++ b/assets/styles/trajectoire.css @@ -0,0 +1,281 @@ +/* ========================================================================== + PAGE CONSTRUIRE SA TRAJECTOIRE - GAEA21 (FIGMA) + ========================================================================== */ + +/* -------------------------------------------------------------------------- + 1. SECTION HERO BANNER + -------------------------------------------------------------------------- */ +.trajectoire-hero { + position: relative; + width: 100%; + min-height: 85vh; + background-size: cover; + background-position: center top; + background-repeat: no-repeat; + display: flex; + align-items: center; + box-sizing: border-box; + color: #ffffff; + overflow: hidden; + padding-top: 80px; +} + +/* + Overlay assombrissant : + Dégradé plus dense à gauche pour détacher le texte blanc, + plus transparent vers la droite pour révéler la personne et l'ordinateur. +*/ +.trajectoire-overlay { + position: absolute; + inset: 0; + background: linear-gradient(90deg, + rgba(10, 20, 25, 0.78) 0%, + rgba(15, 25, 30, 0.55) 45%, + rgba(10, 20, 25, 0.25) 100%); + z-index: 1; + pointer-events: none; +} + +/* -------------------------------------------------------------------------- + 2. NAVBAR TRANSPARENTE EN HAUT DU HERO (Optionnel si intégrée) + -------------------------------------------------------------------------- */ +.trajectoire-header { + position: relative; + z-index: 10; + width: 100%; + max-width: 1440px; + margin: 0 auto; + padding: 1.75rem 3rem; + display: flex; + align-items: center; + justify-content: space-between; + box-sizing: border-box; +} + +.trajectoire-logo img { + height: 44px; + width: auto; + display: block; + object-fit: contain; +} + +.trajectoire-nav-links { + display: flex; + align-items: center; + gap: 2.5rem; + list-style: none; + margin: 0; + padding: 0; +} + +.trajectoire-nav-links li a { + color: #ffffff; + text-decoration: none; + font-size: 0.95rem; + font-weight: 500; + opacity: 0.9; + transition: opacity 0.2s ease, color 0.2s ease; +} + +.trajectoire-nav-links li a:hover { + opacity: 1; + color: #c7d264; +} + +/* Bouton « Participer » */ +.btn-participer-trajectoire { + background-color: #8c8f3e; + color: #ffffff; + padding: 0.6rem 1.6rem; + border-radius: 9999px; + font-size: 0.9rem; + font-weight: 600; + text-decoration: none; + display: inline-block; + transition: background-color 0.2s ease, transform 0.15s ease; +} + +.btn-participer-trajectoire:hover { + background-color: #737630; + transform: translateY(-1px); +} + +/* -------------------------------------------------------------------------- + 3. CONTENU TEXTE DU HERO (GAUCHE) + -------------------------------------------------------------------------- */ +.trajectoire-hero-content { + position: relative; + z-index: 10; + max-width: 1440px; + width: 100%; + margin: 0 auto; + padding: 3rem 4rem; + box-sizing: border-box; +} + +.trajectoire-text-wrapper { + max-width: 580px; +} + +.trajectoire-title { + font-size: 3rem; + font-weight: 800; + line-height: 1.15; + color: #ffffff; + margin-bottom: 1.5rem; + letter-spacing: -0.02em; +} + +.trajectoire-paragraphs { + display: flex; + flex-direction: column; + gap: 0.75rem; + margin-bottom: 2.25rem; +} + +.trajectoire-paragraphs p { + font-size: 0.88rem; + line-height: 1.55; + color: rgba(255, 255, 255, 0.9); + margin: 0; + font-weight: 400; +} + +/* Groupe de boutons d'action Hero */ +.trajectoire-cta-group { + display: flex; + align-items: center; + gap: 1rem; + flex-wrap: wrap; +} + +.btn-trajectoire-primary { + background-color: #8c8f3e; + color: #ffffff; + font-size: 0.88rem; + font-weight: 600; + padding: 0.75rem 1.75rem; + border-radius: 9999px; + text-decoration: none; + transition: all 0.2s ease; + box-shadow: 0 4px 14px rgba(0, 0, 0, 0.2); +} + +.btn-trajectoire-primary:hover { + background-color: #737630; + transform: translateY(-2px); +} + +.btn-trajectoire-secondary { + background-color: transparent; + color: #ffffff; + font-size: 0.88rem; + font-weight: 600; + padding: 0.72rem 1.75rem; + border-radius: 9999px; + border: 1.5px solid rgba(255, 255, 255, 0.85); + text-decoration: none; + transition: all 0.2s ease; +} + +.btn-trajectoire-secondary:hover { + background-color: rgba(255, 255, 255, 0.15); + border-color: #ffffff; +} + +/* -------------------------------------------------------------------------- + 4. SECTION SUIVANTE : QUESTIONNAIRE INTRO (#F4F1EA) + -------------------------------------------------------------------------- */ +.trajectoire-intro-questions { + background-color: #F4F1EA; + padding: 6rem 1.5rem; + display: flex; + justify-content: center; + align-items: center; + text-align: center; + box-sizing: border-box; + width: 100%; +} + +.trajectoire-questions-container { + max-width: 800px; + margin: 0 auto; + display: flex; + flex-direction: column; + align-items: center; +} + +.trajectoire-subtitle-green { + color: #7b8337; + font-size: 0.95rem; + font-weight: 600; + letter-spacing: -0.01em; + margin-bottom: 1.25rem; + display: inline-block; +} + +.trajectoire-heading-black { + color: #000000; + font-size: 2.25rem; + font-weight: 800; + line-height: 1.2; + letter-spacing: -0.02em; + margin: 0 0 2rem 0; +} + +.trajectoire-action-wrapper { + display: flex; + justify-content: center; +} + +/* Bouton vert olive ovale "Commencer" */ +.btn-trajectoire-commencer { + background-color: #7b8337; + color: #ffffff; + font-size: 0.85rem; + font-weight: 600; + padding: 0.55rem 1.6rem; + border-radius: 9999px; + text-decoration: none; + display: inline-flex; + align-items: center; + justify-content: center; + transition: background-color 0.2s ease, transform 0.15s ease; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08); +} + +.btn-trajectoire-commencer:hover { + background-color: #6a712f; + transform: translateY(-1px); +} + +/* -------------------------------------------------------------------------- + 5. RESPONSIVE + -------------------------------------------------------------------------- */ +@media (max-width: 900px) { + .trajectoire-header { + padding: 1.25rem 1.5rem; + } + + .trajectoire-nav-links { + display: none; + } + + .trajectoire-hero-content { + padding: 3rem 1.5rem 4rem 1.5rem; + } + + .trajectoire-title { + font-size: 2.2rem; + } +} + +@media (max-width: 640px) { + .trajectoire-intro-questions { + padding: 4rem 1.25rem; + } + + .trajectoire-heading-black { + font-size: 1.75rem; + } +} \ No newline at end of file diff --git a/assets/styles/trajectoires-cards.css b/assets/styles/trajectoires-cards.css new file mode 100644 index 0000000..e6a44a5 --- /dev/null +++ b/assets/styles/trajectoires-cards.css @@ -0,0 +1,183 @@ +/* ========================================================================== + SECTION 8 TRAJECTOIRES (FIGMA) + ========================================================================== */ + +.trajectoires-section { + background-color: #ffffff; + padding: 5rem 2rem 6rem 2rem; + box-sizing: border-box; + width: 100%; +} + +.trajectoires-container { + max-width: 1320px; + margin: 0 auto; +} + +/* En-tête */ +.trajectoires-header { + margin-bottom: 3.5rem; +} + +/* Le trait vert unique */ +.trajectoires-green-line { + width: 48px; + height: 4px; + background-color: #556B2F; + border-radius: 2px; + margin-bottom: 0.75rem; +} + +/* Titre "Les Trajectoires" */ +.trajectoires-tag-top { + display: block; + font-size: 0.95rem; + font-weight: 600; + color: #111827; + margin-bottom: 0.6rem; + text-transform: capitalize; +} + +.trajectoires-main-title { + font-size: 2.25rem; + font-weight: 800; + color: #0f172a; + letter-spacing: -0.02em; + margin: 0; +} + +/* Grille responsive : 3 colonnes sur desktop, 2 sur tablette, 1 sur mobile */ +.trajectoires-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 2rem; +} + +/* Style de chaque carte individuelle */ +.trajectoire-card { + background-color: #F4F1EA; + /* Teinte beige Figma */ + border-radius: 14px; + padding: 2.25rem 2rem 2rem 2rem; + display: flex; + flex-direction: column; + justify-content: space-between; + transition: transform 0.2s ease, box-shadow 0.2s ease; + box-sizing: border-box; +} + +.trajectoire-card:hover { + transform: translateY(-3px); + box-shadow: 0 10px 24px rgba(0, 0, 0, 0.06); +} + +/* Badge supérieur (carré couleur + label) */ +.trajectoire-card-top { + display: flex; + align-items: center; + gap: 0.75rem; + margin-bottom: 1.5rem; +} + +.trajectoire-badge-indicator { + width: 14px; + height: 14px; + border-radius: 3px; + flex-shrink: 0; +} + +.trajectoire-badge-label { + font-size: 0.8rem; + font-weight: 600; + color: #374151; + line-height: 1.3; +} + +/* Corps de carte */ +.trajectoire-card-body { + flex-grow: 1; +} + +.trajectoire-card-title { + font-size: 1.05rem; + font-weight: 700; + color: #111827; + line-height: 1.35; + margin: 0 0 1rem 0; +} + +.trajectoire-card-desc { + font-size: 0.85rem; + line-height: 1.5; + color: #4b5563; + margin: 0 0 1.25rem 0; +} + +.trajectoire-card-list { + list-style: none; + padding: 0; + margin: 0 0 2rem 0; + display: flex; + flex-direction: column; + gap: 0.55rem; +} + +.trajectoire-card-list li { + font-size: 0.82rem; + color: #4b5563; + line-height: 1.45; + position: relative; + padding-left: 1rem; +} + +.trajectoire-card-list li::before { + content: "•"; + position: absolute; + left: 0; + color: #6b7280; + font-weight: bold; +} + +/* Bouton Découvrir */ +.trajectoire-card-footer { + margin-top: auto; +} + +.btn-card-decouvrir { + background-color: #7b8337; + color: #ffffff; + font-size: 0.82rem; + font-weight: 600; + padding: 0.5rem 1.4rem; + border-radius: 9999px; + text-decoration: none; + display: inline-block; + transition: background-color 0.2s ease, transform 0.15s ease; +} + +.btn-card-decouvrir:hover { + background-color: #6a712f; + transform: translateY(-1px); +} + +/* Responsive */ +@media (max-width: 1080px) { + .trajectoires-grid { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (max-width: 680px) { + .trajectoires-section { + padding: 3.5rem 1.25rem; + } + + .trajectoires-main-title { + font-size: 1.8rem; + } + + .trajectoires-grid { + grid-template-columns: 1fr; + gap: 1.5rem; + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 700cf21..aa0f1c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,8 @@ "license": "UNLICENSED", "dependencies": { "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "react-router-dom": "^7.18.4" }, "devDependencies": { "@babel/core": "^7.24.0", @@ -3040,6 +3041,19 @@ "dev": true, "license": "MIT" }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/core-js": { "version": "3.50.0", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.50.0.tgz", @@ -5684,6 +5698,44 @@ "react": "^18.3.1" } }, + "node_modules/react-router": { + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.18.4.tgz", + "integrity": "sha512-PUPQcMhMGRAslLcvtlPz/kmzBEWPhLdgLFrL7pLNepBL6dX0lWj4WD2cUYVgYCuT3jxvghYFg81cDTj44DhetQ==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.18.4.tgz", + "integrity": "sha512-yrfmJHIpDG7taCpqKjT1G5B6q3O2K+RN8/fgNf0lTjCwiPbQ0ei6vXX9ZjQR+7ld8Tr7Z5xmyMnZ8YJrphWQUw==", + "license": "MIT", + "dependencies": { + "react-router": "7.18.4" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/read-cache": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.2.tgz", @@ -6003,6 +6055,12 @@ "randombytes": "^2.1.0" } }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, "node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", diff --git a/package.json b/package.json index a88415b..aa5407a 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ }, "dependencies": { "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "react-router-dom": "^7.18.4" } } diff --git a/src/Controller/HomeController.php b/src/Controller/HomeController.php index 26d86c1..6bb9487 100644 --- a/src/Controller/HomeController.php +++ b/src/Controller/HomeController.php @@ -8,7 +8,7 @@ use Symfony\Component\Routing\Attribute\Route; class HomeController extends AbstractController { - #[Route('/', name: 'app_home')] + #[Route('/{reactRouting}', name: 'app_home', requirements: ['reactRouting' => '^(?!api|_wdt|_profiler).+'], defaults: ['reactRouting' => null])] public function index(): Response { return $this->render('home/index.html.twig');