diff --git a/frontend/index.html b/frontend/index.html index 3570690..1618bfc 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -4,6 +4,7 @@ MLBlock + diff --git a/frontend/public/assets/poc-logo.png b/frontend/public/assets/poc-logo.png new file mode 100644 index 0000000..67e751a Binary files /dev/null and b/frontend/public/assets/poc-logo.png differ diff --git a/frontend/public/assets/team/ali.png b/frontend/public/assets/team/ali.png new file mode 100644 index 0000000..a7900ee Binary files /dev/null and b/frontend/public/assets/team/ali.png differ diff --git a/frontend/public/assets/team/chedli.png b/frontend/public/assets/team/chedli.png new file mode 100644 index 0000000..07135f5 Binary files /dev/null and b/frontend/public/assets/team/chedli.png differ diff --git a/frontend/public/assets/team/ilan.png b/frontend/public/assets/team/ilan.png new file mode 100644 index 0000000..84afe55 Binary files /dev/null and b/frontend/public/assets/team/ilan.png differ diff --git a/frontend/public/assets/team/sacha.png b/frontend/public/assets/team/sacha.png new file mode 100644 index 0000000..115a0dc Binary files /dev/null and b/frontend/public/assets/team/sacha.png differ diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 79e8335..4706b3e 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,8 +1,13 @@ import useAppStore from './store/useAppStore' import HomePage from './pages/HomePage' import EditorPage from './pages/EditorPage' +import HowItWorksPage from './pages/HowItWorksPage' +import AboutPage from './pages/AboutPage' export default function App() { const screen = useAppStore(s => s.screen) - return screen === 'build' ? : + if (screen === 'build') return + if (screen === 'how-it-works') return + if (screen === 'about') return + return } diff --git a/frontend/src/components/landing/FeaturesSection.tsx b/frontend/src/components/landing/FeaturesSection.tsx index 199b7d0..2fc2498 100644 --- a/frontend/src/components/landing/FeaturesSection.tsx +++ b/frontend/src/components/landing/FeaturesSection.tsx @@ -1,56 +1,165 @@ -import React from 'react' +import React from 'react'; -type Feature = { color: string; icon: React.ReactNode; title: string; desc: string } +type Feature = { + color: string; + icon: React.ReactNode; + title: string; + desc: string; +}; const FEATURES: Feature[] = [ - { - color: '#E59060', - icon:
, - title: 'Comme un jeu de construction', - desc: "Attrape un bloc, dépose-le dans ton projet. Il s'emboîte tout seul à la bonne place. Aucune ligne à taper.", - }, - { - color: '#B6A0E3', - icon: ( -
-
-
-
-
- ), - title: 'Toutes les IA', - desc: 'Images, textes, tableaux de chiffres : reconnais, classe et prédis avec des modèles simples ou de vrais réseaux de neurones.', - }, - { - color: '#7DAFEA', - icon: , - title: 'Vois-le apprendre', - desc: "Appuie sur Lancer et regarde, tour après tour, ton modèle se tromper de moins en moins et devenir de plus en plus précis.", - }, -] + { + color: '#E59060', + icon: ( +
+ ), + title: 'Comme un jeu de construction', + desc: "Attrape un bloc, dépose-le dans ton projet. Il s'emboîte tout seul à la bonne place. Aucune ligne à taper.", + }, + { + color: '#B6A0E3', + icon: ( +
+
+
+
+
+ ), + title: 'Images, textes, tableaux', + desc: 'Images, textes, tableaux de chiffres : reconnais, classe et prédis avec des modèles simples ou de vrais réseaux de neurones.', + }, + { + color: '#7DAFEA', + icon: , + title: 'Vois-le apprendre', + desc: 'Appuie sur Lancer et regarde, tour après tour, ton modèle se tromper de moins en moins et devenir de plus en plus précis.', + }, +]; export default function FeaturesSection() { - return ( -
-
-

- L'intelligence artificielle, en pièces à assembler -

-

- Chaque étape pour faire apprendre une machine devient un bloc coloré. -

-
- {FEATURES.map(({ color, icon, title, desc }) => ( -
-
- {icon} -
-

{title}

-

{desc}

+ return ( +
+
+

+ L'intelligence artificielle, en pièces à assembler +

+

+ Chaque étape de l'apprentissage devient un bloc. +

+
+ {FEATURES.map(({ color, icon, title, desc }) => ( +
+
+ {icon} +
+

+ {title} +

+

+ {desc} +

+
+ ))} +
- ))} -
-
-
- ) + + ); } diff --git a/frontend/src/components/landing/HeroBlockStack.tsx b/frontend/src/components/landing/HeroBlockStack.tsx index be0966b..a32d112 100644 --- a/frontend/src/components/landing/HeroBlockStack.tsx +++ b/frontend/src/components/landing/HeroBlockStack.tsx @@ -1,5 +1,4 @@ -import React, { useLayoutEffect } from 'react' -import { buildClusters, snapW, blockBorderRadius } from '../../utils/snapLogic' +import React from 'react' type HeroBlock = { key: number @@ -18,29 +17,14 @@ const BLOCKS: HeroBlock[] = [ { key: 4, bg: '#7DAFEA', color: '#2a211c', label: <>Apprendre 10 tours, isLast: true }, ] -export default function HeroBlockStack() { - useLayoutEffect(() => { - const timer = setTimeout(() => { - const els = [...document.querySelectorAll('[data-hero-block]')] - if (!els.length) return - const R = 12 - const widths = els.map(el => el.offsetWidth) - const clusters = buildClusters(widths) - const bands = widths.map(w => snapW(w, clusters) ?? w) - const n = els.length - els.forEach((el, i) => { - el.style.minWidth = bands[i] + 'px' - if (i === 0) { - const br = bands[0] === bands[1] ? '0px' : R + 'px' - el.style.borderRadius = `14px ${br} ${br} 0px` - } else { - el.style.borderRadius = blockBorderRadius(i - 1, n - 1, bands.slice(1), bands[0]) - } - }) - }, 120) - return () => clearTimeout(timer) - }, []) +// Border radii are hardcoded to match the snap-aligned result (all 5 blocks at the same width). +function blockRadius(isHat?: boolean, isLast?: boolean) { + if (isHat) return '14px 0px 0px 0px' + if (isLast) return '0px 0px 12px 12px' + return '0px 0px 0px 0px' +} +export default function HeroBlockStack() { return (
@@ -53,7 +37,6 @@ export default function HeroBlockStack() { {BLOCKS.map(({ key, bg, color, label, isHat, isLast }) => (
{!isHat &&
} diff --git a/frontend/src/components/landing/HeroSection.tsx b/frontend/src/components/landing/HeroSection.tsx index aa86f0a..f08a8c1 100644 --- a/frontend/src/components/landing/HeroSection.tsx +++ b/frontend/src/components/landing/HeroSection.tsx @@ -4,18 +4,21 @@ import HeroBlockStack from './HeroBlockStack' export default function HeroSection() { const goBuild = useAppStore(s => s.goBuild) + const scrollToFeatures = () => + document.getElementById('fonctionnalites')?.scrollIntoView({ behavior: 'smooth' }) + return ( -
+
- SANS CODE · POUR APPRENDRE L'IA + Sans code, pour apprendre l'IA

Crée ton intelligence
artificielle, bloc par bloc.

- Empile des blocs colorés pour construire un modèle qui apprend tout seul : reconnaître des images, comprendre des phrases, deviner des réponses. Pas besoin de savoir programmer, il suffit d'assembler. + Empile des blocs pour construire un modèle qui apprend tout seul : reconnaître des images, comprendre des phrases, prédire des évènements. Pas besoin de savoir programmer, il suffit d'assembler.

- +
+ +
) } diff --git a/frontend/src/components/landing/HomeFooter.tsx b/frontend/src/components/landing/HomeFooter.tsx index 4c135de..bc64a94 100644 --- a/frontend/src/components/landing/HomeFooter.tsx +++ b/frontend/src/components/landing/HomeFooter.tsx @@ -1,8 +1,19 @@ export default function HomeFooter() { - return ( -
- MLBlock — le machine learning en blocs - Fait pour apprendre en s'amusant 🧱 -
- ) + return ( +
+ © 2026 PoC Innovation +
+ ); } diff --git a/frontend/src/components/landing/HomeNav.tsx b/frontend/src/components/landing/HomeNav.tsx index 0f84354..9aaa099 100644 --- a/frontend/src/components/landing/HomeNav.tsx +++ b/frontend/src/components/landing/HomeNav.tsx @@ -1,20 +1,53 @@ +import type { CSSProperties } from 'react' import useAppStore from '../../store/useAppStore' export default function HomeNav() { - const goBuild = useAppStore(s => s.goBuild) + const screen = useAppStore(s => s.screen) + const goBuild = useAppStore(s => s.goBuild) + const goHome = useAppStore(s => s.goHome) + const goHowItWorks = useAppStore(s => s.goHowItWorks) + const goAbout = useAppStore(s => s.goAbout) + + const scrollToFeatures = () => + document.getElementById('fonctionnalites')?.scrollIntoView({ behavior: 'smooth' }) + + const handleDecouvrir = () => { + if (screen === 'home') { + scrollToFeatures() + } else { + goHome() + // After navigation the DOM re-renders; scroll on next tick + setTimeout(scrollToFeatures, 80) + } + } + + const linkStyle = (active: boolean): CSSProperties => ({ + fontSize: 15, + fontWeight: 700, + color: active ? '#E8915F' : '#b7ada3', + cursor: 'pointer', + borderBottom: active ? '2px solid #E8915F' : '2px solid transparent', + paddingBottom: 2, + transition: 'color .15s, border-color .15s', + }) return ( -