diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 0fa6326..38eb6f8 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -12,7 +12,8 @@ "framer-motion": "^11.15.0", "lucide-react": "^0.468.0", "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "react-router-dom": "^6.28.0" }, "devDependencies": { "@eslint/js": "^9.17.0", @@ -996,6 +997,14 @@ "node": ">= 8" } }, + "node_modules/@remix-run/router": { + "version": "1.23.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.1.tgz", + "integrity": "sha512-vDbaOzF7yT2Qs4vO6XV1MHcJv+3dgR1sT+l3B8xxOVhUC336prMvqrvsLL/9Dnw2xr6Qhz4J0dmS0llNAbnUmQ==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.27", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", @@ -3231,6 +3240,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.30.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.2.tgz", + "integrity": "sha512-H2Bm38Zu1bm8KUE5NVWRMzuIyAV8p/JrOaBJAwVmp37AXG72+CZJlEBw6pdn9i5TBgLMhNDgijS4ZlblpHyWTA==", + "dependencies": { + "@remix-run/router": "1.23.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.30.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.2.tgz", + "integrity": "sha512-l2OwHn3UUnEVUqc6/1VMmR1cvZryZ3j3NzapC2eUXO1dB0sYp5mvwdjiXhpUbRb21eFow3qSxpP8Yv6oAU824Q==", + "dependencies": { + "@remix-run/router": "1.23.1", + "react-router": "6.30.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 6143c89..8f7c54a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -12,6 +12,7 @@ "dependencies": { "react": "^18.3.1", "react-dom": "^18.3.1", + "react-router-dom": "^6.28.0", "framer-motion": "^11.15.0", "lucide-react": "^0.468.0", "clsx": "^2.1.1" diff --git a/frontend/public/rosetta.svg b/frontend/public/rosetta.svg index f969811..ae1fbd3 100644 --- a/frontend/public/rosetta.svg +++ b/frontend/public/rosetta.svg @@ -1,6 +1,14 @@ - + + + + + + + + + diff --git a/frontend/public/walid.jpeg b/frontend/public/walid.jpeg new file mode 100644 index 0000000..0775b90 Binary files /dev/null and b/frontend/public/walid.jpeg differ diff --git a/frontend/src/App.css b/frontend/src/App.css index 6eab5a8..ccc0fab 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -57,14 +57,28 @@ .hero-subtitle { margin-top: 1.5rem; - font-size: 1.125rem; - color: var(--color-neutral-600); + font-size: 1.25rem; + font-weight: 500; + color: var(--color-neutral-700); max-width: 32rem; margin-left: auto; margin-right: auto; } :root.dark .hero-subtitle { + color: var(--color-neutral-300); +} + +.hero-tagline { + margin-top: 0.75rem; + font-size: 1rem; + color: var(--color-neutral-500); + max-width: 32rem; + margin-left: auto; + margin-right: auto; +} + +:root.dark .hero-tagline { color: var(--color-neutral-400); } diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 19fcec3..1249beb 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -26,7 +26,7 @@ function App() { className="hero-title" > Excel Translation - Made Simple + Without Breaking It! - Instantly translate your Excel spreadsheets to any language while preserving formatting and structure. + Formulas, formatting, and structure — preserved. + + + Translate Excel. Keep everything intact. @@ -46,7 +54,7 @@ function App() { transition={{ delay: 0.5 }} className="features-section" > -

Supports XLSX and XLS files up to 50MB

+

Supports XLSX files up to 50MB

diff --git a/frontend/src/components/features/about/About.css b/frontend/src/components/features/about/About.css new file mode 100644 index 0000000..31ddff4 --- /dev/null +++ b/frontend/src/components/features/about/About.css @@ -0,0 +1,741 @@ +/* About Section */ +.about-section { + margin-bottom: 3rem; +} + +.about-section-title { + font-size: 1.75rem; + font-weight: 700; + color: var(--color-neutral-900); + text-align: center; + margin-bottom: 1.5rem; +} + +:root.dark .about-section-title { + color: white; +} + +/* Bento Grid Layout */ +.bento-grid { + display: grid; + gap: 1rem; + grid-template-columns: 1fr; +} + +@media (min-width: 768px) { + .bento-grid { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (min-width: 1024px) { + .bento-grid { + grid-template-columns: repeat(3, 1fr); + } +} + +.bento-card { + padding: 1.5rem; + border-radius: 1rem; + background: rgba(255, 255, 255, 0.6); + backdrop-filter: blur(12px); + border: 1px solid rgba(229, 229, 229, 0.6); + transition: transform 0.2s, box-shadow 0.2s; +} + +.bento-card:hover { + transform: translateY(-2px); + box-shadow: 0 12px 32px rgba(0, 0, 0, 0.08); +} + +:root.dark .bento-card { + background: rgba(38, 38, 38, 0.6); + border-color: rgba(64, 64, 64, 0.6); +} + +:root.dark .bento-card:hover { + box-shadow: 0 12px 32px rgba(0, 0, 0, 0.3); +} + +/* Problem card - red accent */ +.bento-card-problem { + border-left: 3px solid #ef4444; +} + +:root.dark .bento-card-problem { + border-left-color: #f87171; +} + +/* How it works card - purple accent */ +.bento-card-how { + border-left: 3px solid var(--color-accent-500); +} + +:root.dark .bento-card-how { + border-left-color: var(--color-accent-400); +} + +/* Result card - green accent */ +.bento-card-result { + border-left: 3px solid #22c55e; +} + +:root.dark .bento-card-result { + border-left-color: #4ade80; +} + +/* AI card - purple accent */ +.bento-card-ai { + border-left: 3px solid var(--color-accent-500); +} + +:root.dark .bento-card-ai { + border-left-color: var(--color-accent-400); +} + +/* Feature cards */ +.bento-card-feature { + text-align: center; + padding: 1.25rem; +} + +.bento-icon-wrapper { + display: inline-flex; + align-items: center; + justify-content: center; + width: 2.75rem; + height: 2.75rem; + border-radius: 0.75rem; + margin-bottom: 0.75rem; +} + +.bento-icon { + width: 1.5rem; + height: 1.5rem; +} + +.bento-icon-sm { + width: 1.25rem; + height: 1.25rem; +} + +/* Icon colors */ +.bento-icon-red { + background: rgba(239, 68, 68, 0.1); + color: #ef4444; +} + +:root.dark .bento-icon-red { + background: rgba(239, 68, 68, 0.2); + color: #f87171; +} + +.bento-icon-green { + background: rgba(34, 197, 94, 0.1); + color: #22c55e; +} + +:root.dark .bento-icon-green { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; +} + +.bento-icon-purple { + background: rgba(139, 92, 246, 0.1); + color: var(--color-accent-600); +} + +:root.dark .bento-icon-purple { + background: rgba(139, 92, 246, 0.2); + color: var(--color-accent-400); +} + +.bento-icon-blue { + background: rgba(59, 130, 246, 0.1); + color: #3b82f6; +} + +:root.dark .bento-icon-blue { + background: rgba(59, 130, 246, 0.2); + color: #60a5fa; +} + +.bento-icon-yellow { + background: rgba(234, 179, 8, 0.1); + color: #ca8a04; +} + +:root.dark .bento-icon-yellow { + background: rgba(234, 179, 8, 0.2); + color: #facc15; +} + +.bento-icon-teal { + background: rgba(20, 184, 166, 0.1); + color: #14b8a6; +} + +:root.dark .bento-icon-teal { + background: rgba(20, 184, 166, 0.2); + color: #2dd4bf; +} + +.bento-card-title { + font-size: 1.125rem; + font-weight: 600; + color: var(--color-neutral-900); + margin-bottom: 0.5rem; +} + +:root.dark .bento-card-title { + color: white; +} + +.bento-card-text { + font-size: 0.9375rem; + line-height: 1.6; + color: var(--color-neutral-600); +} + +:root.dark .bento-card-text { + color: var(--color-neutral-400); +} + +.bento-feature-title { + font-size: 0.9375rem; + font-weight: 600; + color: var(--color-neutral-900); + margin-bottom: 0.25rem; +} + +:root.dark .bento-feature-title { + color: white; +} + +.bento-feature-text { + font-size: 0.8125rem; + color: var(--color-neutral-500); +} + +:root.dark .bento-feature-text { + color: var(--color-neutral-400); +} + +/* Profile Header */ +.profile-header { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + gap: 1.25rem; + padding: 1.5rem; + margin-bottom: 1.5rem; + border-radius: 1rem; + background: rgba(255, 255, 255, 0.6); + backdrop-filter: blur(12px); + border: 1px solid rgba(229, 229, 229, 0.6); +} + +:root.dark .profile-header { + background: rgba(38, 38, 38, 0.6); + border-color: rgba(64, 64, 64, 0.6); +} + +@media (min-width: 640px) { + .profile-header { + flex-direction: row; + text-align: left; + padding: 2rem; + } +} + +.profile-avatar { + width: 5rem; + height: 5rem; + border-radius: 50%; + overflow: hidden; + flex-shrink: 0; + box-shadow: 0 4px 12px rgba(139, 92, 246, 0.3); +} + +.profile-avatar-img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.profile-avatar-placeholder { + font-size: 1.25rem; + font-weight: 700; + color: white; +} + +.profile-info { + flex: 1; +} + +.profile-name { + font-size: 1.375rem; + font-weight: 700; + color: var(--color-neutral-900); + margin-bottom: 0.125rem; +} + +:root.dark .profile-name { + color: white; +} + +.profile-title { + font-size: 0.9375rem; + color: var(--color-neutral-600); + margin-bottom: 0.5rem; +} + +:root.dark .profile-title { + color: var(--color-neutral-400); +} + +.profile-meta { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; + align-items: center; + justify-content: center; +} + +@media (min-width: 640px) { + .profile-meta { + justify-content: flex-start; + } +} + +.profile-location { + display: inline-flex; + align-items: center; + gap: 0.25rem; + font-size: 0.8125rem; + color: var(--color-neutral-500); +} + +:root.dark .profile-location { + color: var(--color-neutral-500); +} + +.profile-meta-icon { + width: 0.875rem; + height: 0.875rem; +} + +.profile-cta { + font-size: 0.75rem; + font-weight: 500; + color: var(--color-accent-600); + background: var(--color-accent-100); + padding: 0.25rem 0.625rem; + border-radius: 1rem; +} + +:root.dark .profile-cta { + background: rgba(139, 92, 246, 0.2); + color: var(--color-accent-400); +} + +.profile-links { + display: flex; + gap: 0.5rem; + flex-wrap: wrap; +} + +.profile-link { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.75rem 1.25rem; + border-radius: 0.625rem; + font-size: 0.9375rem; + font-weight: 500; + text-decoration: none; + transition: all 0.15s; +} + +.profile-link svg { + width: 1.25rem; + height: 1.25rem; +} + +.profile-link-linkedin { + background: rgba(10, 102, 194, 0.1); + color: #0a66c2; +} + +.profile-link-linkedin:hover { + background: rgba(10, 102, 194, 0.2); +} + +:root.dark .profile-link-linkedin { + background: rgba(10, 102, 194, 0.2); + color: #4d9fea; +} + +.profile-link-github { + background: var(--color-neutral-100); + color: var(--color-neutral-700); +} + +.profile-link-github:hover { + background: var(--color-neutral-200); +} + +:root.dark .profile-link-github { + background: var(--color-neutral-800); + color: var(--color-neutral-300); +} + +:root.dark .profile-link-github:hover { + background: var(--color-neutral-700); +} + +.profile-link-email { + background: rgba(139, 92, 246, 0.1); + color: var(--color-accent-600); +} + +.profile-link-email:hover { + background: rgba(139, 92, 246, 0.2); +} + +:root.dark .profile-link-email { + background: rgba(139, 92, 246, 0.2); + color: var(--color-accent-400); +} + +/* Profile Intro */ +.profile-intro { + font-size: 0.9375rem; + line-height: 1.7; + color: var(--color-neutral-600); + margin-bottom: 2rem; +} + +:root.dark .profile-intro { + color: var(--color-neutral-400); +} + +/* Timeline - Grid Layout */ +.timeline-container { + width: 100%; +} + +.timeline-grid { + display: grid; + gap: 0.75rem; + grid-template-columns: 1fr; +} + +@media (min-width: 640px) { + .timeline-grid { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (min-width: 1024px) { + .timeline-grid { + grid-template-columns: repeat(3, 1fr); + } +} + +@media (min-width: 1280px) { + .timeline-grid { + grid-template-columns: repeat(4, 1fr); + } +} + +.timeline-card { + padding: 1.25rem; + border-radius: 0.75rem; + background: rgba(255, 255, 255, 0.5); + backdrop-filter: blur(8px); + border: 1px solid rgba(229, 229, 229, 0.5); + transition: transform 0.2s, box-shadow 0.2s; +} + +.timeline-card:hover { + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06); +} + +:root.dark .timeline-card { + background: rgba(38, 38, 38, 0.5); + border-color: rgba(64, 64, 64, 0.5); +} + +:root.dark .timeline-card:hover { + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2); +} + +.timeline-card-header { + display: flex; + align-items: center; + gap: 0.625rem; + margin-bottom: 0.75rem; +} + +.timeline-card-icon { + display: flex; + align-items: center; + justify-content: center; + width: 2rem; + height: 2rem; + border-radius: 0.5rem; + flex-shrink: 0; +} + +.timeline-card-icon svg { + width: 1rem; + height: 1rem; +} + +/* Timeline icon colors */ +.timeline-icon-blue { + background: rgba(59, 130, 246, 0.1); + color: #3b82f6; +} + +:root.dark .timeline-icon-blue { + background: rgba(59, 130, 246, 0.2); + color: #60a5fa; +} + +.timeline-icon-slate { + background: rgba(100, 116, 139, 0.1); + color: #64748b; +} + +:root.dark .timeline-icon-slate { + background: rgba(100, 116, 139, 0.2); + color: #94a3b8; +} + +.timeline-icon-green { + background: rgba(34, 197, 94, 0.1); + color: #22c55e; +} + +:root.dark .timeline-icon-green { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; +} + +.timeline-icon-yellow { + background: rgba(234, 179, 8, 0.1); + color: #ca8a04; +} + +:root.dark .timeline-icon-yellow { + background: rgba(234, 179, 8, 0.2); + color: #facc15; +} + +.timeline-icon-red { + background: rgba(239, 68, 68, 0.1); + color: #ef4444; +} + +:root.dark .timeline-icon-red { + background: rgba(239, 68, 68, 0.2); + color: #f87171; +} + +.timeline-icon-purple { + background: rgba(139, 92, 246, 0.1); + color: var(--color-accent-600); +} + +:root.dark .timeline-icon-purple { + background: rgba(139, 92, 246, 0.2); + color: var(--color-accent-400); +} + +.timeline-icon-accent { + background: rgba(139, 92, 246, 0.15); + color: var(--color-accent-600); +} + +:root.dark .timeline-icon-accent { + background: rgba(139, 92, 246, 0.25); + color: var(--color-accent-400); +} + +.timeline-card-year { + font-size: 0.6875rem; + font-weight: 600; + color: var(--color-neutral-500); + text-transform: uppercase; + letter-spacing: 0.025em; +} + +:root.dark .timeline-card-year { + color: var(--color-neutral-400); +} + +.timeline-card-title { + font-size: 0.9375rem; + font-weight: 600; + color: var(--color-neutral-900); + margin-bottom: 0.125rem; + line-height: 1.3; +} + +:root.dark .timeline-card-title { + color: white; +} + +.timeline-card-company { + font-size: 0.8125rem; + font-weight: 500; + color: var(--color-accent-600); + margin-bottom: 0.5rem; +} + +:root.dark .timeline-card-company { + color: var(--color-accent-400); +} + +.timeline-card-description { + font-size: 0.8125rem; + color: var(--color-neutral-500); + line-height: 1.5; +} + +:root.dark .timeline-card-description { + color: var(--color-neutral-400); +} + +/* Builder Section */ +.builder-section { + margin-bottom: 2rem; +} + +.builder-section-title { + font-size: 1.75rem; + font-weight: 700; + color: var(--color-neutral-900); + text-align: center; + margin-bottom: 1.5rem; +} + +:root.dark .builder-section-title { + color: white; +} + +/* Publications Section */ +.publications-section { + margin-top: 2rem; + margin-bottom: 2rem; +} + +.publications-title { + font-size: 1.25rem; + font-weight: 600; + color: var(--color-neutral-900); + margin-bottom: 1rem; +} + +:root.dark .publications-title { + color: white; +} + +.publications-grid { + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.publication-card { + display: flex; + align-items: flex-start; + gap: 1rem; + padding: 1.25rem; + border-radius: 0.75rem; + background: rgba(255, 255, 255, 0.5); + backdrop-filter: blur(8px); + border: 1px solid rgba(229, 229, 229, 0.5); + text-decoration: none; + transition: transform 0.2s, box-shadow 0.2s, background 0.2s; +} + +.publication-card:hover { + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06); + background: rgba(255, 255, 255, 0.8); +} + +:root.dark .publication-card { + background: rgba(38, 38, 38, 0.5); + border-color: rgba(64, 64, 64, 0.5); +} + +:root.dark .publication-card:hover { + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2); + background: rgba(38, 38, 38, 0.8); +} + +.publication-icon { + display: flex; + align-items: center; + justify-content: center; + width: 2.5rem; + height: 2.5rem; + border-radius: 0.5rem; + background: rgba(59, 130, 246, 0.1); + color: #3b82f6; + flex-shrink: 0; +} + +:root.dark .publication-icon { + background: rgba(59, 130, 246, 0.2); + color: #60a5fa; +} + +.publication-icon svg { + width: 1.25rem; + height: 1.25rem; +} + +.publication-content { + flex: 1; + min-width: 0; +} + +.publication-card-title { + font-size: 0.9375rem; + font-weight: 600; + color: var(--color-neutral-900); + line-height: 1.4; + margin-bottom: 0.25rem; +} + +:root.dark .publication-card-title { + color: white; +} + +.publication-meta { + font-size: 0.8125rem; + color: var(--color-neutral-500); +} + +:root.dark .publication-meta { + color: var(--color-neutral-400); +} + +.publication-link-icon { + width: 1rem; + height: 1rem; + color: var(--color-neutral-400); + flex-shrink: 0; + margin-top: 0.25rem; +} + +:root.dark .publication-link-icon { + color: var(--color-neutral-500); +} diff --git a/frontend/src/components/features/about/AboutRosetta.tsx b/frontend/src/components/features/about/AboutRosetta.tsx new file mode 100644 index 0000000..778f907 --- /dev/null +++ b/frontend/src/components/features/about/AboutRosetta.tsx @@ -0,0 +1,118 @@ +import { motion } from 'framer-motion'; +import { AlertTriangle, CheckCircle, Bot, Shield, Zap, Globe } from 'lucide-react'; +import './About.css'; + +export function AboutRosetta() { + return ( +
+ + Why Rosetta Exists + + + {/* Bento Grid Layout */} +
+ {/* Row 1: Three equal cards - Problem, Result, Built for AI */} + +
+ +
+

The Problem

+

+ Excel files are fragile. Translate them with standard tools or AI, and you'll break + formulas, destroy formatting, and corrupt cell references. Businesses lose hours + fixing what should have been simple. +

+
+ + +
+ +
+

The Result

+

+ You get back an identical file, just in a different language. Formulas work. + Formatting intact. Merged cells preserved. Nothing breaks. Ever. +

+
+ + +
+ +
+

Built for AI

+

+ Designed as infrastructure for AI. When ChatGPT, Claude, or any AI assistant needs + to translate Excel, Rosetta handles it safely via API or MCP. +

+
+ + {/* Row 2: Feature cards */} + +
+ +
+

Structure Preserved

+

Formulas, formatting, references stay intact

+
+ + +
+ +
+

API-First

+

Built for developers and AI integrations

+
+ + +
+ +
+

Any Language

+

Powered by Claude for accurate translation

+
+
+
+ ); +} diff --git a/frontend/src/components/features/about/ProfileHeader.tsx b/frontend/src/components/features/about/ProfileHeader.tsx new file mode 100644 index 0000000..9656805 --- /dev/null +++ b/frontend/src/components/features/about/ProfileHeader.tsx @@ -0,0 +1,62 @@ +import { motion } from 'framer-motion'; +import { MapPin, Linkedin, Github, Mail } from 'lucide-react'; +import './About.css'; + +export function ProfileHeader() { + return ( + +
+ Walid El M'selmi +
+ +
+

Walid El M'selmi

+

Solutions Engineer · Full-Stack Dev · AI Builder

+
+ + + Paris, France + + Open to AI opportunities +
+
+ +
+ + + LinkedIn + + + + GitHub + + + + Email + +
+
+ ); +} diff --git a/frontend/src/components/features/about/Publications.tsx b/frontend/src/components/features/about/Publications.tsx new file mode 100644 index 0000000..01a995c --- /dev/null +++ b/frontend/src/components/features/about/Publications.tsx @@ -0,0 +1,61 @@ +import { motion } from 'framer-motion'; +import { FileText, ExternalLink } from 'lucide-react'; +import './About.css'; + +const publications = [ + { + title: 'High tissue-specificity of lncRNAs maximises the prediction of tissue of origin of circulating DNA', + journal: 'bioRxiv', + year: '2023', + url: 'https://www.biorxiv.org/content/10.1101/2023.01.19.524838v1', + }, + { + title: 'Integrative systems toxicology to predict human biological systems affected by exposure to environmental chemicals', + journal: 'Toxicology and Applied Pharmacology', + year: '2020', + url: 'https://www.sciencedirect.com/science/article/pii/S0041008X20303367', + }, +]; + +export function Publications() { + return ( +
+ + Scientific Publications + + +
+ {publications.map((pub, index) => ( + +
+ +
+
+

{pub.title}

+

+ {pub.journal} · {pub.year} +

+
+ +
+ ))} +
+
+ ); +} diff --git a/frontend/src/components/features/about/Timeline.tsx b/frontend/src/components/features/about/Timeline.tsx new file mode 100644 index 0000000..7606e9b --- /dev/null +++ b/frontend/src/components/features/about/Timeline.tsx @@ -0,0 +1,94 @@ +import { motion } from 'framer-motion'; +import { Languages, GraduationCap, Building2, MapPin, ShoppingCart, Palette, Briefcase, Bot } from 'lucide-react'; +import './About.css'; + +const timelineData = [ + { + year: '2014-2017', + title: 'Bioinformatics Research', + company: 'Paris Diderot / Institut Curie / Inserm', + description: "Master's in Bioinformatics. Published 2 scientific papers on systems toxicology and circulating DNA.", + icon: GraduationCap, + color: 'blue', + }, + { + year: '2017-2019', + title: 'Full-Stack Developer', + company: 'Infotel', + description: 'Web applications for banks. First professional dev role.', + icon: Building2, + color: 'slate', + }, + { + year: '2019-2021', + title: 'Full-Stack Developer', + company: 'Partoo', + description: 'Local SEO platform serving 40,000+ locations. React, Python, PostgreSQL, MongoDB.', + icon: MapPin, + color: 'green', + }, + { + year: '2021-2022', + title: 'Full-Stack Engineer', + company: 'Gorgias', + description: 'E-commerce helpdesk for 2,500+ businesses. Core team, owned billing system. Python, React.', + icon: ShoppingCart, + color: 'yellow', + }, + { + year: '2022-2023', + title: 'Solutions Consultant', + company: 'Adobe', + description: 'Enterprise pre-sales for Adobe Experience Manager. Technical demos, RFPs, workshops.', + icon: Palette, + color: 'red', + }, + { + year: '2023-Now', + title: 'Solutions Engineer', + company: 'Radancy', + description: 'End-to-end enterprise sales. ~€600k TCV closed in Q3-Q4 2025. Discovery to deal closing.', + icon: Briefcase, + color: 'purple', + }, + { + year: '2024', + title: 'AI Builder', + company: 'Rosetta', + description: 'Building the Excel translation API for AI-first workflows.', + icon: Languages, + color: 'accent', + }, +]; + +export function Timeline() { + return ( +
+
+ {timelineData.map((item, index) => { + const Icon = item.icon; + return ( + +
+
+ +
+ {item.year} +
+

{item.title}

+

{item.company}

+

{item.description}

+
+ ); + })} +
+
+ ); +} diff --git a/frontend/src/components/features/about/index.ts b/frontend/src/components/features/about/index.ts new file mode 100644 index 0000000..cd6a806 --- /dev/null +++ b/frontend/src/components/features/about/index.ts @@ -0,0 +1,4 @@ +export { AboutRosetta } from './AboutRosetta'; +export { ProfileHeader } from './ProfileHeader'; +export { Publications } from './Publications'; +export { Timeline } from './Timeline'; diff --git a/frontend/src/components/layout/Footer.tsx b/frontend/src/components/layout/Footer.tsx index ab8a97d..5832c06 100644 --- a/frontend/src/components/layout/Footer.tsx +++ b/frontend/src/components/layout/Footer.tsx @@ -1,5 +1,4 @@ import { motion } from 'framer-motion'; -import { Heart } from 'lucide-react'; import { Container } from './Container'; import './Layout.css'; @@ -14,9 +13,15 @@ export function Footer() {

- Built with - - using Claude AI + Built by{' '} + + Walid + + · + Powered by Claude AI

+ + About + +