diff --git a/CV.pdf b/CV.pdf new file mode 100644 index 0000000..6ac4392 Binary files /dev/null and b/CV.pdf differ diff --git a/counter.js b/counter.js new file mode 100644 index 0000000..881e2d7 --- /dev/null +++ b/counter.js @@ -0,0 +1,9 @@ +export function setupCounter(element) { + let counter = 0 + const setCounter = (count) => { + counter = count + element.innerHTML = `count is ${counter}` + } + element.addEventListener('click', () => setCounter(counter + 1)) + setCounter(0) +} diff --git a/img/Verax.png b/img/Verax.png new file mode 100644 index 0000000..d443837 Binary files /dev/null and b/img/Verax.png differ diff --git a/img/cochons-aigris.png b/img/cochons-aigris.png new file mode 100644 index 0000000..bad668c Binary files /dev/null and b/img/cochons-aigris.png differ diff --git a/img/comics.jpg b/img/comics.jpg new file mode 100644 index 0000000..5115166 Binary files /dev/null and b/img/comics.jpg differ diff --git a/img/data-science.png b/img/data-science.png new file mode 100644 index 0000000..8653f2b Binary files /dev/null and b/img/data-science.png differ diff --git a/img/edutiles.png b/img/edutiles.png new file mode 100644 index 0000000..f573ba7 Binary files /dev/null and b/img/edutiles.png differ diff --git a/img/excel.png b/img/excel.png new file mode 100644 index 0000000..ee3cffd Binary files /dev/null and b/img/excel.png differ diff --git a/img/noa-photo-profil.png b/img/noa-photo-profil.png new file mode 100644 index 0000000..252782c Binary files /dev/null and b/img/noa-photo-profil.png differ diff --git a/img/stormy.png b/img/stormy.png new file mode 100644 index 0000000..e80d022 Binary files /dev/null and b/img/stormy.png differ diff --git a/index.html b/index.html index 287b0fc..1f16701 100644 --- a/index.html +++ b/index.html @@ -1,34 +1,38 @@ - - + + - portfolio3a - One incredible styled html page - + + + + + Noa Sillard - Portfolio + + + + + + + + + + + + - - - - - - -

portfolio3a is my first page, and it has got style!

- -

Welcome on this template html/css project - -

Very simple, some links, some menu... make it your own -… - -

I have nothing more to say - - -

Template made in 2022
- with Code#0 Code#0 -
- +
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/js/include.js b/js/include.js new file mode 100644 index 0000000..877293a --- /dev/null +++ b/js/include.js @@ -0,0 +1,34 @@ +// Fonction pour charger le contenu HTML +async function loadHTML(url, containerId) { + try { + const response = await fetch(url); + if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); + const html = await response.text(); + document.getElementById(containerId).innerHTML = html; + } catch (error) { + console.error('Error loading HTML:', error); + } +} + +// Chargement des sections +document.addEventListener('DOMContentLoaded', async () => { + const sections = [ + { url: 'sections/header.html', id: 'header-container' }, + { url: 'sections/about.html', id: 'about-container' }, + { url: 'sections/skills.html', id: 'skills-container' }, + { url: 'sections/formation.html', id: 'formation-container' }, + { url: 'sections/experience.html', id: 'experience-container' }, + { url: 'sections/projects.html', id: 'projects-container' }, + { url: 'sections/testimonials.html', id: 'testimonials-container' }, + { url: 'sections/footer.html', id: 'footer-container' } + ]; + + // Chargement parallèle des sections + await Promise.all(sections.map(section => + loadHTML(section.url, section.id) + )); + + // Initialisation des scripts après le chargement du contenu + const event = new Event('sectionsLoaded'); + document.dispatchEvent(event); +}); \ No newline at end of file diff --git a/js/main.js b/js/main.js new file mode 100644 index 0000000..486dd38 --- /dev/null +++ b/js/main.js @@ -0,0 +1,311 @@ +// Attendre que les sections soient chargées +document.addEventListener('sectionsLoaded', () => { + // Données des projets + const projectData = { + 6: { + title: "Transformation de photos en style 'Comics'", + description: `Ce projet a pour but de transformer une photo classique en un effet "Comics". Grâce à une série de traitements d'image, nous appliquons des + techniques de détection de contours, de réduction de couleurs et d'effets visuels pour obtenir une image stylisée qui imite l'apparence des dessins animés ou des bandes dessinées. + + • Fonctionnalités principales : + • Transformation en niveaux de gris : + La conversion de l'image en noir et blanc permet de simplifier la détection des contours et d'éliminer les couleurs inutiles. + • Détection des contours : Utilisation du filtre de Sobel pour détecter les bords et renforcer le contraste entre les éléments importants de l'image. + • Réduction des couleurs : Utilisation du K-means pour réduire le nombre de couleurs de l'image, afin de créer un effet visuel "plat" et simplifié comme dans une BD. + • Fusion des contours et des couleurs réduites : Les contours noirs sont superposés à l'image réduite en couleurs pour obtenir l'effet final. +`, + image: "https://via.placeholder.com/800x400", + tags: ["Python", "Numpy", "Scipy","Sklearn","Matplotlib"], + link: "#" + }, + 5: { + title: "IA supervisée - Prédiction du prix de l'immobilier", + description: `Projet visant à comparer plusieurs modèles sur la prédiction des prix de l'immobilier et fonction d'une surface et d'un lieu + + • Projet universitaire réalisé seul - 2025 (7 jours) + • L'application permet d'entraîner ces modèles sur l'historiques des transactions immobilière en France et d'estimer la valeur foncière d'un bien en fonction de sa localisation et de sa surface. + • Le programme: + • Charge et prépare les données. + • Entraîne les modèles de régression. + • Demande à l'utilisateur des informations sur le bien immobilier. + • Prédit le prix du bien à l'aide des modèles entraînés. + • Modèles Implémentés: + • Régression Linéaire + • Random Forest + • LightGBM`, + image: "https://via.placeholder.com/800x400", + tags: ["Python", "Numpy", "Matplotlib", "Scikit-learn","Pandas","Lightgbm"], + link: "#" + }, + 4: { + title: "Jeu 3D - Angry bird inversé, les cochons contre attaquent", + description: `Revisite du jeu Angry Bird dans lequel ce sont les cochons qui attaquent les oiseaux. Ce dernier a la particularité d'être réalisé en 3 dimensions. Caractéristiques principales : + + • Projet universitaire en autonomie - 2025 (110 heures) + • Travail dans une équipe de 4 personnes`, + image: "https://via.placeholder.com/800x400", + tags: ["Three.JS", "Javascript", "HTML", "CSS"], + link: "#" + }, + 3: { + title: "Applications web et mobile de lutte contre la désinformation", + description: `Une plateforme de commerce électronique complète offrant une expérience d'achat fluide et sécurisée. Caractéristiques principales : + + • Projet universitaire en autonomie - 2024 (200 heures) + • Travail dans une équipe de 5 personnes`, + image: "https://via.placeholder.com/800x400", + tags: ["PHP", "Java", "Kotlin", "SQL", "Docker", "HTML", "CSS"], + link: "#" + }, + 2: { + title: "Jeu de dominos (fractions) éducative", + description: `Jeu de domino dans lequel les chiffres sont remplacés par des fractions. Fonctionnalités : + + • Projet universitaire en autonomie - 2023 (170 heures)`, + image: "https://via.placeholder.com/800x400", + tags: ["Javascript", "NodeJs", "socket.io", "HTML", "CSS"], + link: "#" + }, + 1: { + title: "pplication d'organisation pour les étudiants", + description: `Application web permettant de s'organiser au mieux dans notre quotidien. Caractéristiques : + + • Projet universitaire en autonomie - 2022 (180 heures)`, + image: "https://via.placeholder.com/800x400", + tags: ["NodeJs", "TypeScript", "HTML", "CSS"], + link: "#" + } + }; + + // Données des expériences + const experienceData = { + 3: { + date: "2024 - Présent", + title: "Alternant développeur web", + company: "Coqpit, Clermont-Ferrand", + description: `

