diff --git a/animations.js b/animations.js
new file mode 100644
index 0000000..965b970
--- /dev/null
+++ b/animations.js
@@ -0,0 +1,209 @@
+class PortfolioAnimations {
+ constructor() {
+ this.init();
+ }
+
+ init() {
+ this.setupIntersectionObserver();
+ this.setupMagneticEffects();
+ this.setupParallaxEffects();
+ this.addFloatingShapes();
+ }
+
+
+ setupIntersectionObserver() {
+ const observerOptions = {
+ threshold: 0.1,
+ rootMargin: '0px 0px -50px 0px'
+ };
+
+ const observer = new IntersectionObserver((entries) => {
+ entries.forEach(entry => {
+ if (entry.isIntersecting) {
+ const element = entry.target;
+ const animation = element.dataset.animation;
+ const delay = element.dataset.delay || 0;
+
+ setTimeout(() => {
+ element.classList.add(`animate-${animation}`);
+
+ if (element.dataset.counter) {
+ this.animateCounter(element);
+ }
+ }, delay);
+
+ observer.unobserve(element);
+ }
+ });
+ }, observerOptions);
+
+ document.querySelectorAll('.animate-on-scroll').forEach(el => {
+ observer.observe(el);
+ });
+ }
+
+ setupMagneticEffects() {
+ document.querySelectorAll('.magnetic').forEach(button => {
+ button.addEventListener('mousemove', (e) => {
+ const rect = button.getBoundingClientRect();
+ const x = e.clientX - rect.left - rect.width / 2;
+ const y = e.clientY - rect.top - rect.height / 2;
+
+ button.style.transform = `translate(${x * 0.1}px, ${y * 0.1}px) scale(1.02)`;
+ });
+
+ button.addEventListener('mouseleave', () => {
+ button.style.transform = 'translate(0px, 0px) scale(1)';
+ });
+ });
+ }
+
+ setupParallaxEffects() {
+ window.addEventListener('scroll', () => {
+ const scrolled = window.pageYOffset;
+ const parallaxElements = document.querySelectorAll('.parallax');
+
+ parallaxElements.forEach(element => {
+ const speed = element.dataset.speed || 0.5;
+ const yPos = -(scrolled * speed);
+ element.style.transform = `translateY(${yPos}px)`;
+ });
+ });
+ }
+
+ animateCounter(element) {
+ const target = parseInt(element.dataset.counter);
+ const duration = 2000;
+ const start = 0;
+ const increment = target / (duration / 16);
+ let current = start;
+
+ const timer = setInterval(() => {
+ current += increment;
+ if (current >= target) {
+ current = target;
+ clearInterval(timer);
+ }
+ element.textContent = Math.floor(current);
+ }, 16);
+ }
+
+ addFloatingShapes() {
+ const hero = document.querySelector('.hero-gradient');
+ if (!hero) return;
+
+ const shapesContainer = document.createElement('div');
+ shapesContainer.className = 'floating-shapes';
+
+ for (let i = 0; i < 3; i++) {
+ const shape = document.createElement('div');
+ shape.className = 'floating-shape';
+ shapesContainer.appendChild(shape);
+ }
+
+ hero.appendChild(shapesContainer);
+ }
+
+ static typeWriter(element, text, speed = 100) {
+ let i = 0;
+ element.textContent = '';
+
+ function type() {
+ if (i < text.length) {
+ element.textContent += text.charAt(i);
+ i++;
+ setTimeout(type, speed);
+ }
+ }
+
+ type();
+ }
+
+ static revealText(element) {
+ const text = element.textContent;
+ const words = text.split(' ');
+ element.innerHTML = '';
+
+ words.forEach((word, index) => {
+ const span = document.createElement('span');
+ span.textContent = word + ' ';
+ span.style.opacity = '0';
+ span.style.transform = 'translateY(20px)';
+ span.style.transition = `all 0.6s ease ${index * 0.1}s`;
+ element.appendChild(span);
+
+ setTimeout(() => {
+ span.style.opacity = '1';
+ span.style.transform = 'translateY(0)';
+ }, 100);
+ });
+ }
+
+ static setupSmoothScroll() {
+ 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'
+ });
+ }
+ });
+ });
+ }
+}
+
+document.addEventListener('DOMContentLoaded', () => {
+ new PortfolioAnimations();
+ PortfolioAnimations.setupSmoothScroll();
+});
+
+window.PortfolioAnimations = PortfolioAnimations;
+
+function initScrollAnimations() {
+ const observerOptions = {
+ threshold: 0.1,
+ rootMargin: '0px 0px -50px 0px'
+ };
+
+ const observer = new IntersectionObserver((entries) => {
+ entries.forEach(entry => {
+ if (entry.isIntersecting) {
+ const delay = entry.target.dataset.delay || 0;
+ setTimeout(() => {
+ entry.target.classList.add('visible');
+ }, delay);
+ }
+ });
+ }, observerOptions);
+
+ document.querySelectorAll('.animate-on-scroll').forEach(el => {
+ observer.observe(el);
+ });
+}
+
+function initMagneticEffect() {
+ const magneticElements = document.querySelectorAll('.magnetic');
+
+ magneticElements.forEach(el => {
+ el.addEventListener('mousemove', (e) => {
+ const rect = el.getBoundingClientRect();
+ const x = e.clientX - rect.left - rect.width / 2;
+ const y = e.clientY - rect.top - rect.height / 2;
+
+ el.style.transform = `translate(${x * 0.1}px, ${y * 0.1}px) scale(1.02)`;
+ });
+
+ el.addEventListener('mouseleave', () => {
+ el.style.transform = 'translate(0px, 0px) scale(1)';
+ });
+ });
+}
+
+document.addEventListener('DOMContentLoaded', () => {
+ initScrollAnimations();
+ initMagneticEffect();
+});
\ No newline at end of file
diff --git a/apropos.html b/apropos.html
new file mode 100644
index 0000000..7001fda
--- /dev/null
+++ b/apropos.html
@@ -0,0 +1,251 @@
+
+
+
+
+
+ À propos - Jules Merienne
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ À propos de moi
+
+
+
+
+
+
+
+
+
+
+
+
+ Stack Technique
+
+
+
+
+
+
Langages de Programmation
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/contact.html b/contact.html
new file mode 100644
index 0000000..cd50119
--- /dev/null
+++ b/contact.html
@@ -0,0 +1,287 @@
+
+
+
+
+
+ Contact - Jules Merienne
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contactez-moi
+
+
+ Une idée de projet ? Une question ? N'hésitez pas à me contacter.
+ Je vous répondrai dans les plus brefs délais.
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/images/CodeFirstLogo.png b/images/CodeFirstLogo.png
deleted file mode 100644
index a9741c8..0000000
Binary files a/images/CodeFirstLogo.png and /dev/null differ
diff --git a/images/My_face.png b/images/My_face.png
new file mode 100644
index 0000000..2bd9c2f
Binary files /dev/null and b/images/My_face.png differ
diff --git a/images/atelier_merienne.png b/images/atelier_merienne.png
new file mode 100644
index 0000000..7ccba54
Binary files /dev/null and b/images/atelier_merienne.png differ
diff --git a/images/atelier_merienne2.png b/images/atelier_merienne2.png
new file mode 100644
index 0000000..82a6909
Binary files /dev/null and b/images/atelier_merienne2.png differ
diff --git a/images/duckandcover.png b/images/duckandcover.png
new file mode 100644
index 0000000..3a6caa2
Binary files /dev/null and b/images/duckandcover.png differ
diff --git a/images/duckandcover2.png b/images/duckandcover2.png
new file mode 100644
index 0000000..4f0f89a
Binary files /dev/null and b/images/duckandcover2.png differ
diff --git a/images/duckandcover3.png b/images/duckandcover3.png
new file mode 100644
index 0000000..fe0e9e1
Binary files /dev/null and b/images/duckandcover3.png differ
diff --git a/images/duckandcover4.png b/images/duckandcover4.png
new file mode 100644
index 0000000..dae652f
Binary files /dev/null and b/images/duckandcover4.png differ
diff --git a/images/skillupnow.png b/images/skillupnow.png
new file mode 100644
index 0000000..b45d568
Binary files /dev/null and b/images/skillupnow.png differ
diff --git a/images/skillupnow2.png b/images/skillupnow2.png
new file mode 100644
index 0000000..643bf97
Binary files /dev/null and b/images/skillupnow2.png differ
diff --git a/images/skillupnow3.png b/images/skillupnow3.png
new file mode 100644
index 0000000..e302cac
Binary files /dev/null and b/images/skillupnow3.png differ
diff --git a/index.html b/index.html
index a297d60..9090fcb 100644
--- a/index.html
+++ b/index.html
@@ -1,34 +1,250 @@
-
-
+
+
- portfoliojules - One incredible styled html page
-
+
+
+ Portfolio - Jules Merienne
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Disponible pour de nouveaux projets
+
+
+
+
+ Bonjour, je suis
+
+ Jules Merienne
+
+
+
+
+ Étudiant et freelance dev web + design , je transforme vos idées en
+ solutions numériques innovantes
+ et performantes.
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+ Ce que je peux faire pour vous
+
+
+ Des solutions complètes pour donner vie à vos projets numériques
+
+
+
+
+
+
+
Développement Fullstack
+
Applications web modernes avec TypeScript, Adonis.js, React et Next.js pour des solutions robustes et performantes
+
+
+
+
+
Applications C#
+
Développement d'applications desktop et web avec C# pour des solutions enterprise robustes et évolutives
+
+
+
+
+
Design UI/UX
+
Création d'interfaces modernes et intuitives avec une attention particulière à l'expérience utilisateur
+
+
+
+
-
-
+
+
+
+ Prêt à concrétiser votre projet ?
+
+
+ Discutons ensemble de vos besoins et transformons vos idées en réalité numérique.
+
+
+
+
+
+ Commençons maintenant
+
+
+
+
-
-portfoliojules is my first page, and it has got style!
+
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/interets.html b/interets.html
new file mode 100644
index 0000000..e2845fc
--- /dev/null
+++ b/interets.html
@@ -0,0 +1,267 @@
+
+
+
+
+
+ Centres d'intérêt - Jules Merienne
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mes Passions
+
+
+ Découvrez mes passions qui enrichissent mon quotidien et ma créativité.
+
+
+
+
+
+
+
+
+
+
+ Parlons de nos passions
+
+
+ Vous partagez ces centres d'intérêt ? Contactez-moi !
+
+
+
+
+
+ Entamons la conversation
+
+
+
+
+
+
+
+
+
+
+ Télécharger CV
+
+
+
+
\ 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/navigation.js b/navigation.js
new file mode 100644
index 0000000..d769e83
--- /dev/null
+++ b/navigation.js
@@ -0,0 +1,371 @@
+function createNavigation(activePage = 'home') {
+ const nav = document.getElementById('navbar');
+ if (!nav) return;
+
+ const currentPath = window.location.pathname;
+ const isInSubdir = currentPath.includes('/projets/') || currentPath.includes('/projects/');
+ const prefix = isInSubdir ? '../' : '';
+
+ nav.innerHTML = `
+
+ `;
+
+ if (!document.getElementById('nav-styles')) {
+ const styles = document.createElement('style');
+ styles.id = 'nav-styles';
+ styles.textContent = `
+ .nav-link {
+ position: relative;
+ font-weight: 500;
+ padding: 12px 20px;
+ border-radius: 8px;
+ color: rgb(75 85 99);
+ text-decoration: none;
+ transition: all 0.3s ease;
+ }
+
+ .nav-link-text {
+ display: inline-block;
+ }
+
+ .nav-link-text .letter {
+ display: inline-block;
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ transform-origin: center bottom;
+ }
+
+ .nav-link:hover .nav-link-text .letter {
+ color: #3b82f6;
+ transform: translateY(-2px) scale(1.05);
+ }
+
+ .nav-link:hover .nav-link-text .letter:nth-child(1) { transition-delay: 0ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(2) { transition-delay: 50ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(3) { transition-delay: 100ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(4) { transition-delay: 150ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(5) { transition-delay: 200ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(6) { transition-delay: 250ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(7) { transition-delay: 300ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(8) { transition-delay: 350ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(9) { transition-delay: 400ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(10) { transition-delay: 450ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(11) { transition-delay: 500ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(12) { transition-delay: 550ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(13) { transition-delay: 600ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(14) { transition-delay: 650ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(15) { transition-delay: 700ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(16) { transition-delay: 750ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(17) { transition-delay: 800ms; }
+ .nav-link:hover .nav-link-text .letter:nth-child(18) { transition-delay: 850ms; }
+
+ .nav-link::after {
+ content: '';
+ position: absolute;
+ bottom: 8px;
+ left: 50%;
+ width: 0;
+ height: 1px;
+ background: linear-gradient(90deg, #3b82f6, #8b5cf6);
+ transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
+ transform: translateX(-50%);
+ }
+
+ .nav-link:hover::after {
+ width: 80%;
+ }
+
+ .nav-link-active {
+ color: rgb(37 99 235);
+ font-weight: 600;
+ }
+
+ .nav-link-active::after {
+ width: 80%;
+ }
+
+ .nav-link-active .nav-link-text .letter {
+ color: #3b82f6;
+ }
+
+ .mobile-nav-link {
+ display: block;
+ padding: 8px 12px;
+ font-weight: 500;
+ border-radius: 6px;
+ transition: all 0.2s;
+ overflow: hidden;
+ position: relative;
+ }
+
+ .mobile-nav-text {
+ display: inline-block;
+ }
+
+ .mobile-nav-text .letter {
+ display: inline-block;
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ transform-origin: center bottom;
+ }
+
+ .mobile-nav-link:hover .mobile-nav-text .letter {
+ color: #3b82f6;
+ transform: translateY(-2px) scale(1.05);
+ }
+
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(1) { transition-delay: 0ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(2) { transition-delay: 50ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(3) { transition-delay: 100ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(4) { transition-delay: 150ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(5) { transition-delay: 200ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(6) { transition-delay: 250ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(7) { transition-delay: 300ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(8) { transition-delay: 350ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(9) { transition-delay: 400ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(10) { transition-delay: 450ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(11) { transition-delay: 500ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(12) { transition-delay: 550ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(13) { transition-delay: 600ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(14) { transition-delay: 650ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(15) { transition-delay: 700ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(16) { transition-delay: 750ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(17) { transition-delay: 800ms; }
+ .mobile-nav-link:hover .mobile-nav-text .letter:nth-child(18) { transition-delay: 850ms; }
+
+ .mobile-nav-link::after {
+ content: '';
+ position: absolute;
+ bottom: 4px;
+ left: 50%;
+ width: 0;
+ height: 1px;
+ background: linear-gradient(90deg, #3b82f6, #8b5cf6);
+ transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
+ transform: translateX(-50%);
+ }
+
+ .mobile-nav-link:hover::after {
+ width: 80%;
+ }
+
+ .btn-primary-nav {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 10px 24px;
+ font-size: 14px;
+ font-weight: 600;
+ color: white;
+ background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
+ border-radius: 12px;
+ border: none;
+ transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
+ box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
+ overflow: hidden;
+ cursor: pointer;
+ }
+
+ .btn-primary-nav:hover {
+ transform: translateY(-3px) scale(1.02);
+ box-shadow: 0 8px 25px rgba(59, 130, 246, 0.4);
+ background: linear-gradient(135deg, #2563eb 0%, #1e40af 100%);
+ }
+
+ .btn-primary-nav::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: -100%;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
+ transition: left 0.6s ease;
+ }
+
+ .btn-primary-nav:hover::before {
+ left: 100%;
+ }
+
+ .btn-primary-nav:active {
+ transform: translateY(-1px) scale(0.98);
+ transition: all 0.1s ease;
+ }
+ `;
+ document.head.appendChild(styles);
+ }
+
+ if (!document.getElementById('cv-download-btn')) {
+ const cvButton = document.createElement('a');
+ cvButton.id = 'cv-download-btn';
+ cvButton.href = '../assets/cv.pdf';
+ cvButton.className = 'cv-download-btn';
+ cvButton.download = true;
+ cvButton.title = 'Télécharger mon CV';
+ cvButton.innerHTML = `Télécharger CV `;
+ document.body.appendChild(cvButton);
+ }
+
+ function splitTextIntoLetters() {
+ const navLinks = document.querySelectorAll('.nav-link-text, .mobile-nav-text');
+ navLinks.forEach(link => {
+ const text = link.textContent;
+ link.innerHTML = text.split('').map(letter =>
+ letter === ' ' ? ' ' : `${letter} `
+ ).join('');
+ });
+ }
+
+ const mobileMenuButton = document.getElementById('mobile-menu-button');
+ const mobileMenu = document.getElementById('mobile-menu');
+ const menuIcon = document.getElementById('menu-icon');
+ const closeIcon = document.getElementById('close-icon');
+ let isMobileMenuOpen = false;
+
+ mobileMenuButton.addEventListener('click', () => {
+ isMobileMenuOpen = !isMobileMenuOpen;
+
+ if (isMobileMenuOpen) {
+ mobileMenu.style.maxHeight = '384px';
+ mobileMenu.style.opacity = '1';
+ menuIcon.classList.add('hidden');
+ closeIcon.classList.remove('hidden');
+ } else {
+ mobileMenu.style.maxHeight = '0';
+ mobileMenu.style.opacity = '0';
+ menuIcon.classList.remove('hidden');
+ closeIcon.classList.add('hidden');
+ }
+ });
+
+ splitTextIntoLetters();
+}
+
+function initNavigation(activePage) {
+ createNavigation(activePage);
+}
+
+if (typeof module !== 'undefined' && module.exports) {
+ module.exports = { initNavigation };
+}
\ No newline at end of file
diff --git a/projets.html b/projets.html
new file mode 100644
index 0000000..acf237c
--- /dev/null
+++ b/projets.html
@@ -0,0 +1,192 @@
+
+
+
+
+
+ Projets - Jules Merienne
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mes Projets
+
+
+ Découvrez une sélection de mes réalisations, alliant créativité et expertise technique.
+
+
+
+
+
+
+
+ Vous avez un projet en tête ?
+
+
+ Discutons ensemble de votre vision et donnons vie à vos idées.
+
+
+
+
+
+ Contactez-moi
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Télécharger CV
+
+
+
+
\ No newline at end of file
diff --git a/projets/ateliermerienne.html b/projets/ateliermerienne.html
new file mode 100644
index 0000000..d1319e2
--- /dev/null
+++ b/projets/ateliermerienne.html
@@ -0,0 +1,373 @@
+
+
+
+
+
+ Site E-commerce - Jules Merienne
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Atelier Merienne 🛍️
+
+
+
+
Projet personnel complet
+
+ Résumé : Développement complet d'un site e-commerce pour un atelier de maroquinerie,
+ proposant des produits en cuir, des réparations et des créations sur mesure. Le site inclut un back office
+ intégré pour la gestion des produits, des stocks et des commandes. Ce projet m'a permis de développer
+ mes compétences en développement d'application (C1) , optimisation d'applications (C2) ,
+ et gestion de projet (C5) .
+
+
+
+
+ AdonisJS
+ TypeScript
+ React
+ Tailwind CSS
+ Figma
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
À propos du projet
+
+
+
+ Ce projet est un site e-commerce complet développé pour un atelier de maroquinerie, proposant
+ une gamme de produits en cuir, des services de réparation et des créations sur mesure. L'objectif
+ était de créer une plateforme moderne et intuitive permettant aux clients de découvrir les produits
+ et services, tout en offrant une gestion efficace des commandes et du stock.
+
+
+
Fonctionnalités développées
+
+
+
+
+
+ Catalogue de produits en maroquinerie
+
+
+
+
+
+ Réservation de services de réparation
+
+
+
+
+
+ Demandes de créations sur mesure
+
+
+
+
+
+ Gestion des stocks en temps réel
+
+
+
+
+
+ Suivi des commandes et réparations
+
+
+
+
+
+ Interface d'administration intuitive
+
+
+
+
+
+
+
+
+
Informations du projet
+
+
+
+
+
+
+
+
Mon rôle
+
Développeur Full Stack
+
+
+
+
Technologies
+
AdonisJS, TypeScript, React
+
+
+
+
+
+
+
+
+
Compétences développées
+
+
+
+
+ C1
+
+
+
Développement d'application
+
Full Stack, TypeScript, React, Inertia.js
+
+
+
+
+
+ C2
+
+
+
Optimisation d'applications
+
Performance, SEO, Expérience utilisateur
+
+
+
+
+
+ C5
+
+
+
Gestion de projet
+
Planning, Organisation, Méthodologie
+
+
+
+
+
+
+
+
+
+
+
+
+
Architecture technique
+
+
+
+
+
Frontend (React + Inertia.js)
+
Interface utilisateur moderne avec Tailwind CSS, animations fluides et design responsive, intégrée avec Inertia.js pour une expérience SPA.
+
+
+
+
+
Backend (AdonisJS)
+
Application full-stack avec AdonisJS et Inertia.js, permettant une intégration transparente entre le frontend et le backend.
+
+
+
+
+
Base de données
+
Modèle de données optimisé pour les performances et la scalabilité, avec gestion efficace des relations et des transactions.
+
+
+
+
+
+
+
+
+
+ Vous avez un projet e-commerce ?
+
+
+ De la conception à la réalisation, je peux vous accompagner dans votre projet avec une approche complète alliant design et développement.
+
+
+
+
+
+
+
+
+
+
+
+
+ Télécharger CV
+
+
+
+
\ No newline at end of file
diff --git a/projets/duckandcover.html b/projets/duckandcover.html
new file mode 100644
index 0000000..10788cc
--- /dev/null
+++ b/projets/duckandcover.html
@@ -0,0 +1,374 @@
+
+
+
+
+
+ DuckAndCover - Jules Merienne
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ DuckAndCover 🦆
+
+
+
+
Réalisation technique de l'année en cours
+
+ Résumé : J'ai réalisé, en équipe de 4, la transformation du jeu de plateau DuckAndCover en jeu numérique.
+ Mon rôle a combiné développement et gestion de projet. Développé en C# .NET MAUI avec XAML, j'ai porté une attention
+ particulière à l'architecture évolutive et aux performances. J'ai mis en place un système de branches Git pour le travail
+ collaboratif et utilisé ClickUp pour la gestion de projet (planning, temps, attribution des tâches). Ce projet m'a permis
+ de développer mes compétences en développement d'applications (C1) , optimisation (C2) et
+ gestion de projet (C5) , tout en contribuant à la collaboration d'équipe (C6) .
+
+
+
+
+ C# .NET MAUI
+ XAML
+ Git/Branches
+ ClickUp
+ Multijoueur Local
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
À propos du projet
+
+
+
+ DuckAndCover est un projet de transformation numérique d'un jeu de plateau existant.
+ L'objectif était de créer une version digitale fidèle tout en apportant des améliorations
+ comme l'intelligence artificielle et une interface moderne.
+
+
+
Le jeu original
+
+ DuckAndCover est un jeu multijoueur local (2-7 joueurs) où les participants incarnent des canards
+ dans un univers coloré. L'objectif est de finir avec le moins de points possible après 3 manches.
+ Une manche se termine quand il ne reste qu'une pile à un joueur ou quand le nombre de joueurs +
+ cartes en défausse égale 11.
+
+
+
Fonctionnalités développées
+
+
+
+
+
+ Interface utilisateur intuitive en XAML
+
+
+
+
+
+ Multijoueur local jusqu'à 7 joueurs
+
+
+
+
+
+ Intelligence artificielle pour compléter les parties
+
+
+
+
+
+ Architecture évolutive et maintenable
+
+
+
+
+
+ Animations et effets visuels engageants
+
+
+
+
+
+ Compatibilité cross-platform (Windows, Android, iOS)
+
+
+
+
+
+
+
+
+
Informations du projet
+
+
+
+
+
+
Équipe
+
2 développeurs
+
+
+
+
Mon rôle
+
Développeur
+
+
+
+
Plateformes
+
Windows, Android, iOS
+
+
+
+
+
+
+
+
+
Compétences développées
+
+
+
+
+ C1
+
+
+
Développement d'application
+
Architecture MVVM, C# .NET MAUI
+
+
+
+
+
+ C2
+
+
+
Optimisation d'applications
+
Performance, mémoire, animations
+
+
+
+
+
+ C5
+
+
+
Gestion de projet
+
ClickUp, planning, coordination équipe
+
+
+
+
+
+ C6
+
+
+
Collaboration d'équipe
+
Git, branches, travail collaboratif
+
+
+
+
+
+
+
+
+
+
+
+
+
Architecture technique
+
+
+
+
+
Frontend (XAML)
+
Interface utilisateur responsive avec animations fluides et design moderne adapté au multijoueur local.
+
+
+
+
+
Backend (C#)
+
Logique métier robuste avec gestion d'état, intelligence artificielle et mécaniques de jeu optimisées.
+
+
+
+
+
Architecture MVVM
+
Séparation claire des responsabilités pour une maintenance facilitée et une évolutivité optimale.
+
+
+
+
+
+
+
+
+
+ Vous avez un projet de jeu ou d'application ?
+
+
+ De l'idée à la réalisation, je peux vous accompagner dans votre projet avec une approche complète alliant développement et gestion.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Télécharger CV
+
+
+
+
\ No newline at end of file
diff --git a/projets/skillupnow.html b/projets/skillupnow.html
new file mode 100644
index 0000000..e6e8d01
--- /dev/null
+++ b/projets/skillupnow.html
@@ -0,0 +1,282 @@
+
+
+
+
+
+ SkillUpNow - Jules Merienne
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SkillUpNow 🎮
+
+
+
+
Design d'interface pour une marketplace de coaching gaming
+
+ Résumé : Design d'interface pour une marketplace de coaching gaming, connectant joueurs et coachs professionnels.
+ J'ai créé une expérience utilisateur intuitive et moderne, facilitant la découverte et la réservation de séances de coaching.
+
+
+
+
+ Figma
+ UI/UX Design
+ Prototypage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
À propos du projet
+
+
+
+ SkillUpNow est une marketplace innovante dédiée au coaching gaming, permettant aux joueurs de
+ trouver et réserver des séances avec des coachs professionnels. Mon rôle était de concevoir
+ une interface intuitive et moderne qui facilite la découverte et la réservation de séances.
+
+
+
Contexte
+
+ Le projet visait à créer une plateforme qui connecte les joueurs souhaitant améliorer leurs
+ compétences avec des coachs professionnels. L'enjeu principal était de concevoir une interface
+ qui rende le processus de recherche et de réservation de coaching simple et agréable.
+
+
+
Mon Rôle
+
+ En tant que designer d'interface, j'ai été responsable de la conception de l'expérience utilisateur
+ complète, de la recherche initiale jusqu'au prototypage final. J'ai travaillé en étroite collaboration
+ avec l'équipe de développement pour assurer une implémentation fidèle des designs.
+
+
+
Processus de Design
+
+ Le processus de design a commencé par une analyse approfondie des besoins des utilisateurs et des
+ coachs. J'ai ensuite créé des wireframes et des prototypes interactifs pour tester différentes
+ approches de l'interface. Les retours des utilisateurs ont guidé les itérations successives jusqu'à
+ l'obtention d'une expérience optimale.
+
+
+
Fonctionnalités Clés
+
+
+
+
+
+ Interface de recherche intuitive avec filtres avancés
+
+
+
+
+
+ Profils de coachs détaillés avec système de notation
+
+
+
+
+
+ Processus de réservation simplifié en quelques clics
+
+
+
+
+
+ Système de messagerie intégré pour la communication
+
+
+
+
Résultats
+
+ Le design final a été très bien accueilli par les utilisateurs, avec une augmentation significative
+ des réservations et une réduction du temps nécessaire pour trouver et réserver un coach. L'interface
+ intuitive a contribué à une meilleure rétention des utilisateurs et à une expérience globale positive.
+
+
+
+
+
+
+
+
Informations du projet
+
+
+
+
+
+
+
+
Mon rôle
+
Designer d'interface
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Télécharger CV
+
+
+
+
\ No newline at end of file
diff --git a/slider.css b/slider.css
new file mode 100644
index 0000000..bf8aac0
--- /dev/null
+++ b/slider.css
@@ -0,0 +1,36 @@
+.slider-container {
+ position: relative;
+ overflow: hidden;
+}
+
+.slider-wrapper {
+ display: flex;
+ transition: transform 0.5s ease-in-out;
+}
+
+.slider-slide {
+ min-width: 100%;
+}
+
+.slider-nav {
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
+ background-color: rgba(255, 255, 255, 0.8);
+ padding: 0.5rem;
+ border-radius: 9999px;
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
+ transition: all 0.3s ease;
+}
+
+.slider-nav:hover {
+ background-color: white;
+}
+
+.slider-nav.prev {
+ left: 0.5rem;
+}
+
+.slider-nav.next {
+ right: 0.5rem;
+}
\ No newline at end of file
diff --git a/slider.js b/slider.js
new file mode 100644
index 0000000..5189133
--- /dev/null
+++ b/slider.js
@@ -0,0 +1,26 @@
+function initSlider() {
+ const sliderWrapper = document.querySelector('.slider-wrapper');
+ const slides = document.querySelectorAll('.slider-slide');
+ const prevBtn = document.querySelector('.slider-nav.prev');
+ const nextBtn = document.querySelector('.slider-nav.next');
+ let currentSlide = 0;
+
+ function updateSlider() {
+ sliderWrapper.style.transform = `translateX(-${currentSlide * 100}%)`;
+ }
+
+ prevBtn.addEventListener('click', () => {
+ currentSlide = (currentSlide - 1 + slides.length) % slides.length;
+ updateSlider();
+ });
+
+ nextBtn.addEventListener('click', () => {
+ currentSlide = (currentSlide + 1) % slides.length;
+ updateSlider();
+ });
+
+ setInterval(() => {
+ currentSlide = (currentSlide + 1) % slides.length;
+ updateSlider();
+ }, 5000);
+}
\ No newline at end of file
diff --git a/styles.css b/styles.css
new file mode 100644
index 0000000..6183e14
--- /dev/null
+++ b/styles.css
@@ -0,0 +1,595 @@
+/* ========================================
+ PORTFOLIO - JULES MERIENNE
+ Styles principaux
+======================================== */
+
+/* Variables CSS */
+:root {
+ --primary-blue: #3b82f6;
+ --primary-dark: #1d4ed8;
+ --secondary-blue: #2563eb;
+ --secondary-dark: #1e40af;
+ --purple-600: #9333ea;
+ --purple-500: #a855f7;
+ --green-500: #10b981;
+ --gray-900: #111827;
+ --gray-800: #1f2937;
+ --gray-700: #374151;
+ --gray-600: #4b5563;
+ --gray-50: #f9fafb;
+ --white: #ffffff;
+ --gradient-primary: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
+ --gradient-secondary: linear-gradient(135deg, #2563eb 0%, #1e40af 100%);
+ --shadow-primary: 0 4px 15px rgba(59, 130, 246, 0.3);
+ --shadow-primary-hover: 0 8px 25px rgba(59, 130, 246, 0.4);
+ --timing: cubic-bezier(0.4, 0, 0.2, 1);
+ --timing-magnetic: cubic-bezier(0.23, 1, 0.32, 1);
+}
+
+/* Base styles */
+body {
+ font-family: 'Inter', sans-serif;
+}
+
+/* ========================================
+ ANIMATIONS
+======================================== */
+
+/* Animation base styles */
+.animate-on-scroll {
+ opacity: 0;
+ transform: translateY(30px);
+ transition: all 0.8s var(--timing);
+}
+
+.animate-on-scroll.visible {
+ opacity: 1;
+ transform: translateY(0);
+}
+
+.animate-fade-up {
+ opacity: 1;
+ transform: translateY(0);
+}
+
+.animate-slide-right {
+ opacity: 1;
+ transform: translateX(0);
+}
+
+.animate-scale-up {
+ opacity: 1;
+ transform: scale(1);
+}
+
+.magnetic {
+ transition: all 0.2s var(--timing);
+}
+
+/* Form focus animations */
+input:focus,
+select:focus,
+textarea:focus {
+ transform: translateY(-1px);
+ box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
+}
+
+/* ========================================
+ BUTTONS
+======================================== */
+
+.btn-primary {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 14px 32px;
+ font-size: 16px;
+ font-weight: 600;
+ color: var(--white);
+ background: var(--gradient-primary);
+ border-radius: 12px;
+ border: none;
+ transition: all 0.3s var(--timing-magnetic);
+ box-shadow: var(--shadow-primary);
+ overflow: hidden;
+ cursor: pointer;
+}
+
+.btn-primary-orange {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 14px 32px;
+ font-size: 16px;
+ font-weight: 600;
+ color: var(--white);
+ background: linear-gradient(135deg, #f97316 0%, #ea580c 100%);
+ border-radius: 12px;
+ border: none;
+ transition: all 0.3s var(--timing-magnetic);
+ box-shadow: 0 4px 15px rgba(249, 115, 22, 0.3);
+ overflow: hidden;
+ cursor: pointer;
+}
+
+.btn-primary-orange:hover {
+ transform: translateY(-2px);
+ background: linear-gradient(135deg, #ea580c 0%, #c2410c 100%);
+ box-shadow: 0 8px 25px rgba(249, 115, 22, 0.4);
+}
+
+.btn-primary-orange::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: -100%;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
+ transition: left 0.6s ease;
+}
+
+.btn-primary-orange:hover::before {
+ left: 100%;
+}
+
+.btn-primary-orange:active {
+ transform: translateY(-1px) scale(0.98);
+ transition: all 0.1s ease;
+}
+
+.btn-primary:hover {
+ transform: translateY(-2px);
+ box-shadow: var(--shadow-primary-hover);
+ background: var(--gradient-secondary);
+}
+
+.btn-primary::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: -100%;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
+ transition: left 0.6s ease;
+}
+
+.btn-primary:hover::before {
+ left: 100%;
+}
+
+.btn-primary:active {
+ transform: translateY(-1px) scale(0.98);
+ transition: all 0.1s ease;
+}
+
+.btn-secondary {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 14px 32px;
+ font-size: 16px;
+ font-weight: 600;
+ color: #374151;
+ background: var(--white);
+ border-radius: 12px;
+ border: 2px solid #e5e7eb;
+ transition: all 0.3s ease;
+ cursor: pointer;
+}
+
+.btn-secondary:hover {
+ transform: translateY(-2px);
+ border-color: var(--primary-blue);
+ color: var(--primary-blue);
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
+}
+
+.btn-white {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 14px 32px;
+ font-size: 16px;
+ font-weight: 600;
+ color: var(--primary-dark);
+ background: var(--white);
+ border-radius: 12px;
+ border: none;
+ transition: all 0.3s ease;
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
+ cursor: pointer;
+}
+
+.btn-white:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
+ background: #f8fafc;
+}
+
+.btn-premium {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 14px 32px;
+ font-size: 16px;
+ font-weight: 600;
+ color: var(--white);
+ background: var(--gradient-primary);
+ border-radius: 12px;
+ border: none;
+ transition: all 0.3s var(--timing-magnetic);
+ box-shadow: var(--shadow-primary);
+ overflow: hidden;
+ cursor: pointer;
+}
+
+.btn-premium:hover {
+ transform: translateY(-3px) scale(1.02);
+ box-shadow: var(--shadow-primary-hover);
+ background: var(--gradient-secondary);
+}
+
+.btn-premium::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: -100%;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
+ transition: left 0.6s ease;
+}
+
+.btn-premium:hover::before {
+ left: 100%;
+}
+
+.btn-premium:active {
+ transform: translateY(-1px) scale(0.98);
+ transition: all 0.1s ease;
+}
+
+.btn-outline {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 14px 32px;
+ font-size: 16px;
+ font-weight: 600;
+ color: var(--primary-blue);
+ background: transparent;
+ border-radius: 12px;
+ border: 2px solid var(--primary-blue);
+ transition: all 0.3s var(--timing-magnetic);
+ cursor: pointer;
+}
+
+.btn-outline:hover {
+ transform: translateY(-2px);
+ background: var(--primary-blue);
+ color: var(--white);
+ box-shadow: 0 8px 25px rgba(59, 130, 246, 0.2);
+}
+
+.btn-outline:active {
+ transform: translateY(-1px) scale(0.98);
+ transition: all 0.1s ease;
+}
+
+.btn-outline-orange {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 14px 32px;
+ font-size: 16px;
+ font-weight: 600;
+ color: #f97316;
+ background: transparent;
+ border-radius: 12px;
+ border: 2px solid #f97316;
+ transition: all 0.3s var(--timing-magnetic);
+ cursor: pointer;
+}
+
+.btn-outline-orange:hover {
+ transform: translateY(-2px);
+ background: #f97316;
+ color: var(--white);
+ box-shadow: 0 8px 25px rgba(249, 115, 22, 0.2);
+}
+
+.btn-outline-orange:active {
+ transform: translateY(-1px) scale(0.98);
+ transition: all 0.1s ease;
+}
+
+/* ========================================
+ CARDS & COMPONENTS
+======================================== */
+
+.stats-card {
+ background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
+ border-radius: 16px;
+ padding: 24px;
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
+ transition: all 0.3s var(--timing);
+ border: 1px solid #e5e7eb;
+}
+
+.stats-card:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
+ border-color: var(--primary-blue);
+}
+
+.feature-card {
+ background: var(--white);
+ border-radius: 20px;
+ padding: 32px;
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
+ transition: all 0.3s var(--timing);
+ border: 1px solid #f3f4f6;
+}
+
+.feature-card:hover {
+ transform: translateY(-6px);
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.15);
+ border-color: var(--primary-blue);
+}
+
+.tech-stack-item {
+ display: flex;
+ align-items: center;
+ padding: 12px 20px;
+ background: linear-gradient(135deg, #f8fafc 0%, #ffffff 100%);
+ border-radius: 12px;
+ border: 1px solid #e5e7eb;
+ transition: all 0.3s var(--timing);
+ cursor: pointer;
+}
+
+.tech-stack-item:hover {
+ transform: translateY(-2px) scale(1.02);
+ box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
+ border-color: var(--primary-blue);
+ background: linear-gradient(135deg, #eff6ff 0%, #ffffff 100%);
+}
+
+/* ========================================
+ NAVIGATION ENHANCEMENTS
+======================================== */
+
+.nav-link {
+ position: relative;
+ overflow: hidden;
+}
+
+.nav-link::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 0;
+ height: 2px;
+ background: var(--gradient-primary);
+ transition: width 0.3s var(--timing);
+}
+
+.nav-link:hover::after {
+ width: 100%;
+}
+
+/* ========================================
+ HERO SECTION
+======================================== */
+
+.hero-gradient {
+ background: linear-gradient(135deg, #eff6ff 0%, #ffffff 50%, #f3e8ff 100%);
+ position: relative;
+ overflow: hidden;
+}
+
+.hero-gradient::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-image:
+ radial-gradient(circle at 25% 25%, rgba(59, 130, 246, 0.1) 0%, transparent 50%),
+ radial-gradient(circle at 75% 75%, rgba(147, 51, 234, 0.1) 0%, transparent 50%);
+ pointer-events: none;
+}
+
+.floating-shapes {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ pointer-events: none;
+}
+
+.floating-shape {
+ position: absolute;
+ border-radius: 50%;
+ opacity: 0.6;
+ animation: float 6s ease-in-out infinite;
+}
+
+.floating-shape:nth-child(1) {
+ width: 80px;
+ height: 80px;
+ background: linear-gradient(45deg, #3b82f6, #8b5cf6);
+ top: 20%;
+ left: 10%;
+}
+
+.floating-shape:nth-child(2) {
+ width: 60px;
+ height: 60px;
+ background: linear-gradient(45deg, #10b981, #3b82f6);
+ top: 60%;
+ right: 15%;
+ animation-delay: 2s;
+}
+
+.floating-shape:nth-child(3) {
+ width: 100px;
+ height: 100px;
+ background: linear-gradient(45deg, #8b5cf6, #ec4899);
+ bottom: 20%;
+ left: 20%;
+ animation-delay: 4s;
+}
+
+/* ========================================
+ KEYFRAMES
+======================================== */
+
+@keyframes float {
+ 0%, 100% {
+ transform: translateY(0px) rotate(0deg);
+ }
+ 50% {
+ transform: translateY(-20px) rotate(180deg);
+ }
+}
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ transform: translateY(20px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes slideInRight {
+ from {
+ opacity: 0;
+ transform: translateX(30px);
+ }
+ to {
+ opacity: 1;
+ transform: translateX(0);
+ }
+}
+
+@keyframes scaleIn {
+ from {
+ opacity: 0;
+ transform: scale(0.8);
+ }
+ to {
+ opacity: 1;
+ transform: scale(1);
+ }
+}
+
+/* ========================================
+ RESPONSIVE DESIGN
+======================================== */
+
+@media (max-width: 768px) {
+ .floating-shape {
+ display: none;
+ }
+
+ .stats-card {
+ padding: 20px;
+ }
+
+ .feature-card {
+ padding: 24px;
+ }
+
+ .btn-primary,
+ .btn-secondary,
+ .btn-white,
+ .btn-premium {
+ padding: 12px 24px;
+ font-size: 14px;
+ }
+}
+
+/* ========================================
+ UTILITY CLASSES
+======================================== */
+
+.gradient-text {
+ background: linear-gradient(135deg, var(--primary-blue) 0%, var(--purple-600) 100%);
+ -webkit-background-clip: text;
+ background-clip: text;
+ -webkit-text-fill-color: transparent;
+}
+
+.glassmorphism {
+ background: rgba(255, 255, 255, 0.1);
+ backdrop-filter: blur(10px);
+ border: 1px solid rgba(255, 255, 255, 0.2);
+}
+
+.text-shadow {
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.hover-lift {
+ transition: transform 0.3s var(--timing);
+}
+
+.hover-lift:hover {
+ transform: translateY(-4px);
+}
+
+.cv-download-btn {
+ position: fixed;
+ bottom: 24px;
+ right: 24px;
+ display: flex;
+ align-items: center;
+ gap: 0.5em;
+ padding: 10px 18px;
+ background: #2563eb;
+ color: #fff;
+ border-radius: 8px;
+ font-size: 1rem;
+ font-weight: 500;
+ box-shadow: 0 2px 8px rgba(37,99,235,0.15);
+ border: none;
+ z-index: 1000;
+ cursor: pointer;
+ text-decoration: none;
+ transition: background 0.2s, transform 0.2s;
+}
+
+.cv-download-btn:hover {
+ background: #1d4ed8;
+ transform: translateY(-2px) scale(1.04);
+}
+
+.cv-download-btn svg {
+ width: 18px;
+ height: 18px;
+ margin-left: 4px;
+}
+
+@media (max-width: 600px) {
+ .cv-download-btn {
+ bottom: 12px;
+ right: 12px;
+ padding: 8px 12px;
+ font-size: 0.95rem;
+ }
+}
\ No newline at end of file