diff --git a/app/[locale]/(standalone)/cv-v3/CVV3.tsx b/app/[locale]/(standalone)/cv-v3/CVV3.tsx new file mode 100644 index 0000000..7f97311 --- /dev/null +++ b/app/[locale]/(standalone)/cv-v3/CVV3.tsx @@ -0,0 +1,453 @@ +'use client'; + +import Image from 'next/image'; +import { useMemo } from 'react'; +import { motion, useReducedMotion } from 'framer-motion'; +import { ArrowDown, ArrowUpRight, Download, Mail, MapPin } from 'lucide-react'; +import { useLocale, useMessages } from 'next-intl'; +import { buildCVData, type RawCVMessages } from '@/lib/cv/cv-data'; + +const ease = [0.22, 1, 0.36, 1] as const; +const reveal = { + hidden: { opacity: 0, y: 28 }, + visible: { opacity: 1, y: 0 }, +}; + +export default function CVV3() { + const locale = useLocale(); + const messages = useMessages() as { cv: RawCVMessages }; + const cv = useMemo(() => buildCVData(messages.cv), [messages]); + const reduceMotion = useReducedMotion(); + const isHebrew = locale === 'he'; + const portfolioHref = `/${locale}/portfolio`; + const pdfHref = `/${locale}/cv/render?variant=default`; + + const copy = isHebrew + ? { + portfolio: 'פורטפוליו', + download: 'הורדת PDF', + experience: 'ניסיון', + capabilities: 'יכולות', + work: 'עבודות נבחרות', + foundation: 'השכלה ושפות', + contact: 'יצירת קשר', + scroll: 'לניסיון', + kicker: 'Senior Product Engineer / ברלין', + headline: 'בונה מוצרים מורכבים עד לפרודקשן.', + intro: + 'יותר מעשור של Full-Stack, מסחר, אינטגרציות ו-AI. אני נכנס בשלב שבו הדרישות עדיין לא מסודרות ונשאר עד שהמוצר עובד בצורה אמינה אצל משתמשים אמיתיים.', + proofYears: '10+ שנים', + proofYearsLabel: 'תוכנה בפרודקשן', + proofCuralife: '4+ שנים', + proofCuralifeLabel: 'אחריות מוצרית ב-Curalife', + proofSync: '85%-', + proofSyncLabel: 'כשלי סנכרון', + proofPerf: '60%+', + proofPerfLabel: 'ביצועים במסלולים מרכזיים', + profileTitle: 'מוצר, ארכיטקטורה והוצאה לפועל באותה יד.', + profileBody: + 'אני עובד הכי טוב על מוצרים שבהם צריך לחבר בין החלטות מוצריות לעומק טכני: frontend, backend, APIs, אינטגרציות, דאטה, cloud ואילוצי פרודקשן. הניסיון שלי משלב חברות מוצר, מערכות enterprise, e-commerce ועבודה founder-led.', + recentTitle: 'הניסיון שמגדיר את העבודה שלי היום.', + earlierTitle: 'ניסיון הנדסי מוקדם', + earlierIntro: 'Enterprise integrations, software development ויזמות טכנולוגית משנת 2011.', + skillsTitle: 'היכולות שבהן אני הכי חזק.', + workTitle: 'מוצרים שממחישים ownership אמיתי.', + foundationTitle: 'בסיס מקצועי ותקשורת.', + contactTitle: 'מחפש את הבעיה הבאה ששווה לקחת עליה אחריות.', + availability: 'ברלין · אזרח האיחוד האירופי', + viewPortfolio: 'לפורטפוליו המלא', + selectedImpact: 'השפעה', + curalifeImpact: '85% פחות כשלי סנכרון, שיפור של 60% בביצועים, ומוצר טלרפואה שהפך לערוץ רכישה והכנסות מרכזי.', + starlinkerImpact: 'מוצר founder-led שנבנה מהגדרת המוצר והארכיטקטורה ועד agent שפועל בתוך סביבת העבודה.', + rightflowImpact: 'תהליך בדיקה רגיש ורב-מסמכים שהפך ל-workflow מובנה, עקבי וניתן לייצוא.', + cartshiftImpact: 'סטודיו פעיל שמחבר delivery ללקוחות עם בנייה של מוצרי web, commerce ו-AI בפרודקשן.', + } + : { + portfolio: 'Portfolio', + download: 'Download PDF', + experience: 'Experience', + capabilities: 'Capabilities', + work: 'Selected work', + foundation: 'Education & languages', + contact: 'Contact', + scroll: 'Experience', + kicker: 'Senior Product Engineer / Berlin', + headline: 'I build complex products all the way to production.', + intro: + '10+ years across full-stack, commerce, integrations and AI. I work best where requirements are still messy, then stay with the problem until reliable software is in real users’ hands.', + proofYears: '10+ yrs', + proofYearsLabel: 'production software', + proofCuralife: '4+ yrs', + proofCuralifeLabel: 'product ownership at Curalife', + proofSync: '−85%', + proofSyncLabel: 'sync failures', + proofPerf: '+60%', + proofPerfLabel: 'key-journey performance', + profileTitle: 'Product, architecture and execution in one loop.', + profileBody: + 'I am strongest on products where product decisions and technical depth have to move together: frontend, backend, APIs, integrations, data, cloud and production constraints. My background spans product companies, enterprise systems, e-commerce and founder-led software.', + recentTitle: 'The experience that defines how I work today.', + earlierTitle: 'Earlier engineering', + earlierIntro: 'Enterprise integrations, software development and entrepreneurship from 2011 onward.', + skillsTitle: 'The capabilities I rely on most.', + workTitle: 'Products that show real ownership.', + foundationTitle: 'Foundation & communication.', + contactTitle: 'Looking for the next problem worth owning.', + availability: 'Berlin · EU citizen', + viewPortfolio: 'View full portfolio', + selectedImpact: 'Impact', + curalifeImpact: '85% fewer sync failures, 60% better performance, and a telemedicine product that became a primary acquisition and revenue funnel.', + starlinkerImpact: 'Founder-led from product definition and architecture through an AI agent that acts inside the workspace.', + rightflowImpact: 'A sensitive, document-heavy verification process turned into a structured, repeatable workflow with report export.', + cartshiftImpact: 'An active studio combining client delivery with production web, commerce and AI product work.', + }; + + const sectionReveal = reduceMotion + ? { initial: false as const } + : { + variants: reveal, + initial: 'hidden' as const, + whileInView: 'visible' as const, + viewport: { once: true, amount: 0.16 }, + transition: { duration: 0.62, ease }, + }; + + const proof = [ + [copy.proofYears, copy.proofYearsLabel], + [copy.proofCuralife, copy.proofCuralifeLabel], + [copy.proofSync, copy.proofSyncLabel], + [copy.proofPerf, copy.proofPerfLabel], + ]; + + const projects = [ + { + name: 'Curalife', + descriptor: 'Commerce + Digital Health', + impact: copy.curalifeImpact, + href: `/${locale}/work/curalife-metabolic-wellness-platform`, + external: false, + }, + { + name: 'StarLinker', + descriptor: 'AI-native Productivity', + impact: copy.starlinkerImpact, + href: 'https://starlinker.io', + external: true, + }, + { + name: 'RightFlow', + descriptor: 'Document Intelligence', + impact: copy.rightflowImpact, + href: 'https://right-flow.com', + external: true, + }, + { + name: 'CartShift Studio', + descriptor: 'Commerce + Product Engineering', + impact: copy.cartshiftImpact, + href: `https://cart-shift.com/${locale}`, + external: true, + }, + ]; + + return ( +
+
+ +
+ +
+ + +
+ +
+
+ {cv.location} + {copy.availability}
Full-stack · AI · Commerce
+
+ +
+ + {copy.kicker} + + + {copy.headline} + + + {copy.intro} + +
+ +
+ {proof.map(([value, label]) => ( +
+

{value}

+

{label}

+
+ ))} +
+ + + {copy.scroll} + +
+
+ +
+ +

01 / Profile

+
+

{copy.profileTitle}

+
+

{copy.profileBody}

+
+ {[ + ['Location', cv.location], + ['Authorization', cv.workAuthorization], + ['Email', cv.email], + ['Phone', cv.phone], + ].map(([label, value]) => ( +
+ {label} + {value} +
+ ))} +
+
+
+
+
+ +
+
+ +

02 / {copy.experience}

+

{copy.recentTitle}

+
+ +
+ {cv.recentExperiences.map((item, index) => ( + +
+

{String(index + 1).padStart(2, '0')}

+

{item.duration}

+
+
+

{item.company}

+

{item.title}

+ {item.location ?

{item.location}

: null} +
+
+ {item.description ?

{item.description}

: null} +
    + {item.highlights.map(highlight => ( +
  • + + {highlight} +
  • + ))} +
+
+
+ ))} +
+ +
+
+

{copy.earlierTitle}

+

{copy.earlierIntro}

+
+
+ {cv.earlierExperiences.map(item => ( +
+

{item.duration}

+

{item.company}

+

{item.title}

+
+ ))} +
+
+
+
+ +
+
+ +

03 / {copy.capabilities}

+

{copy.skillsTitle}

+
+
+ {cv.skills.map((skill, index) => ( +
+

{String(index + 1).padStart(2, '0')}

+

{skill.category}

+
+ {skill.items.map((item, itemIndex) => ( + {item}{itemIndex < skill.items.length - 1 ? / : null} + ))} +
+
+ ))} +
+
+
+ +
+
+ +

04 / {copy.work}

+
+

{copy.workTitle}

+ {copy.viewPortfolio} +
+
+
+ {projects.map((project, index) => ( + +
+

{String(index + 1).padStart(2, '0')}

+
+

{project.name}

+

{project.descriptor}

+
+

{copy.selectedImpact}: {project.impact}

+ +
+
+ ))} +
+
+
+ +
+
+

05 / {copy.foundation}

+
+ {copy.foundationTitle} +
+
+

{cv.sections.education}

+ {cv.education.map(item => ( +
+

{item.institution}

+

{item.program}

+ {item.years ?

{item.years}

: null} +
+ ))} +
+
+

{cv.sections.languages}

+
+ {cv.languages.map(language => ( +
+

{language.name}

+

{language.level}

+
+ ))} +
+
+
+
+
+
+ + +
+ ); +} diff --git a/app/[locale]/(standalone)/cv/page.tsx b/app/[locale]/(standalone)/cv/page.tsx index f704dc2..b6b6029 100644 --- a/app/[locale]/(standalone)/cv/page.tsx +++ b/app/[locale]/(standalone)/cv/page.tsx @@ -1,8 +1,7 @@ import type { Metadata } from 'next'; import Script from 'next/script'; import { getTranslations, setRequestLocale } from 'next-intl/server'; -import CVV2 from '../cv-v2/CVV2'; -import '../cv-v2/cv-v2.css'; +import CVV3 from '../cv-v3/CVV3'; type Props = { params: Promise<{ locale: string }>; @@ -17,8 +16,8 @@ export async function generateMetadata({ params }: Props): Promise { ? "יותם פרג'י | Senior Product Engineer בברלין" : 'Yotam Faraggi | Senior Product Engineer in Berlin'; const description = validLocale === 'he' - ? 'Senior Product Engineer בברלין עם 10+ שנות ניסיון במוצרי Full-Stack, AI, מסחר, אינטגרציות ומערכות פרודקשן.' - : 'Berlin-based Senior Product Engineer with 10+ years of experience building full-stack products, AI-assisted software, commerce systems, integrations, and production platforms.'; + ? 'Senior Product Engineer בברלין עם 10+ שנות ניסיון ב-Full-Stack, מסחר, אינטגרציות, AI ומערכות פרודקשן מורכבות.' + : 'Berlin-based Senior Product Engineer with 10+ years across full-stack products, commerce, integrations, AI and production software.'; return { title, @@ -61,8 +60,8 @@ export default async function CVPage({ params }: Props) { const t = await getTranslations({ locale: validLocale, namespace: 'cv' }); const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://cart-shift.com'; const description = validLocale === 'he' - ? 'Senior Product Engineer בברלין עם ניסיון במוצרי Full-Stack, AI, מסחר ואינטגרציות.' - : 'Senior Product Engineer in Berlin building full-stack products, AI-assisted software, commerce systems, and integration-heavy platforms.'; + ? 'Senior Product Engineer בברלין עם ניסיון ב-Full-Stack, מסחר, אינטגרציות ו-AI.' + : 'Senior Product Engineer in Berlin building full-stack products, commerce systems, AI-assisted software and integration-heavy platforms.'; const jsonLd = { '@context': 'https://schema.org', @@ -114,7 +113,7 @@ export default async function CVPage({ params }: Props) { type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} /> - + ); } diff --git a/app/[locale]/(standalone)/portfolio-v3/PortfolioV3.tsx b/app/[locale]/(standalone)/portfolio-v3/PortfolioV3.tsx new file mode 100644 index 0000000..c296d0e --- /dev/null +++ b/app/[locale]/(standalone)/portfolio-v3/PortfolioV3.tsx @@ -0,0 +1,467 @@ +'use client'; + +import Image from 'next/image'; +import { useMemo } from 'react'; +import { motion, useReducedMotion } from 'framer-motion'; +import { ArrowDown, ArrowUpRight, Download, Mail, MapPin } from 'lucide-react'; +import { useMessages } from 'next-intl'; +import { buildCVData, type RawCVMessages } from '@/lib/cv/cv-data'; + +type Project = { + number: string; + title: string; + descriptor: string; + summary: string; + ownership: string; + outcome: string; + year: string; + image: string; + imageAlt: string; + href: string; + external: boolean; +}; + +const ease = [0.22, 1, 0.36, 1] as const; +const reveal = { + hidden: { opacity: 0, y: 30 }, + visible: { opacity: 1, y: 0 }, +}; + +export default function PortfolioV3({ locale }: { locale: string }) { + const isHebrew = locale === 'he'; + const messages = useMessages() as { cv: RawCVMessages }; + const cv = useMemo(() => buildCVData(messages.cv), [messages]); + const reduceMotion = useReducedMotion(); + const cvHref = `/${locale}/cv`; + const pdfHref = `/${locale}/cv/render?variant=default`; + + const copy = isHebrew + ? { + navWork: 'עבודות', + navApproach: 'גישה', + navExperience: 'ניסיון', + navCv: 'קורות חיים', + navContact: 'קשר', + kicker: 'Senior Product Engineer · ברלין', + headline: 'הופך בעיות מוצר מורכבות לתוכנה שעובדת.', + intro: + 'אני מחבר חשיבה מוצרית לעומק הנדסי, מהרגע שבו הדרישות עדיין לא מסודרות ועד ארכיטקטורה, פיתוח, השקה ואיטרציה בפרודקשן.', + primaryCta: 'לצפייה בעבודות', + secondaryCta: 'הורדת CV', + proofYears: '10+ שנים', + proofYearsLabel: 'תוכנה בפרודקשן', + proofCuralife: '4+ שנים', + proofCuralifeLabel: 'ownership ב-Curalife', + proofSync: '85%-', + proofSyncLabel: 'כשלי סנכרון', + proofPerf: '60%+', + proofPerfLabel: 'ביצועי מסלולים מרכזיים', + workEyebrow: 'עבודות נבחרות', + workTitle: 'פחות דמואים. יותר ownership אמיתי.', + workIntro: + 'המכנה המשותף בפרויקטים האלה הוא לא תחום מסוים אלא האחריות: להבין את הבעיה, לבחור ארכיטקטורה, לבנות את החלקים הקשים ולהביא אותם לפרודקשן.', + ownership: 'מה לקחתי על עצמי', + outcome: 'תוצאה', + approachEyebrow: 'איך אני עובד', + approachTitle: 'אני אוהב להיות קרוב גם לבעיה וגם לקוד.', + approachIntro: + 'העבודה הכי טובה שלי קורית כשלא צריך לבחור בין product sense לבין engineering depth. אני אוהב להבין למה משהו צריך להיבנות, ואז להיות מספיק hands-on כדי לוודא שהוא באמת עובד.', + principleProduct: 'להפוך ambiguity להחלטות', + principleProductText: 'לחדד scope, trade-offs ו-user journey לפני שהמורכבות מתקבעת בקוד.', + principleSystems: 'לתכנן עבור המציאות', + principleSystemsText: 'APIs, אינטגרציות, דאטה, ביצועים, אמינות ותחזוקה כחלק מאותו design problem.', + principleShip: 'להישאר עד אחרי ההשקה', + principleShipText: 'למדוד, לתקן ולהמשיך לשפר אחרי שהמערכת פוגשת משתמשים ותנאי פרודקשן אמיתיים.', + experienceEyebrow: 'ניסיון', + experienceTitle: 'יותר מעשור, ממערכות enterprise ועד מוצרי AI.', + experienceIntro: 'הקריירה שלי נעה בהדרגה מאינטגרציות ותוכנה enterprise לאחריות מוצרית מלאה על web, commerce ו-AI.', + fullHistory: 'לניסיון המלא', + contactEyebrow: 'ברלין · אזרח האיחוד האירופי', + contactTitle: 'מחפש את הצוות והבעיה הבאים ששווה להתחייב אליהם.', + getInTouch: 'יצירת קשר', + location: 'ברלין, גרמניה', + roleLine: 'Senior Product Engineer · Full-stack · AI · Commerce', + scroll: 'עבודות', + curalifeSummary: 'אחריות על חלקים מרכזיים באקוסיסטם Shopify ו-digital health, כולל אינטגרציות, performance ומוצר טלרפואה שנבנה מקצה לקצה.', + curalifeOwnership: 'Product ownership · Architecture · Full-stack · Shopify · Integrations', + curalifeOutcome: '85% פחות כשלי סנכרון, שיפור של 60% בביצועים, ומוצר טלרפואה שהפך לערוץ רכישה והכנסות מרכזי.', + starlinkerSummary: 'מוצר תכנון ויזואלי למטרות, משימות, הרגלים והערות על קנבס מחובר, עם agent שפועל בתוך סביבת העבודה.', + starlinkerOwnership: 'Founder · Product definition · Architecture · AI · Full-stack', + starlinkerOutcome: 'נבנה מקצה לקצה מהגדרת המוצר ועד חוויית AI שפועלת ישירות בתוך ה-workspace.', + rightflowSummary: 'פלטפורמת בדיקה ואימות מסמכים להפקדות פנסיה ושכר עם תהליכי review מובנים וייצוא דוחות.', + rightflowOwnership: 'Founder · Workflow design · Automation · Full-stack', + rightflowOutcome: 'תהליך רגיש ורב-מסמכים שהפך ל-workflow מובנה, עקבי וניתן לייצוא.', + cartshiftSummary: 'סטודיו לפיתוח web ו-commerce שמחבר delivery ללקוחות עם בנייה של מוצרים, אינטגרציות ואוטומציות.', + cartshiftOwnership: 'Founder · Client delivery · Product engineering · Commerce', + cartshiftOutcome: 'מערכות production ללקוחות לצד מוצרים עצמאיים, עם ownership מלא על discovery, build ו-release.', + } + : { + navWork: 'Work', + navApproach: 'Approach', + navExperience: 'Experience', + navCv: 'CV', + navContact: 'Contact', + kicker: 'Senior Product Engineer · Berlin', + headline: 'I turn hard product problems into software that works.', + intro: + 'I connect product thinking with engineering depth, from the first unclear requirement through architecture, implementation, launch and iteration in production.', + primaryCta: 'View selected work', + secondaryCta: 'Download CV', + proofYears: '10+ yrs', + proofYearsLabel: 'production software', + proofCuralife: '4+ yrs', + proofCuralifeLabel: 'ownership at Curalife', + proofSync: '−85%', + proofSyncLabel: 'sync failures', + proofPerf: '+60%', + proofPerfLabel: 'key-journey performance', + workEyebrow: 'Selected work', + workTitle: 'Less demo reel. More real ownership.', + workIntro: + 'The common thread is not one industry. It is responsibility: understand the problem, choose the architecture, build the hard parts and get them into production.', + ownership: 'What I owned', + outcome: 'Outcome', + approachEyebrow: 'How I work', + approachTitle: 'I stay close to both the problem and the code.', + approachIntro: + 'My best work happens when product sense and engineering depth do not have to live in separate rooms. I want to understand why something should exist, then stay hands-on enough to make sure it actually works.', + principleProduct: 'Turn ambiguity into decisions', + principleProductText: 'Clarify scope, trade-offs and the user journey before complexity hardens into code.', + principleSystems: 'Design for reality', + principleSystemsText: 'Treat APIs, integrations, data, performance, reliability and maintainability as one design problem.', + principleShip: 'Stay after launch', + principleShipText: 'Measure, fix and keep improving once the system meets real users and real production constraints.', + experienceEyebrow: 'Experience', + experienceTitle: 'A decade-plus, from enterprise systems to AI products.', + experienceIntro: 'My career moved from enterprise integration and software into end-to-end ownership of web, commerce and AI products.', + fullHistory: 'View full experience', + contactEyebrow: 'Berlin · EU citizen', + contactTitle: 'Looking for the next team and problem worth committing to.', + getInTouch: 'Get in touch', + location: 'Berlin, Germany', + roleLine: 'Senior Product Engineer · Full-stack · AI · Commerce', + scroll: 'Work', + curalifeSummary: 'Owned major parts of a Shopify commerce and digital-health ecosystem, including integrations, performance and an end-to-end telemedicine acquisition product.', + curalifeOwnership: 'Product ownership · Architecture · Full-stack · Shopify · Integrations', + curalifeOutcome: '85% fewer sync failures, 60% better performance, and a telemedicine product that became a primary acquisition and revenue funnel.', + starlinkerSummary: 'A visual planning product for goals, tasks, habits and notes on a connected canvas, with an AI agent that can act inside the workspace.', + starlinkerOwnership: 'Founder · Product definition · Architecture · AI · Full-stack', + starlinkerOutcome: 'Built end to end from product definition through an AI experience that acts directly inside the workspace.', + rightflowSummary: 'A document review and verification platform for pension and payroll contribution checks, with structured review flows and report export.', + rightflowOwnership: 'Founder · Workflow design · Automation · Full-stack', + rightflowOutcome: 'Turned a sensitive, document-heavy process into a structured, repeatable workflow with report export.', + cartshiftSummary: 'A web and commerce engineering studio combining client delivery with product, integration and automation work.', + cartshiftOwnership: 'Founder · Client delivery · Product engineering · Commerce', + cartshiftOutcome: 'Production client systems alongside independent products, with full ownership across discovery, build and release.', + }; + + const projects: Project[] = [ + { + number: '01', + title: 'Curalife', + descriptor: 'Commerce + Digital Health', + summary: copy.curalifeSummary, + ownership: copy.curalifeOwnership, + outcome: copy.curalifeOutcome, + year: '2021–25', + image: '/images/case-studies/curalife-metabolic-wellness-platform/hero.jpg', + imageAlt: 'Curalife digital health and commerce experience', + href: `/${locale}/work/curalife-metabolic-wellness-platform`, + external: false, + }, + { + number: '02', + title: 'StarLinker', + descriptor: 'AI-native Productivity', + summary: copy.starlinkerSummary, + ownership: copy.starlinkerOwnership, + outcome: copy.starlinkerOutcome, + year: '2026', + image: '/images/cv/portfolio/starlinker-en-light.png', + imageAlt: 'StarLinker visual planning product interface', + href: 'https://starlinker.io', + external: true, + }, + { + number: '03', + title: 'RightFlow', + descriptor: 'Document Intelligence', + summary: copy.rightflowSummary, + ownership: copy.rightflowOwnership, + outcome: copy.rightflowOutcome, + year: '2025', + image: '/images/cv/portfolio/rightflow-en-light.png', + imageAlt: 'RightFlow document review interface', + href: 'https://right-flow.com', + external: true, + }, + { + number: '04', + title: 'CartShift Studio', + descriptor: 'Commerce + Product Engineering', + summary: copy.cartshiftSummary, + ownership: copy.cartshiftOwnership, + outcome: copy.cartshiftOutcome, + year: '2025–26', + image: '/images/cv/portfolio/cartshift-en-light.png', + imageAlt: 'CartShift Studio website and product engineering work', + href: `https://cart-shift.com/${locale}`, + external: true, + }, + ]; + + const proof = [ + [copy.proofYears, copy.proofYearsLabel], + [copy.proofCuralife, copy.proofCuralifeLabel], + [copy.proofSync, copy.proofSyncLabel], + [copy.proofPerf, copy.proofPerfLabel], + ]; + + const experience = cv.recentExperiences.slice(0, 3); + + const sectionReveal = reduceMotion + ? { initial: false as const } + : { + variants: reveal, + initial: 'hidden' as const, + whileInView: 'visible' as const, + viewport: { once: true, amount: 0.16 }, + transition: { duration: 0.64, ease }, + }; + + return ( +
+
+ +
+ +
+ + +
+ +
+
+ {copy.location} + {copy.roleLine} +
+ +
+ + {copy.kicker} + + + {copy.headline} + + +

{copy.intro}

+ +
+
+ +
+ {proof.map(([value, label]) => ( +
+

{value}

+

{label}

+
+ ))} +
+ {copy.scroll} +
+
+ +
+ +
+ +
+
+ +

02 / {copy.approachEyebrow}

+
+

{copy.approachTitle}

+

{copy.approachIntro}

+
+
+ +
+ {[ + [copy.principleProduct, copy.principleProductText], + [copy.principleSystems, copy.principleSystemsText], + [copy.principleShip, copy.principleShipText], + ].map(([title, text], index) => ( +
+

0{index + 1}

+

{title}

+

{text}

+
+ ))} +
+
+
+ +
+
+ +

03 / {copy.experienceEyebrow}

+
+

{copy.experienceTitle}

+

{copy.experienceIntro}

+
+
+ +
+ {experience.map((item, index) => ( +
+

0{index + 1}

{item.duration}

+

{item.company}

{item.title}

+

{item.description ?? item.highlights[0]}

+
+ ))} + +
+
+
+ + +
+ ); +} diff --git a/app/[locale]/(standalone)/portfolio/page.tsx b/app/[locale]/(standalone)/portfolio/page.tsx index df095bb..e107ead 100644 --- a/app/[locale]/(standalone)/portfolio/page.tsx +++ b/app/[locale]/(standalone)/portfolio/page.tsx @@ -1,8 +1,7 @@ import type { Metadata } from 'next'; import Script from 'next/script'; import { setRequestLocale } from 'next-intl/server'; -import PortfolioV2 from '../portfolio-v2/PortfolioV2'; -import '../portfolio-v2/portfolio-v2.css'; +import PortfolioV3 from '../portfolio-v3/PortfolioV3'; type Props = { params: Promise<{ locale: string }>; @@ -16,8 +15,8 @@ export async function generateMetadata({ params }: Props): Promise { ? "יותם פרג'י - Senior Product Engineer | פורטפוליו" : 'Yotam Faraggi - Senior Product Engineer | Portfolio'; const description = isHebrew - ? 'פורטפוליו של Senior Product Engineer בברלין: מוצרי Full-Stack, AI, מסחר, אינטגרציות ועבודה מקצה לקצה.' - : 'Portfolio of a Berlin-based Senior Product Engineer building full-stack products, AI-assisted software, commerce systems, integrations, and production platforms.'; + ? 'פורטפוליו של Senior Product Engineer בברלין עם 10+ שנות ניסיון ב-Full-Stack, מסחר, אינטגרציות ו-AI, עם דגש על ownership ותוצאות בפרודקשן.' + : 'Portfolio of a Berlin-based Senior Product Engineer with 10+ years across full-stack products, commerce, integrations and AI, focused on ownership and production outcomes.'; return { title, @@ -67,6 +66,9 @@ export default async function PortfolioPage({ params }: Props) { '@type': 'Person', name: isHebrew ? "יותם פרג'י" : 'Yotam Faraggi', jobTitle: 'Senior Product Engineer', + description: isHebrew + ? 'Senior Product Engineer בברלין המתמחה במוצרי Full-Stack, מסחר, אינטגרציות ו-AI.' + : 'Senior Product Engineer in Berlin focused on full-stack products, commerce, integrations and AI.', url: `${siteUrl}/${locale}/portfolio`, image: `${siteUrl}/images/portfolio-v2/hero-art.webp`, sameAs: [ @@ -100,7 +102,7 @@ export default async function PortfolioPage({ params }: Props) { type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} /> - + ); } diff --git a/tailwind.config.ts b/tailwind.config.ts index e3d829c..ddf180d 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -62,6 +62,30 @@ const config: Config = { warning: 'rgb(var(--color-warning) / )', }, + opacity: { + 15: '0.15', + 18: '0.18', + 28: '0.28', + 35: '0.35', + 38: '0.38', + 42: '0.42', + 43: '0.43', + 45: '0.45', + 46: '0.46', + 48: '0.48', + 52: '0.52', + 55: '0.55', + 58: '0.58', + 62: '0.62', + 64: '0.64', + 65: '0.65', + 66: '0.66', + 67: '0.67', + 68: '0.68', + 72: '0.72', + 85: '0.85', + }, + fontSize: { 'fluid-xs': ['clamp(0.75rem, 0.7rem + 0.25vw, 0.875rem)', { lineHeight: '1.5' }], 'fluid-sm': ['clamp(0.875rem, 0.8rem + 0.375vw, 1rem)', { lineHeight: '1.5' }], @@ -227,4 +251,4 @@ const config: Config = { plugins: [tailwindcssAnimate], }; -export default config; +export default config; \ No newline at end of file