J'ai créé des sites webs en autonomie, en gérant le développement ainsi que le suivi du projet avec les clients.

+

Caractéristiques principales :

+ `, + skills: ["Wordpress", "ACF Pro", "HTML", "SCSS", "JS", "PHP"], + }, + 2: { + date: "2024 (10 semaines)", + title: "Stage en développement web (full stack) en entreprise", + company: "Open Studio, Clermont-Ferrand", + description: `

J'ai développé un module du CMS open source Thelia et automatisé la génération de la documentation du CMS

+

Caractéristiques principales :

+ `, + skills: ["Javascript", "PHP 8.3", "Symfony 6", "Propel", "Smarty", "Python"], + }, + 1: { + date: "2023 (10 semaines)", + title: "Stage en dévelopment web (full stack) en entreprise", + company: "Code Rhapsody, Lyon", + description: `

J'ai participé au développement d'une application interne de gestion des temps et de facturation automatisée

+

Caractéristiques principales :

+ `, + skills: ["Javascript", "PHP 8.2", "Symfony 6", "Doctrine", "Twig"], + } + }; + + // Mobile menu + const mobileMenuBtn = document.querySelector('.mobile-menu-btn'); + const navLinks = document.querySelector('.nav-links'); + + if (mobileMenuBtn && navLinks) { + mobileMenuBtn.addEventListener('click', () => { + mobileMenuBtn.classList.toggle('active'); + navLinks.classList.toggle('active'); + }); + + // Close menu when clicking on a link + navLinks.querySelectorAll('a').forEach(link => { + link.addEventListener('click', () => { + mobileMenuBtn.classList.remove('active'); + navLinks.classList.remove('active'); + }); + }); + } + + // Modal expérience + const experienceModal = document.getElementById('experienceModal'); + if (experienceModal) { + const modalDate = experienceModal.querySelector('.modal-date'); + const modalTitle = experienceModal.querySelector('.modal-title'); + const modalCompany = experienceModal.querySelector('.modal-company'); + const modalDescription = experienceModal.querySelector('.modal-description'); + const modalSkills = experienceModal.querySelector('.modal-skills'); + const modalAchievements = experienceModal.querySelector('.modal-achievements'); + const modalClose = experienceModal.querySelector('.modal-close'); + + // Ouvrir la modal + document.querySelectorAll('.experience-card').forEach(card => { + card.addEventListener('click', () => { + const experienceId = card.dataset.experience; + const experience = experienceData[experienceId]; + + modalDate.textContent = experience.date; + modalTitle.textContent = experience.title; + modalCompany.textContent = experience.company; + modalDescription.innerHTML = experience.description; + modalSkills.innerHTML = experience.skills + .map(skill => `${skill}`) + .join(''); + modalAchievements.innerHTML = experience.achievements; + + experienceModal.style.display = 'block'; + document.body.style.overflow = 'hidden'; + }); + }); + + // Fermer la modal + modalClose.addEventListener('click', () => { + experienceModal.style.display = 'none'; + document.body.style.overflow = 'auto'; + }); + + window.addEventListener('click', (e) => { + if (e.target === experienceModal) { + experienceModal.style.display = 'none'; + document.body.style.overflow = 'auto'; + } + }); + } + + // Modal projet + const projectModal = document.getElementById('projectModal'); + if (projectModal) { + const modalImage = projectModal.querySelector('.modal-image'); + const modalTitle = projectModal.querySelector('.modal-title'); + const modalDescription = projectModal.querySelector('.modal-description'); + const modalTags = projectModal.querySelector('.modal-tags'); + const modalLink = projectModal.querySelector('.modal-link'); + const modalClose = projectModal.querySelector('.modal-close'); + + // Ouvrir la modal + document.querySelectorAll('.project-card .btn-primary').forEach(button => { + button.addEventListener('click', (e) => { + e.preventDefault(); + e.stopPropagation(); + const card = button.closest('.project-card'); + const projectId = card.dataset.project; + const project = projectData[projectId]; + + modalImage.src = project.image; + modalImage.alt = project.title; + modalTitle.textContent = project.title; + modalDescription.innerHTML = project.description; + modalTags.innerHTML = project.tags + .map(tag => `${tag}`) + .join(''); + modalLink.href = project.link; + + projectModal.style.display = 'block'; + document.body.style.overflow = 'hidden'; + }); + }); + + // Fermer la modal + modalClose.addEventListener('click', () => { + projectModal.style.display = 'none'; + document.body.style.overflow = 'auto'; + }); + + window.addEventListener('click', (e) => { + if (e.target === projectModal) { + projectModal.style.display = 'none'; + document.body.style.overflow = 'auto'; + } + }); + } + + // Testimonials Slider + const testimonialCards = document.querySelectorAll('.testimonial-card'); + const dots = document.querySelectorAll('.dot'); + const prevBtn = document.querySelector('.control-btn.prev'); + const nextBtn = document.querySelector('.control-btn.next'); + let currentTestimonial = 0; + let autoSlideInterval; + + function showTestimonial(index) { + testimonialCards.forEach(card => card.classList.remove('active')); + dots.forEach(dot => dot.classList.remove('active')); + + testimonialCards[index].classList.add('active'); + dots[index].classList.add('active'); + } + + function nextTestimonial() { + currentTestimonial = (currentTestimonial + 1) % testimonialCards.length; + showTestimonial(currentTestimonial); + } + + function prevTestimonial() { + currentTestimonial = (currentTestimonial - 1 + testimonialCards.length) % testimonialCards.length; + showTestimonial(currentTestimonial); + } + + function startAutoSlide() { + autoSlideInterval = setInterval(nextTestimonial, 5000); + } + + function stopAutoSlide() { + clearInterval(autoSlideInterval); + } + + // Event listeners pour les contrôles des témoignages + if (prevBtn && nextBtn) { + prevBtn.addEventListener('click', () => { + prevTestimonial(); + stopAutoSlide(); + startAutoSlide(); + }); + + nextBtn.addEventListener('click', () => { + nextTestimonial(); + stopAutoSlide(); + startAutoSlide(); + }); + } + + if (dots.length > 0) { + dots.forEach((dot, index) => { + dot.addEventListener('click', () => { + currentTestimonial = index; + showTestimonial(currentTestimonial); + stopAutoSlide(); + startAutoSlide(); + }); + }); + + // Démarrer le défilement automatique + startAutoSlide(); + + // Pause du défilement automatique au survol + const testimonialSlider = document.querySelector('.testimonials-slider'); + if (testimonialSlider) { + testimonialSlider.addEventListener('mouseenter', stopAutoSlide); + testimonialSlider.addEventListener('mouseleave', startAutoSlide); + } + } +}); \ No newline at end of file diff --git a/main.js b/main.js new file mode 100644 index 0000000..fd15261 --- /dev/null +++ b/main.js @@ -0,0 +1,236 @@ +// Smooth scroll for navigation links +document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', function (e) { + e.preventDefault(); + const target = document.querySelector(this.getAttribute('href')); + if (target) { + target.scrollIntoView({ + behavior: 'smooth', + block: 'start' + }); + } + }); +}); + +// Mobile menu +const mobileMenuBtn = document.querySelector('.mobile-menu-btn'); +const navLinks = document.querySelector('.nav-links'); + +if (mobileMenuBtn && navLinks) { + mobileMenuBtn.addEventListener('click', () => { + mobileMenuBtn.classList.toggle('active'); + navLinks.classList.toggle('active'); + }); + + // Close menu when clicking on a link + navLinks.querySelectorAll('a').forEach(link => { + link.addEventListener('click', () => { + mobileMenuBtn.classList.remove('active'); + navLinks.classList.remove('active'); + }); + }); +} + +// Experience card details toggle +document.querySelectorAll('.show-more').forEach(button => { + button.addEventListener('click', () => { + const card = button.closest('.experience-card'); + const details = card.querySelector('.experience-details'); + + if (details) { + details.classList.toggle('show'); + button.textContent = details.classList.contains('show') ? 'Voir moins' : 'Voir plus'; + } + }); +}); + +// Testimonials slider +const testimonialCards = document.querySelectorAll('.testimonial-card'); +const dots = document.querySelectorAll('.dot'); +const prevBtn = document.querySelector('.control-btn.prev'); +const nextBtn = document.querySelector('.control-btn.next'); +let currentTestimonial = 0; +let autoSlideInterval; + +function showTestimonial(index) { + testimonialCards.forEach(card => card.classList.remove('active')); + dots.forEach(dot => dot.classList.remove('active')); + + testimonialCards[index].classList.add('active'); + dots[index].classList.add('active'); +} + +function nextTestimonial() { + currentTestimonial = (currentTestimonial + 1) % testimonialCards.length; + showTestimonial(currentTestimonial); +} + +function prevTestimonial() { + currentTestimonial = (currentTestimonial - 1 + testimonialCards.length) % testimonialCards.length; + showTestimonial(currentTestimonial); +} + +function startAutoSlide() { + autoSlideInterval = setInterval(nextTestimonial, 5000); +} + +function stopAutoSlide() { + clearInterval(autoSlideInterval); +} + +// Event listeners for testimonial controls +if (prevBtn && nextBtn) { + prevBtn.addEventListener('click', () => { + prevTestimonial(); + stopAutoSlide(); + startAutoSlide(); + }); + + nextBtn.addEventListener('click', () => { + nextTestimonial(); + stopAutoSlide(); + startAutoSlide(); + }); +} + +dots.forEach((dot, index) => { + dot.addEventListener('click', () => { + currentTestimonial = index; + showTestimonial(currentTestimonial); + stopAutoSlide(); + startAutoSlide(); + }); +}); + +// Start auto-sliding +startAutoSlide(); + +// Pause auto-slide when hovering over testimonials +const testimonialSlider = document.querySelector('.testimonials-slider'); +if (testimonialSlider) { + testimonialSlider.addEventListener('mouseenter', stopAutoSlide); + testimonialSlider.addEventListener('mouseleave', startAutoSlide); +} + +// Project modal +const projectData = { + 1: { + title: "Application E-commerce", + description: `Une plateforme de commerce électronique complète offrant une expérience d'achat fluide et sécurisée. Caractéristiques principales : + + • Système de panier d'achat dynamique + • Intégration de paiement sécurisé + • Gestion des stocks en temps réel + • Interface administrateur complète + • Système de notation et avis clients + • Optimisation SEO avancée`, + image: "https://via.placeholder.com/800x400", + tags: ["React", "Node.js", "MongoDB", "Stripe", "Redux", "AWS"], + link: "#" + }, + 2: { + title: "Dashboard Analytics", + description: `Interface d'administration sophistiquée permettant la visualisation et l'analyse de données en temps réel. Fonctionnalités : + + • Graphiques interactifs personnalisables + • Tableaux de bord en temps réel + • Export de rapports automatisés + • Système d'alertes intelligent + • Analyse prédictive + • Interface responsive`, + image: "https://via.placeholder.com/800x400", + tags: ["Vue.js", "D3.js", "Firebase", "TypeScript", "TailwindCSS"], + link: "#" + }, + 3: { + title: "Application Mobile Fitness", + description: `Application mobile de suivi fitness complète avec synchronisation cloud et analyses détaillées. Caractéristiques : + + • Suivi d'activités personnalisé + • Synchronisation multi-appareils + • Statistiques détaillées + • Plans d'entraînement adaptatifs + • Intégration avec appareils connectés + • Mode hors ligne`, + image: "https://via.placeholder.com/800x400", + tags: ["React Native", "Redux", "AWS", "Node.js", "MongoDB"], + link: "#" + } +}; + +const modal = document.getElementById('projectModal'); +const modalImage = modal.querySelector('.modal-image'); +const modalTitle = modal.querySelector('.modal-title'); +const modalDescription = modal.querySelector('.modal-description'); +const modalTags = modal.querySelector('.modal-tags'); +const modalLink = modal.querySelector('.modal-link'); +const modalClose = modal.querySelector('.modal-close'); + +// Open modal +document.querySelectorAll('.project-card').forEach(card => { + card.addEventListener('click', (e) => { + const projectId = card.dataset.project; + const project = projectData[projectId]; + + modalImage.src = project.image; + modalImage.alt = project.title; + modalTitle.textContent = project.title; + modalDescription.innerHTML = project.description; + modalTags.innerHTML = project.tags + .map(tag => `${tag}`) + .join(''); + modalLink.href = project.link; + + modal.style.display = 'block'; + document.body.style.overflow = 'hidden'; + }); +}); + +// Close modal +modalClose.addEventListener('click', () => { + modal.style.display = 'none'; + document.body.style.overflow = 'auto'; +}); + +window.addEventListener('click', (e) => { + if (e.target === modal) { + modal.style.display = 'none'; + document.body.style.overflow = 'auto'; + } +}); + +// Intersection Observer for scroll animations +const observerOptions = { + threshold: 0.1, + rootMargin: '0px 0px -50px 0px' +}; + +const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.classList.add('animate-in'); + observer.unobserve(entry.target); + } + }); +}, observerOptions); + +// Observe all sections for animation +document.querySelectorAll('section').forEach(section => { + observer.observe(section); +}); + +// Header scroll behavior +let lastScroll = 0; +const header = document.querySelector('.header'); + +window.addEventListener('scroll', () => { + const currentScroll = window.pageYOffset; + + if (currentScroll > lastScroll && currentScroll > 80) { + header.style.transform = 'translateY(-100%)'; + } else { + header.style.transform = 'translateY(0)'; + } + + lastScroll = currentScroll; +}); \ No newline at end of file diff --git a/mycoolstyle.css b/mycoolstyle.css deleted file mode 100644 index 92d69df..0000000 --- a/mycoolstyle.css +++ /dev/null @@ -1,32 +0,0 @@ -body { - padding-left: 11em; - font-family: Georgia, 'Georgia', "Times New Roman", - Times, serif; - color: darksalmon; - background-color: rgb(39, 39, 84) } - ul.navbar { - list-style-type: none; - padding: 0; - margin: 0; - position: absolute; - top: 2em; - left: 1em; - width: 9em } - h1 { - font-family: Helvetica, Geneva, Arial, - SunSans-Regular, sans-serif } - ul.navbar li { - background: white; - margin: 0.5em 0; - padding: 0.3em; - border-right: 1em solid darksalmon } - ul.navbar a { - text-decoration: none } - a:link { - color: blue } - a:visited { - color: darkblue } - address { - margin-top: 1em; - padding-top: 1em; - border-top: thin dotted } \ No newline at end of file diff --git a/sections/about.html b/sections/about.html new file mode 100644 index 0000000..5acaf84 --- /dev/null +++ b/sections/about.html @@ -0,0 +1,58 @@ +
+
+ +
+
+ Alternant développeur Web +

À mon propos

+
+

Enchanté, je me présente, je m'appelle Noa Sillard et je suis étudiant au BUT informatique de Clermont-Ferrand et en recherche d'école de commerce

+ +

Attiré par l'informatique, j'ai confirmé mon intérêt pour ce domaine au lycée et souhaite désormais évoluer vers des métiers en lien avec ce parcours, avec une dimension plus orientée business.

+ +

Je tire ma curiosité, mon organisation et mon autonomie de mes passions que sont les nouvelles technologies mais également + l'architecture, l'horlgerie, l'automobile et le sport tel que la musculation ou le tir à l'arc.

+
+
+
+ 650+ + Heures de projets académiques de groupe +
+
+ 5+ + Projets réalisés en entreprise +
+
+ 30+ + Collaborateurs +
+
+
+ + +
+
+
\ No newline at end of file diff --git a/sections/experience.html b/sections/experience.html new file mode 100644 index 0000000..c1d356a --- /dev/null +++ b/sections/experience.html @@ -0,0 +1,63 @@ +
+
+ Parcours +

Expériences professionnelles

+
+
+ 2024 - Présent +

Alternant développeur web

+

Coqpit, Clermont-Ferrand

+
+

Création de sites webs en autonomie

+
+
+ +

• 1120 heures

+

• Suivi du projet directement avec les clients

+

• Création de sites webs avec Wordpress(HTML, SCSS, JS, PHP (laravel))

+

Cliquez pour plus de détails

+
+
+ +
+ 2024 (10 semaines) +

Stage en entreprise

+

Open Studio, Clermont-Ferrand

+
+

Développement d'un module du CMS open source Thelia

+
+
+

• Développement du module CustomFrontMenu qui permet à un client de gérer lui même ses menus

+

• Développement de scripts pour automatiser la création de la documentation du CMS

+

Cliquez pour plus de détails

+
+
+ +
+ 2023 (10 semaines) +

Stage en entreprise

+

Code Rhapsody, Lyon

+
+

Développement d'une application interne de gestion des temps et de facturation automatisée

+
+
+

• Développement d'une application interne de gestion des temps et de facturation automatisée

+

Cliquez pour plus de détails

+
+
+
+
+ + + +
\ No newline at end of file diff --git a/sections/footer.html b/sections/footer.html new file mode 100644 index 0000000..77a6557 --- /dev/null +++ b/sections/footer.html @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/sections/formation.html b/sections/formation.html new file mode 100644 index 0000000..31c70a4 --- /dev/null +++ b/sections/formation.html @@ -0,0 +1,24 @@ +
+
+ Parcours +

Formation

+
+
+
+

2021 - 2025

+

Bachelor Universitaire de Technologie Informatique

+

Clermont-Ferrand

+

Gestion de projet, développement, base de données, réseau, architecture

+
+
+
+
+

2020 - 2021

+

Baccalauréat

+

Spécialités Maths - Informatique

+

Option Mathématiques Expertes

+
+
+
+
+
\ No newline at end of file diff --git a/sections/header.html b/sections/header.html new file mode 100644 index 0000000..dde2eb0 --- /dev/null +++ b/sections/header.html @@ -0,0 +1,32 @@ +
+ + + + + + + + + + + + +
\ No newline at end of file diff --git a/sections/projects.html b/sections/projects.html new file mode 100644 index 0000000..1de18dc --- /dev/null +++ b/sections/projects.html @@ -0,0 +1,135 @@ +
+
+ Portfolio +

Mes Réalisations

+
+ +
+
+ Transformation en style comics +
+
+

Transformation de photos en style "Comics"

+

Projet de traitement d'image réalisé seul en une petite semaine dont l'objectif est de transformer une photo existante en style "Comics"

+

Disponible sur mon github

+
+ Python + Numpy + Scipy + Sklearn + Matplotlib +
+ +
+
+ +
+
+ Prediction IA +
+
+

IA supervisée - Prédiction du prix de l'immobilier

+

Ce projet réalisé seul en 7 jours dans le cadre de ma 3ème année de BUT vise à prédire les + prix de l'immobilier en France en utilisant plusieurs modèles de machine learning

+

Disponible sur mon github

+
+ Python + Numpy + Matplotlib + Scikit-learn + Pandas + Lightgbm +
+ +
+
+ +
+
+ Application Web +
+
+

Jeu 3D - Angry bird inversé, les cochons contre attaquent

+

Projet universitaire en autonomie - 2025 (110 heures)

+

Travail dans une équipe de 4 personnes

+
+ Three.JS + Javascript + HTML + CSS +
+ +
+
+ +
+
+ Application Web +
+
+

Applications web et mobile de lutte contre la désinformation

+

Projet universitaire en autonomie - 2024 (200 heures)

+

Travail dans une équipe de 5 personnes

+
+ PHP + Java + Kotlin + SQL + Docker + HTML + CSS +
+ +
+
+ +
+
+ Application Web +
+
+

Jeu de dominos (fractions) éducative

+

2023 (170 heures)

+
+ Javascript + NodeJs + socket.io + HTML + CSS +
+ +
+
+ +
+
+ Application Web +
+
+

Application d'organisation pour les étudiants

+

Projet universitaire en autonomie - 2022 (180 heures)

+

+
+ NodeJs + TypeScript + HTML + CSS +
+ +
+
+
+
+ + + +
\ No newline at end of file diff --git a/sections/skills.html b/sections/skills.html new file mode 100644 index 0000000..112f53f --- /dev/null +++ b/sections/skills.html @@ -0,0 +1,187 @@ +
+
+ Expertise +

Mes Connaissances

+
+ +
+

Soft skills

+
+
+ 🗣️ Vulgarisation +
+
+ 🤝 Esprit d'équipe +
+
+ 🔑 Autonomie +
+
+ 👥 Gestion d'équipe +
+
+ 🔄 Adaptabilité +
+
+ 💬 Relationnel +
+
+
+ +
+

Base de données

+
+
+ PostgreSQL + PostgreSQL +
+
+ MongoDB + MongoDB +
+
+ MariaDB + MariaDB +
+
+ Neo4j + Neo4j +
+
+ Hadoop + Hadoop +
+
+
+ +
+

Outils

+
+
+ Excel + Excel +
+
+ Google Sheets + Google Sheets +
+
+ Power BI + Power BI +
+
+ Git + Git +
+
+ Bootstrap + Bootstrap +
+
+ Figma + Figma +
+
+ Postman + Postman +
+
+ Docker + Docker +
+
+ VSCode + VSCode +
+
+
+ +
+

Langues

+
+
+ 🇫🇷 + Français - Natif +
+
+ 🇬🇧 + Anglais - Courant +
+
+ 🇪🇸 + Espagnol - Bases +
+
+
+ +
+

Back-end

+
+
+ PHP + PHP +
+
+ Python + Python +
+
+ Node.js + Node.js +
+
+ Java + Java +
+
+ C + C +
+
+ C++ + C++ +
+
+
+ +
+

Front-end

+
+
+ HTML + HTML +
+
+ JavaScript + JavaScript +
+
+ CSS + CSS +
+
+ SCSS + SCSS +
+
+
+ +
+
+
\ No newline at end of file diff --git a/sections/testimonials.html b/sections/testimonials.html new file mode 100644 index 0000000..86636c6 --- /dev/null +++ b/sections/testimonials.html @@ -0,0 +1,100 @@ +
+
+ Témoignages +

Ce que disent mes collaborateurs

+
+ +
+
+

"Collaborer avec Noa durant ma deuxième année de BUT informatique a été une chance. Sur notre premier projet d'envergure, Stormy , + j'ai pu mesurer l'étendue de ses compétences. Rare sont ceux qui allient aussi harmonieusement compétences techniques, aisance + communicationnelle et sens des priorités dans le domaine du développement logiciel. Son implication et sa résilience ont été + déterminantes dans la réussite de ce projet, prouvant qu'il sait assumer des responsabilités et organiser efficacement son + travail ainsi que celui de son équipe. Noa est sans conteste un partenaire de projet inestimable, dont l'impact positif va bien + au-delà des attentes." +

+
+
+

David d'Almeida

+

Camarade de 2e année

+
+
+
+
+ +
+
+

"Noa, c'est le mec avec qui tu veux être en équipe lors d'un projet. Avec sa bonne maîtrise technique et son attitude positive, + il arrive à motiver toute l'équipe. Il sait résoudre les problèmes avec efficacité et est une source de motivation pour + surpasser les défis techniques. Il renforce la cohésion d'équipe et garantit de très bons résultats à chaque projet." +

+
+
+

Alexis Feron

+

Camarade de 2e et 3e année

+
+
+
+
+ +
+
+

"Noa est un camarade volontaire et très disponible, c'est agréable de travailler sur des projets avec + lui car il s'y met à fond peu importe la tâche, tout en étant toujours présent pour apporter son aide." +

+
+
+

Shana Cascarra

+

Camarade de 2e et 3e année

+
+
+
+
+ +
+
+

"J'ai eu l'occasion de collaborer avec Noa sur plusieurs projets pendant mes études. C'était toujours agréable de + travailler avec lui car il était très sérieux et engagé. Lorsque nous avons travaillé ensemble sur un projet de + JavaScript, nous avons obtenu un excellent résultat. Noa m'a également apporté son aide dans certaines matières + où j'avais des difficultés, notamment en cryptographie." +

+
+
+

Baptiste Dudonné

+

Camarade de 2e année

+
+
+
+
+ +
+
+

"Lorsque nous travaillons sur le projet Verax, Noa à toujours été un membre travailleur et positif. Etant plus + expérimenté que nous il nous a grandement aidé en nous conseillant sur certaines façons d'aborder certaines notions + qu'il avait déjà vu apparavant. Lors de situations nouvelles il a été un élément fort de notre + groupe d'un point de vu technique et social, surtout lors de certains conflits au sein du groupe de projet." +

+
+
+

Alexis Laurent

+

Camarade de 2e année

+
+
+
+
+ +
+
+ +
+ + + + + +
+ +
+
+ +
\ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..59a5e7a --- /dev/null +++ b/style.css @@ -0,0 +1,796 @@ +:root { + --primary-color: #2563eb; + --text-color: #1f2937; + --bg-color: #ffffff; + --accent-color: #3b82f6; + --gray-light: #f3f4f6; + --gray-dark: #4b5563; + --transition: all 0.3s ease; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Poppins', sans-serif; + line-height: 1.6; + color: var(--text-color); + background-color: var(--bg-color); +} + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 0 2rem; +} + +/* Header & Navigation */ +.header { + position: fixed; + top: 0; + left: 0; + width: 100%; + background-color: var(--bg-color); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); + z-index: 1000; + transition: var(--transition); +} + +.nav-container { + display: flex; + justify-content: space-between; + align-items: center; + height: 80px; + padding: 0 2rem; +} + +.logo { + font-size: 1.5rem; + font-weight: 700; + color: var(--primary-color); +} + +.nav-links { + display: flex; + gap: 2rem; + list-style: none; +} + +.nav-links a { + text-decoration: none; + color: var(--text-color); + font-weight: 500; + transition: var(--transition); +} + +.nav-links a:hover { + color: var(--primary-color); +} + +.mobile-menu-btn { + display: none; + background: none; + border: none; + cursor: pointer; +} + +/* Buttons */ +.btn-primary { + display: inline-block; + padding: 0.8rem 1.5rem; + width: 100%; + background-color: var(--primary-color); + color: white; + text-decoration: none; + border-radius: 0.5rem; + transition: var(--transition); +} + +.btn-primary:hover { + background-color: var(--accent-color); + transform: translateY(-2px); +} + +.btn-secondary { + display: inline-block; + padding: 0.8rem 1.5rem; + background-color: var(--accent-color); + color: white; + text-decoration: none; + border-radius: 0.5rem; + transition: var(--transition); +} + +.btn-outline { + display: inline-block; + padding: 0.8rem 1.5rem; + border: 2px solid var(--primary-color); + color: var(--primary-color); + text-decoration: none; + border-radius: 0.5rem; + transition: var(--transition); +} + +.btn-outline:hover { + background-color: var(--primary-color); + color: white; +} + +/* Sections */ +.section { + padding: 8rem 0; +} + +/* About Section */ +.about-content { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 4rem; + align-items: center; +} + +.section-subtitle { + display: inline-block; + font-size: 1rem; + color: var(--primary-color); + font-weight: 500; + margin-bottom: 1rem; + text-transform: uppercase; + letter-spacing: 2px; +} + +.section-title { + font-size: 2.5rem; + margin-bottom: 2rem; + color: var(--text-color); + line-height: 1.2; +} + +.about-description { + margin-bottom: 2.5rem; +} + +.about-description p { + margin-bottom: 1rem; + color: var(--gray-dark); +} + +.about-stats { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 2rem; + margin-top: 3rem; +} + +.stat-item { + text-align: center; +} + +.stat-number { + display: block; + font-size: 2rem; + font-weight: 700; + color: var(--primary-color); + margin-bottom: 0.5rem; +} + +.stat-label { + font-size: 0.9rem; + color: var(--gray-dark); +} + +.about-image { + position: relative; +} + +.profile-image { + width: 100%; + border-radius: 1rem; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + position: relative; + z-index: 2; +} + +.image-decoration { + position: absolute; + width: 100%; + height: 100%; + border: 2px solid var(--primary-color); + border-radius: 1rem; + top: 20px; + left: 20px; + z-index: 1; +} + +/* Projects Section */ +.projects-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 2rem; + margin-top: 3rem; +} + +.project-card { + background-color: var(--bg-color); + border-radius: 1rem; + overflow: hidden; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + transition: var(--transition); +} + +.project-card:hover { + transform: translateY(-10px); +} + +.project-image { + width: 100%; + height: 250px; + overflow: hidden; +} + +.project-image img { + width: 100%; + height: 100%; + object-fit: cover; + transition: var(--transition); +} + +.project-card:hover .project-image img { + transform: scale(1.1); +} + +.project-content { + padding: 2rem; +} + +.project-content h3 { + font-size: 1.5rem; + margin-bottom: 1rem; + color: var(--text-color); +} + +.project-content p { + color: var(--gray-dark); + margin-bottom: 1.5rem; +} + +.project-tags { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-bottom: 1.5rem; +} + +.project-tags span { + background-color: var(--gray-light); + color: var(--primary-color); + padding: 0.4rem 0.8rem; + border-radius: 2rem; + font-size: 0.9rem; +} + +.project-links { + display: flex; + gap: 1rem; +} + +/* Testimonials Section */ +.testimonials { + background-color: var(--gray-light); +} + +.testimonials-slider { + position: relative; + max-width: 800px; + margin: 3rem auto 0; + overflow: hidden; +} + +.testimonial-card { + display: none; + background-color: var(--bg-color); + padding: 2rem; + border-radius: 1rem; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); +} + +.testimonial-card.active { + display: block; + animation: fadeIn 0.5s ease-in-out; +} + +.testimonial-content p { + font-size: 1.1rem; + color: var(--gray-dark); + font-style: italic; + margin-bottom: 1.5rem; +} + +.testimonial-author { + display: flex; + align-items: center; + gap: 1rem; +} + +.author-info h4 { + font-size: 1.1rem; + color: var(--text-color); + margin-bottom: 0.2rem; +} + +.author-info p { + font-size: 0.9rem; + color: var(--gray-dark); +} + +.testimonial-controls { + display: flex; + justify-content: center; + align-items: center; + gap: 2rem; + margin-top: 2rem; +} + +.control-btn { + background: none; + border: none; + font-size: 1.5rem; + color: var(--primary-color); + cursor: pointer; + transition: var(--transition); +} + +.control-btn:hover { + color: var(--accent-color); +} + +.testimonial-dots { + display: flex; + gap: 0.5rem; +} + +.dot { + width: 10px; + height: 10px; + border-radius: 50%; + background-color: var(--gray-dark); + border: none; + cursor: pointer; + transition: var(--transition); +} + +.dot.active { + background-color: var(--primary-color); +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Footer */ +.footer { + background-color: var(--gray-light); + padding: 3rem 0; + margin-top: 4rem; +} + +.footer-content { + display: flex; + flex-direction: column; + align-items: center; + gap: 2rem; +} + +.social-links { + display: flex; + gap: 1.5rem; +} + +.social-icon { + width: 24px; + height: 24px; + background-size: contain; + background-repeat: no-repeat; +} + +/* Formation Section */ +.formation { + background-color: var(--gray-light); +} + +.timeline { + position: relative; + max-width: 800px; + margin: 3rem auto 0; + padding: 2rem 0; +} + +.timeline::before { + content: ''; + position: absolute; + width: 2px; + height: 100%; + background-color: var(--primary-color); + left: 50%; + transform: translateX(-50%); + top: 0; +} + +.timeline-item { + position: relative; + margin-bottom: 3rem; + width: calc(50% - 2rem); + margin-left: auto; +} + +.timeline-item:nth-child(odd) { + margin-right: auto; + margin-left: 0; +} + +.timeline-content { + background-color: var(--bg-color); + padding: 2rem; + border-radius: 1rem; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + position: relative; + transition: var(--transition); +} + +.timeline-content:hover { + transform: translateY(-5px); +} + +.timeline-content::before { + content: ''; + position: absolute; + width: 20px; + height: 20px; + background-color: var(--primary-color); + border-radius: 50%; + top: 50%; + transform: translateY(-50%); +} + +.timeline-item:nth-child(odd) .timeline-content::before { + right: -3rem; +} + +.timeline-item:nth-child(even) .timeline-content::before { + left: -3rem; +} + +.timeline-content h3 { + color: var(--primary-color); + font-size: 1.2rem; + margin-bottom: 0.5rem; +} + +.timeline-content h4 { + font-size: 1.5rem; + margin-bottom: 1rem; + color: var(--text-color); +} + +.timeline-content p { + color: var(--gray-dark); +} + +/* Experience Section */ +.experience-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 2rem; + margin-top: 3rem; +} + +.experience-card { + background-color: var(--bg-color); + border-radius: 1rem; + padding: 2rem; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + transition: var(--transition); + position: relative; + overflow: hidden; +} + +.experience-card:hover { + transform: translateY(-5px); +} + +.experience-date { + display: inline-block; + background-color: var(--primary-color); + color: white; + padding: 0.5rem 1rem; + border-radius: 2rem; + font-size: 0.9rem; + margin-bottom: 1rem; +} + +.experience-card h3 { + font-size: 1.5rem; + margin-bottom: 1rem; + color: var(--text-color); +} + +.experience-description { + color: var(--gray-dark); + margin-bottom: 1.5rem; +} + +.experience-details { + max-height: 0; + overflow: hidden; + transition: max-height 0.3s ease-out; +} + +.experience-details.show { + max-height: 500px; + margin-top: 1rem; + padding-top: 1rem; + border-top: 1px solid var(--gray-light); +} + +.show-more { + background: none; + border: none; + color: var(--primary-color); + cursor: pointer; + font-weight: 500; + padding: 0; + transition: var(--transition); +} + +.show-more:hover { + color: var(--accent-color); +} + +/* Modal */ +.modal { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.8); + z-index: 1100; + overflow-y: auto; +} + +.modal-content { + position: relative; + background-color: var(--bg-color); + margin: 2rem auto; + padding: 2rem; + width: 90%; + max-width: 800px; + border-radius: 1rem; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2); +} + +.modal-close { + position: absolute; + top: 1rem; + right: 1rem; + font-size: 1.5rem; + background: none; + border: none; + color: var(--gray-dark); + cursor: pointer; + transition: var(--transition); +} + +.modal-close:hover { + color: var(--primary-color); + transform: rotate(90deg); +} + +.modal-image { + width: 100%; + height: 300px; + object-fit: cover; + border-radius: 0.5rem; + margin-bottom: 1.5rem; +} + +.modal-title { + font-size: 1.8rem; + margin-bottom: 1rem; + color: var(--text-color); +} + +.modal-description { + color: var(--gray-dark); + margin-bottom: 1.5rem; + line-height: 1.6; +} + +.modal-tags { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-bottom: 1.5rem; +} + +.modal-tags span { + background-color: var(--gray-light); + color: var(--primary-color); + padding: 0.4rem 0.8rem; + border-radius: 2rem; + font-size: 0.9rem; +} + +.modal-link { + display: inline-block; + padding: 0.8rem 1.5rem; + background-color: var(--primary-color); + color: white; + text-decoration: none; + border-radius: 0.5rem; + transition: var(--transition); +} + +.modal-link:hover { + background-color: var(--accent-color); + transform: translateY(-2px); +} + +/* Mobile Menu */ +.mobile-menu-btn { + display: none; + flex-direction: column; + justify-content: space-between; + width: 30px; + height: 21px; + background: none; + border: none; + cursor: pointer; + padding: 0; + z-index: 1000; +} + +.mobile-menu-btn span { + width: 100%; + height: 3px; + background-color: var(--primary-color); + border-radius: 3px; + transition: var(--transition); +} + +/* Projects Section Update */ +.project-card { + position: relative; + cursor: pointer; + transition: var(--transition); +} + +.project-card:hover { + transform: translateY(-10px); +} + +.project-content { + padding: 1.5rem; +} + +.project-content h3 { + font-size: 1.5rem; + margin-bottom: 1rem; + color: var(--text-color); +} + +.project-content p { + color: var(--gray-dark); + margin-bottom: 1.5rem; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; +} + +/* Responsive Design Update */ +@media (max-width: 768px) { + .mobile-menu-btn { + display: flex; + } + + .nav-links { + position: fixed; + top: 80px; + left: -100%; + width: 100%; + height: calc(100vh - 80px); + background-color: var(--bg-color); + flex-direction: column; + align-items: center; + padding: 2rem; + transition: var(--transition); + z-index: 900; + } + + .nav-links.active { + left: 0; + } + + .nav-links li { + margin: 1.5rem 0; + } + + .mobile-menu-btn.active span:nth-child(1) { + transform: translateY(9px) rotate(45deg); + } + + .mobile-menu-btn.active span:nth-child(2) { + opacity: 0; + } + + .mobile-menu-btn.active span:nth-child(3) { + transform: translateY(-9px) rotate(-45deg); + } + + .about-content { + grid-template-columns: 1fr; + text-align: center; + } + + .about-stats { + justify-content: center; + } + + .profile-image { + max-width: 300px; + margin: 0 auto; + } + + .image-decoration { + display: none; + } + + .section-title { + font-size: 2rem; + } + + .projects-grid { + grid-template-columns: 1fr; + } + + .project-links { + flex-direction: column; + } + + .testimonial-controls { + gap: 1rem; + } + + .timeline::before { + left: 1rem; + } + + .timeline-item { + width: calc(100% - 3rem); + margin-left: 3rem; + } + + .timeline-item:nth-child(odd) { + margin-left: 3rem; + } + + .timeline-content::before { + left: -2.5rem !important; + } + + .experience-grid { + grid-template-columns: 1fr; + } +} \ No newline at end of file diff --git a/style/about.css b/style/about.css new file mode 100644 index 0000000..5ae0932 --- /dev/null +++ b/style/about.css @@ -0,0 +1,134 @@ +.about-content { + display: grid; + grid-template-columns: 3fr 1fr; + gap: 4rem; + align-items: start; +} + +.about-description { + margin-bottom: 2.5rem; +} + +.about-description p { + margin-bottom: 1rem; + color: var(--gray-dark); +} + +.about-stats { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 2rem; + margin-top: 3rem; +} + +.stat-item { + text-align: center; +} + +.stat-number { + display: block; + font-size: 2rem; + font-weight: 700; + color: var(--primary-color); + margin-bottom: 0.5rem; +} + +.stat-label { + font-size: 0.9rem; + color: var(--gray-dark); +} + +.about-right { + display: flex; + flex-direction: column; + gap: 2rem; + padding-right: 20px; +} + +.about-image { + position: relative; + max-width: 400px; + margin: 0 auto; +} + +.profile-image { + width: 100%; + border-radius: 1rem; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + position: relative; + z-index: 2; +} + +.image-decoration { + position: absolute; + width: 100%; + height: 100%; + border: 2px solid var(--primary-color); + border-radius: 1rem; + top: 20px; + left: 20px; + z-index: 1; +} + +.about-social { + display: flex; + justify-content: center; + gap: 1.5rem; + margin-top: 1rem; +} + +.social-link { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: 50%; + background-color: var(--gray-light); + transition: var(--transition); +} + +.social-link:hover { + transform: translateY(-3px); + background-color: var(--primary-color); +} + +.social-link img, +.social-link svg { + width: 24px; + height: 24px; + color: var(--primary-color); +} + +.social-link:hover img, +.social-link:hover svg { + filter: brightness(0) invert(1); +} + +.mail-icon { + width: 24px; + height: 24px; +} + +@media (max-width: 768px) { + .about-content { + grid-template-columns: 1fr; + text-align: center; + } + + .about-stats { + justify-content: center; + grid-template-columns: 1fr; + } + + .about-right{ + padding-right: inherit; + } + .about-image { + max-width: 100%; + } + + .image-decoration { + display: none; + } +} \ No newline at end of file diff --git a/style/experience.css b/style/experience.css new file mode 100644 index 0000000..e5da329 --- /dev/null +++ b/style/experience.css @@ -0,0 +1,182 @@ +section.experience{ + background-color: var(--gray-light); +} + +.experience-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 2rem; + margin-top: 3rem; +} + +.experience-card { + background-color: var(--bg-color); + border-radius: 1rem; + padding: 2rem; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + transition: var(--transition); + position: relative; + overflow: hidden; + cursor: pointer; +} + +.experience-card:hover { + transform: translateY(-5px); +} + +.experience-date { + display: inline-block; + background-color: var(--primary-color); + color: white; + padding: 0.5rem 1rem; + border-radius: 2rem; + font-size: 0.9rem; + margin-bottom: 1rem; +} + +.experience-card h3 { + font-size: 1.5rem; + margin-bottom: 0.5rem; + color: var(--text-color); +} + +.experience-company { + color: var(--gray-dark); + margin-bottom: 1rem; + font-weight: 500; +} + +.experience-preview { + color: var(--gray-dark); +} + +.experience-hover { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(37, 99, 235, 0.96); + color: white; + padding: 2rem; + opacity: 0; + transition: var(--transition); + display: flex; + flex-direction: column; + justify-content: center; +} + +.experience-card:hover .experience-hover { + opacity: 1; +} + +.experience-hover p { + margin-bottom: 0.5rem; +} + +.experience-hover p:last-child { + margin-top: 1rem; + font-style: italic; + font-size: 0.9rem; +} + +/* Modal */ +.modal { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.8); + z-index: 1100; + overflow-y: auto; +} + +.modal-content { + position: relative; + background-color: var(--bg-color); + margin: 2rem auto; + padding: 2rem; + width: 90%; + max-width: 800px; + border-radius: 1rem; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2); +} + +.modal-close { + position: absolute; + top: 1rem; + right: 1rem; + font-size: 1.5rem; + background: none; + border: none; + color: var(--gray-dark); + cursor: pointer; + transition: var(--transition); +} + +.modal-close:hover { + color: var(--primary-color); + transform: rotate(90deg); +} + +.modal-date { + display: inline-block; + background-color: var(--primary-color); + color: white; + padding: 0.5rem 1rem; + border-radius: 2rem; + font-size: 0.9rem; + margin-bottom: 1rem; +} + +.modal-title { + font-size: 1.8rem; + margin-bottom: 0.5rem; + color: var(--text-color); +} + +.modal-company { + color: var(--gray-dark); + font-weight: 500; + margin-bottom: 1.5rem; +} + +.modal-description { + color: var(--gray-dark); + margin-bottom: 1.5rem; + line-height: 1.6; +} + +.modal-skills { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-bottom: 1.5rem; +} + +.modal-skills span { + background-color: var(--gray-light); + color: var(--primary-color); + padding: 0.4rem 0.8rem; + border-radius: 2rem; + font-size: 0.9rem; +} + +.modal-achievements { + border-top: 1px solid var(--gray-light); + padding-top: 1.5rem; + color: var(--gray-dark); +} + +.modal-achievements h4 { + color: var(--text-color); + margin-bottom: 1rem; +} + +@media (max-width: 768px) { + .experience-grid { + grid-template-columns: 1fr; + } +} \ No newline at end of file diff --git a/style/footer.css b/style/footer.css new file mode 100644 index 0000000..b88cd58 --- /dev/null +++ b/style/footer.css @@ -0,0 +1,46 @@ +.footer { + background-color: var(--gray-light); + padding: 7rem 0 3rem 0; +} + +.footer-content { + display: flex; + flex-direction: column; + align-items: center; + gap: 2rem; +} + +.social-links { + display: flex; + gap: 1.5rem; +} + +.social-icon { + width: 24px; + height: 24px; + background-size: contain; + background-repeat: no-repeat; + transition: var(--transition); +} + +.social-icon.linkedin { + background-image: url('data:image/svg+xml,'); +} + +.social-icon.github { + background-image: url('data:image/svg+xml,'); +} + +.social-icon.twitter { + background-image: url('data:image/svg+xml,'); +} + +.social-links a:hover .social-icon { + transform: translateY(-3px); +} + +.copyright { + color: var(--gray-dark); + font-size: 0.9rem; + text-align: center; +} \ No newline at end of file diff --git a/style/formation.css b/style/formation.css new file mode 100644 index 0000000..c7274d7 --- /dev/null +++ b/style/formation.css @@ -0,0 +1,100 @@ +.formation { + background-color: var(--gray-light); +} + +.timeline { + position: relative; + max-width: 800px; + margin: 3rem auto 0; + padding: 2rem 0; +} + +.timeline::before { + content: ''; + position: absolute; + width: 2px; + height: 100%; + background-color: var(--primary-color); + left: 50%; + transform: translateX(-50%); + top: 0; +} + +.timeline-item { + position: relative; + margin-bottom: 3rem; + width: calc(50% - 2rem); + margin-left: auto; +} + +.timeline-item:nth-child(odd) { + margin-right: auto; + margin-left: 0; +} + +.timeline-content { + background-color: var(--bg-color); + padding: 2rem; + border-radius: 1rem; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + position: relative; + transition: var(--transition); +} + +.timeline-content:hover { + transform: translateY(-5px); +} + +.timeline-content::before { + content: ''; + position: absolute; + width: 20px; + height: 20px; + background-color: var(--primary-color); + border-radius: 50%; + top: 50%; + transform: translateY(-50%); +} + +.timeline-item:nth-child(odd) .timeline-content::before { + right: -3rem; +} + +.timeline-item:nth-child(even) .timeline-content::before { + left: -3rem; +} + +.timeline-content h3 { + color: var(--primary-color); + font-size: 1.2rem; + margin-bottom: 0.5rem; +} + +.timeline-content h4 { + font-size: 1.5rem; + margin-bottom: 1rem; + color: var(--text-color); +} + +.timeline-content p { + color: var(--gray-dark); +} + +@media (max-width: 768px) { + .timeline::before { + left: 1rem; + } + + .timeline-item { + width: calc(100% - 3rem); + margin-left: 3rem; + } + + .timeline-item:nth-child(odd) { + margin-left: 3rem; + } + + .timeline-content::before { + left: -2.5rem !important; + } +} \ No newline at end of file diff --git a/style/header.css b/style/header.css new file mode 100644 index 0000000..5102042 --- /dev/null +++ b/style/header.css @@ -0,0 +1,108 @@ +.header { + position: fixed; + top: 0; + left: 0; + width: 100%; + background-color: var(--bg-color); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); + z-index: 1000; + transition: var(--transition); +} + +.nav-container { + display: flex; + justify-content: space-between; + align-items: center; + height: 80px; + padding: 0 2rem; +} + +.logo { + font-size: 1.5rem; + font-weight: 700; + color: var(--primary-color); +} + +.logo a{ + color: var(--primary-color); + text-decoration: none; +} + +.nav-links { + display: flex; + gap: 2rem; + list-style: none; +} + +.nav-links a { + text-decoration: none; + color: var(--text-color); + font-weight: 500; + transition: var(--transition); +} + +.nav-links a:hover { + color: var(--primary-color); +} + +/* Mobile Menu */ +.mobile-menu-btn { + display: none; + flex-direction: column; + justify-content: space-between; + width: 30px; + height: 21px; + background: none; + border: none; + cursor: pointer; + padding: 0; + z-index: 1000; +} + +.mobile-menu-btn span { + width: 100%; + height: 3px; + background-color: var(--primary-color); + border-radius: 3px; + transition: var(--transition); +} + +@media (max-width: 768px) { + .mobile-menu-btn { + display: flex; + } + + .nav-links { + position: fixed; + top: 80px; + left: -100%; + width: 100%; + height: calc(100vh - 80px); + background-color: var(--bg-color); + flex-direction: column; + align-items: center; + padding: 2rem; + transition: var(--transition); + z-index: 900; + } + + .nav-links.active { + left: 0; + } + + .nav-links li { + margin: 1.5rem 0; + } + + .mobile-menu-btn.active span:nth-child(1) { + transform: translateY(9px) rotate(45deg); + } + + .mobile-menu-btn.active span:nth-child(2) { + opacity: 0; + } + + .mobile-menu-btn.active span:nth-child(3) { + transform: translateY(-9px) rotate(-45deg); + } +} \ No newline at end of file diff --git a/style/main.css b/style/main.css new file mode 100644 index 0000000..484904f --- /dev/null +++ b/style/main.css @@ -0,0 +1,90 @@ +:root { + --primary-color: #2563eb; + --text-color: #1f2937; + --bg-color: #ffffff; + --accent-color: #3b82f6; + --gray-light: #f3f4f6; + --gray-dark: #4b5563; + --transition: all 0.3s ease; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Poppins', sans-serif; + line-height: 1.6; + color: var(--text-color); + background-color: var(--bg-color); +} + +.container { + max-width: 1200px; + margin: 0 auto; + /*padding: 0 2rem;*/ +} + +.section { + padding: 100px 16px; +} + +.section-subtitle { + display: inline-block; + font-size: 1rem; + color: var(--primary-color); + font-weight: 500; + margin-bottom: 1rem; + text-transform: uppercase; + letter-spacing: 2px; +} + +.section-title { + font-size: 2.5rem; + margin-bottom: 2rem; + color: var(--text-color); + line-height: 1.2; +} + +/* Boutons communs */ +.btn-primary { + display: inline-block; + padding: 0.8rem 1.5rem; + background-color: var(--primary-color); + color: white; + text-decoration: none; + border-radius: 0.5rem; + transition: var(--transition); +} + +.btn-primary:hover { + background-color: var(--accent-color); + transform: translateY(-2px); +} + +.btn-secondary { + display: inline-block; + padding: 0.8rem 1.5rem; + background-color: var(--accent-color); + color: white; + text-decoration: none; + border-radius: 0.5rem; + transition: var(--transition); +} + +.btn-outline { + display: inline-block; + padding: 0.8rem 1.5rem; + border: 2px solid var(--primary-color); + color: var(--primary-color); + text-decoration: none; + border-radius: 0.5rem; + transition: var(--transition); +} + +.btn-outline:hover { + background-color: var(--primary-color); + color: white; +} \ No newline at end of file diff --git a/style/projects.css b/style/projects.css new file mode 100644 index 0000000..defef99 --- /dev/null +++ b/style/projects.css @@ -0,0 +1,158 @@ +.projects-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 2rem; + margin-top: 3rem; +} + +.project-card { + background-color: var(--bg-color); + border-radius: 1rem; + overflow: hidden; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + transition: var(--transition); + cursor: pointer; +} + +.project-card:hover { + transform: translateY(-10px); +} + +.project-image { + width: 100%; + height: 250px; + overflow: hidden; +} + +.project-image img { + width: 100%; + height: 100%; + object-fit: cover; + transition: var(--transition); +} + +.project-card:hover .project-image img { + transform: scale(1.1); +} + +.project-content { + padding: 2rem; +} + +.project-content h3 { + font-size: 1.5rem; + margin-bottom: 1rem; + color: var(--text-color); +} + +.project-content p { + color: var(--gray-dark); + margin-bottom: 1.5rem; +} + +.project-tags { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-bottom: 1.5rem; +} + +.project-tags span { + background-color: var(--gray-light); + color: var(--primary-color); + padding: 0.4rem 0.8rem; + border-radius: 2rem; + font-size: 0.9rem; +} + +/* Modal */ +.modal { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.8); + z-index: 1100; + overflow-y: auto; +} + +.modal-content { + position: relative; + background-color: var(--bg-color); + margin: 2rem auto; + padding: 2rem; + width: 90%; + max-width: 800px; + border-radius: 1rem; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2); +} + +.modal-close { + position: absolute; + top: 1rem; + right: 1rem; + font-size: 1.5rem; + background: none; + border: none; + color: var(--gray-dark); + cursor: pointer; + transition: var(--transition); +} + +.modal-close:hover { + color: var(--primary-color); + transform: rotate(90deg); +} + +.modal-image { + width: 100%; + height: 300px; + object-fit: cover; + border-radius: 0.5rem; + margin-bottom: 1.5rem; +} + +.modal-title { + font-size: 1.8rem; + margin-bottom: 1rem; + color: var(--text-color); +} + +.modal-description { + color: var(--gray-dark); + margin-bottom: 1.5rem; + line-height: 1.6; + white-space: pre-line; +} + +.modal-tags { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-bottom: 1.5rem; +} + +.modal-tags span { + background-color: var(--gray-light); + color: var(--primary-color); + padding: 0.4rem 0.8rem; + border-radius: 2rem; + font-size: 0.9rem; +} + +.modal-link { + display: inline-block; + padding: 0.8rem 1.5rem; + background-color: var(--primary-color); + color: white; + text-decoration: none; + border-radius: 0.5rem; + transition: var(--transition); +} + +.modal-link:hover { + background-color: var(--accent-color); + transform: translateY(-2px); +} \ No newline at end of file diff --git a/style/skills.css b/style/skills.css new file mode 100644 index 0000000..7ee8afe --- /dev/null +++ b/style/skills.css @@ -0,0 +1,87 @@ +.skills { + /*background-color: var(--gray-light);*/ +} + +.skills-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 2rem; + margin-top: 3rem; +} + +.skill-card { + background-color: var(--bg-color); + border-radius: 1rem; + padding: 2rem; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + transition: var(--transition); +} + +.skill-card:hover { + transform: translateY(-5px); +} + +.skill-card h3 { + font-size: 1.5rem; + color: var(--primary-color); + margin-bottom: 1.5rem; + text-align: center; +} + +.skill-items { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(80px, 1fr)); + gap: 1.5rem; +} + +.skill-item { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; +} + +.skill-item img { + width: 40px; + height: 40px; + transition: var(--transition); +} + +.skill-item:hover img { + transform: scale(1.1); +} + +.skill-item span { + font-size: 0.9rem; + color: var(--gray-dark); + text-align: center; +} + +.skill-list { + display: flex; + flex-direction: column; + gap: 1rem; +} + +.skill-list-item { + display: flex; + align-items: center; + gap: 1rem; + padding: 0.5rem; + border-radius: 0.5rem; + transition: var(--transition); +} + +.skill-list-item:hover { + background-color: var(--gray-light); +} + +.skill-icon { + font-size: 1.5rem; +} + +@media (max-width: 768px) { + .skills-grid { + grid-template-columns: 1fr; + } +} \ No newline at end of file diff --git a/style/testimonials.css b/style/testimonials.css new file mode 100644 index 0000000..ba64fd8 --- /dev/null +++ b/style/testimonials.css @@ -0,0 +1,101 @@ +.testimonials { + background-color: var(--gray-light); +} + +.testimonials-slider { + position: relative; + max-width: 800px; + margin: 3rem auto 0; + overflow: hidden; +} + +.testimonial-card { + display: none; + background-color: var(--bg-color); + padding: 2rem; + border-radius: 1rem; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); +} + +.testimonial-card.active { + display: block; + animation: fadeIn 0.5s ease-in-out; +} + +.testimonial-content p { + font-size: 1.1rem; + color: var(--gray-dark); + font-style: italic; + margin-bottom: 1.5rem; + line-height: 1.8; +} + +.testimonial-author { + display: flex; + align-items: center; + gap: 1rem; +} + +.author-info h4 { + font-size: 1.1rem; + color: var(--text-color); + margin-bottom: 0.2rem; +} + +.author-info p { + font-size: 0.9rem; + color: var(--gray-dark); + font-style: normal; + margin: 0; +} + +.testimonial-controls { + display: flex; + justify-content: center; + align-items: center; + gap: 2rem; + margin-top: 2rem; +} + +.control-btn { + background: none; + border: none; + font-size: 1.5rem; + color: var(--primary-color); + cursor: pointer; + transition: var(--transition); +} + +.control-btn:hover { + color: var(--accent-color); +} + +.testimonial-dots { + display: flex; + gap: 0.5rem; +} + +.dot { + width: 10px; + height: 10px; + border-radius: 50%; + background-color: var(--gray-dark); + border: none; + cursor: pointer; + transition: var(--transition); +} + +.dot.active { + background-color: var(--primary-color); +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} \ No newline at end of file