+ );
+}
diff --git a/frontend/components/home/HeroBackground.tsx b/frontend/components/home/WelcomeHeroBackground.tsx
similarity index 76%
rename from frontend/components/home/HeroBackground.tsx
rename to frontend/components/home/WelcomeHeroBackground.tsx
index 06e360d2..db6a4d24 100644
--- a/frontend/components/home/HeroBackground.tsx
+++ b/frontend/components/home/WelcomeHeroBackground.tsx
@@ -1,8 +1,10 @@
-export function HeroBackground() {
+import React from 'react';
+
+export function WelcomeHeroBackground() {
return (
<>
-
-
+
+
diff --git a/frontend/components/home/WelcomeHeroSection.tsx b/frontend/components/home/WelcomeHeroSection.tsx
new file mode 100644
index 00000000..bf64bf2e
--- /dev/null
+++ b/frontend/components/home/WelcomeHeroSection.tsx
@@ -0,0 +1,70 @@
+'use client';
+
+import { useTranslations } from 'next-intl';
+import React from 'react';
+import { motion } from 'framer-motion';
+import { ChevronDown } from 'lucide-react';
+
+
+import { InteractiveConstellation } from '@/components/home/InteractiveConstellation';
+import { InteractiveCTAButton } from '@/components/home/InteractiveCTAButton';
+import { WelcomeHeroBackground } from '@/components/home/WelcomeHeroBackground';
+
+export default function WelcomeHeroSection() {
+ const t = useTranslations('homepage');
+
+ return (
+
+
+
+
+
+ {t('subtitle')}
+
+
+
+
+ DevLovers
+
+
+
+ DevLovers
+
+
+
+
+
+ {t('welcomeDescription')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/frontend/components/ui/particle-canvas.tsx b/frontend/components/ui/particle-canvas.tsx
index 27cd2ea2..15130e25 100644
--- a/frontend/components/ui/particle-canvas.tsx
+++ b/frontend/components/ui/particle-canvas.tsx
@@ -363,4 +363,4 @@ export function ParticleCanvas({
}, []);
return ;
-}
+}
\ No newline at end of file
diff --git a/frontend/lib/about/stats.ts b/frontend/lib/about/stats.ts
index c42e764e..2b0ea081 100644
--- a/frontend/lib/about/stats.ts
+++ b/frontend/lib/about/stats.ts
@@ -43,7 +43,7 @@ export const getPlatformStats = unstable_cache(
const linkedinCount = process.env.LINKEDIN_FOLLOWER_COUNT
? parseInt(process.env.LINKEDIN_FOLLOWER_COUNT)
- : 1400;
+ : 1500;
let totalUsers = 243;
let solvedTests = 1890;
diff --git a/frontend/messages/en.json b/frontend/messages/en.json
index 8ea781ee..8a5be3a3 100644
--- a/frontend/messages/en.json
+++ b/frontend/messages/en.json
@@ -46,7 +46,8 @@
"homepage": {
"title": "DevLovers — Technical Interview Platform",
"subtitle": "Platform for Technical Interview Preparation",
- "description": "Prepare for technical interviews with Q&A, quizzes, leaderboards, and AI-powered explanations.",
+ "welcomeDescription": "Prepare for technical interviews with Q&A, quizzes, leaderboards, and AI-powered explanations.",
+ "description": "Build real confidence in frontend, backend, and full-stack development through interactive interview questions, quizzes, and practical explanations",
"ogImageAlt": "DevLovers — Technical Interview Platform",
"cta": "Take the first step",
"ctaVariants": {
@@ -58,6 +59,61 @@
"6": "Brave move, by the way",
"7": "Okay, now it's happening",
"8": "Hello, new commit"
+ },
+ "featuresHeading": {
+ "aceYourNext": "Ace Your Next",
+ "technicalInterview": "Technical Interview"
+ },
+ "featureBadges": {
+ "smartQA": "Smart Q&A",
+ "adaptiveQuizzes": "Adaptive Quizzes",
+ "performance": "Performance"
+ },
+ "featuresCta": {
+ "browseQuestions": "Browse All Questions",
+ "takeQuiz": "Take a Quiz"
+ },
+ "flipCard": {
+ "ui": {
+ "tapToReveal": "Tap to reveal",
+ "clickToReveal": "Click to reveal",
+ "tapAgain": "Tap again to see question",
+ "clickAgain": "Click again to see question",
+ "answer": "Answer",
+ "proTip": "Pro Tip"
+ },
+ "questions": {
+ "1": {
+ "question": "When should you actually use useMemo?",
+ "answer": "Don't prematurely optimize! Use it only for expensive calculations or when passing objects as props to children wrapped in React.memo to prevent unnecessary re-renders.",
+ "category": "React",
+ "tip": "Overusing it can hurt performance due to dependency comparison overhead."
+ },
+ "2": {
+ "question": "Why is \"Event Delegation\" better than direct binding?",
+ "answer": "It attaches a single listener to a parent instead of thousands on children. This uses less memory and automatically handles dynamically added elements via event bubbling.",
+ "category": "JavaScript",
+ "tip": "Perfect for lists, tables, and infinite scroll feeds."
+ },
+ "3": {
+ "question": "How does the Node.js Event Loop handle I/O?",
+ "answer": "Node.js offloads I/O operations to the system kernel. When an operation completes, the kernel notifies Node.js, and the callback is added to the Poll phase to be executed.",
+ "category": "Node.js",
+ "tip": "This is why Node.js is \"non-blocking\" despite being single-threaded."
+ },
+ "4": {
+ "question": "Should you use SSR, SSG, or ISR?",
+ "answer": "Use SSG for static blogs (fastest). Use SSR for personalized dashboards (freshest). Use ISR to update static pages incrementally without a full rebuild.",
+ "category": "Next.js",
+ "tip": "Start with SSG/ISR by default for better performance."
+ },
+ "5": {
+ "question": "Why use Generics in TypeScript?",
+ "answer": "They let you write reusable code that works with any type while keeping full type safety. It's like function arguments, but for types.",
+ "category": "TypeScript",
+ "tip": "Commonly used in API wrappers, hooks, and utility functions."
+ }
+ }
}
},
"qa": {
diff --git a/frontend/messages/pl.json b/frontend/messages/pl.json
index 7ccdf583..4128c2ce 100644
--- a/frontend/messages/pl.json
+++ b/frontend/messages/pl.json
@@ -45,10 +45,11 @@
},
"homepage": {
"title": "DevLovers",
- "subtitle": "Platforma do przygotowania do rozmów kwalifikacyjnych",
- "description": "Przygotuj się do rozmów technicznych dzięki pytaniom, quizom, rankingom i wyjaśnieniom wspieranym przez AI.",
+ "subtitle": "Platforma do Przygotowania do Rozmów Kwalifikacyjnych",
+ "welcomeDescription": "Przygotuj się do rozmów technicznych z Q&A, quizami, rankingiem i wyjaśnieniami AI.",
+ "description": "Zbuduj prawdziwą pewność w frontend, backend i full-stack development dzięki interaktywnym pytaniom rekrutacyjnym, quizom i praktycznym wyjaśnieniom",
"ogImageAlt": "DevLovers — platforma do przygotowania do rozmów technicznych",
- "cta": "Rozpocznij",
+ "cta": "Rozpocznij naukę",
"ctaVariants": {
"1": "Bez presji. Po prostu zacznij",
"2": "To może być ciekawsze, niż myślisz",
@@ -58,6 +59,61 @@
"6": "Klik był — to się liczy",
"7": "Postęp ważniejszy niż perfekcja",
"8": "Zacząć to też funkcja"
+ },
+ "featuresHeading": {
+ "aceYourNext": "Zdaj kolejną",
+ "technicalInterview": "rozmowę perfekcyjnie"
+ },
+ "featureBadges": {
+ "smartQA": "Inteligentne Q&A",
+ "adaptiveQuizzes": "Adaptacyjne quizy",
+ "performance": "Wydajność"
+ },
+ "featuresCta": {
+ "browseQuestions": "Przeglądaj wszystkie pytania",
+ "takeQuiz": "Rozwiąż quiz"
+ },
+ "flipCard": {
+ "ui": {
+ "tapToReveal": "Dotknij, aby odkryć",
+ "clickToReveal": "Kliknij, aby odkryć",
+ "tapAgain": "Dotknij ponownie, aby zobaczyć pytanie",
+ "clickAgain": "Kliknij ponownie, aby zobaczyć pytanie",
+ "answer": "Odpowiedź",
+ "proTip": "Wskazówka"
+ },
+ "questions": {
+ "1": {
+ "question": "Kiedy faktycznie używać useMemo?",
+ "answer": "Nie optymalizuj przedwcześnie! Używaj tylko do kosztownych obliczeń lub przy przekazywaniu obiektów jako props do dzieci owiniętych w React.memo, aby zapobiec niepotrzebnym renderowaniom.",
+ "category": "React",
+ "tip": "Nadużywanie może zaszkodzić wydajności przez narzut porównywania zależności."
+ },
+ "2": {
+ "question": "Dlaczego \"Delegacja Zdarzeń\" jest lepsza niż bezpośrednie wiązanie?",
+ "answer": "Dołącza pojedynczy nasłuchiwacz do rodzica zamiast tysięcy do dzieci. Zużywa mniej pamięci i automatycznie obsługuje dynamicznie dodawane elementy poprzez bąbelkowanie zdarzeń.",
+ "category": "JavaScript",
+ "tip": "Idealne dla list, tabel i nieskończonych przewijań."
+ },
+ "3": {
+ "question": "Jak Event Loop w Node.js obsługuje I/O?",
+ "answer": "Node.js zleca operacje I/O jądru systemu. Gdy operacja się kończy, jądro powiadamia Node.js, a callback trafia do fazy Poll w celu wykonania.",
+ "category": "Node.js",
+ "tip": "Dlatego Node.js jest \"nieblokujący\" mimo bycia jednowątkowym."
+ },
+ "4": {
+ "question": "Co wybrać: SSR, SSG czy ISR?",
+ "answer": "Używaj SSG dla statycznych blogów (najszybsze). Używaj SSR dla spersonalizowanych kokpitów (najświeższe). Używaj ISR do aktualizacji statycznych stron bez pełnej przebudowy.",
+ "category": "Next.js",
+ "tip": "Zacznij od SSG/ISR domyślnie dla lepszej wydajności."
+ },
+ "5": {
+ "question": "Po co używać Generics w TypeScript?",
+ "answer": "Pozwalają pisać kod wielokrotnego użytku, który działa z każdym typem, zachowując pełne bezpieczeństwo typów. To jak argumenty funkcji, ale dla typów.",
+ "category": "TypeScript",
+ "tip": "Powszechnie używane w wrapperach API, hookach i funkcjach użytkowych."
+ }
+ }
}
},
"qa": {
diff --git a/frontend/messages/uk.json b/frontend/messages/uk.json
index 32aea444..85d1a9ca 100644
--- a/frontend/messages/uk.json
+++ b/frontend/messages/uk.json
@@ -46,7 +46,8 @@
"homepage": {
"title": "DevLovers — Платформа для підготовки до технічних співбесід",
"subtitle": "Платформа для підготовки до технічних співбесід",
- "description": "Готуйся до технічних співбесід за допомогою питань, квізів, рейтингу та пояснень на базі AI.",
+ "welcomeDescription": "Готуйся до технічних співбесід з Q&A, квізами, рейтингом та AI-поясненнями.",
+ "description": "Сформуй справжню впевненість у frontend, backend та full-stack розробці завдяки інтерактивним питанням для співбесід, квізам і практичним поясненням",
"ogImageAlt": "DevLovers — платформа для підготовки до технічних співбесід",
"cta": "Зроби перший крок",
"ctaVariants": {
@@ -58,6 +59,61 @@
"6": "Ну все, процес пішов",
"7": "Простіше, ніж виглядає",
"8": "Почати — це теж фіча"
+ },
+ "featuresHeading": {
+ "aceYourNext": "Пройди наступну",
+ "technicalInterview": "співбесіду на відмінно"
+ },
+ "featureBadges": {
+ "smartQA": "Розумні Q&A",
+ "adaptiveQuizzes": "Адаптивні квізи",
+ "performance": "Продуктивність"
+ },
+ "featuresCta": {
+ "browseQuestions": "Переглянути всі питання",
+ "takeQuiz": "Пройти квіз"
+ },
+ "flipCard": {
+ "ui": {
+ "tapToReveal": "Торкніться, щоб відкрити",
+ "clickToReveal": "Клікніть, щоб відкрити",
+ "tapAgain": "Торкніться ще раз, щоб побачити питання",
+ "clickAgain": "Клікніть ще раз, щоб побачити питання",
+ "answer": "Відповідь",
+ "proTip": "Порада"
+ },
+ "questions": {
+ "1": {
+ "question": "Коли насправді варто використовувати useMemo?",
+ "answer": "Не оптимізуйте передчасно! Використовуйте тільки для важких обчислень або при передачі об'єктів як пропсів у компоненти, огорнуті в React.memo, щоб запобігти зайвим ре-рендерам.",
+ "category": "React",
+ "tip": "Надмірне використання може зашкодити продуктивності через накладні витрати на порівняння залежностей."
+ },
+ "2": {
+ "question": "Чому \"Делегування подій\" краще за пряме прив'язування?",
+ "answer": "Воно додає один слухач до батьківського елемента замість тисяч на дочірніх. Це використовує менше пам'яті та автоматично обробляє динамічно додані елементи через спливання подій.",
+ "category": "JavaScript",
+ "tip": "Ідеально для списків, таблиць та стрічок з нескінченною прокруткою."
+ },
+ "3": {
+ "question": "Як Event Loop у Node.js обробляє I/O?",
+ "answer": "Node.js перекладає операції I/O на ядро системи. Коли операція завершується, ядро повідомляє Node.js, і колбек додається у фазу Poll для виконання.",
+ "category": "Node.js",
+ "tip": "Ось чому Node.js є \"неблокуючим\", незважаючи на однопотоковість."
+ },
+ "4": {
+ "question": "Що обрати: SSR, SSG чи ISR?",
+ "answer": "Використовуйте SSG для статичних блогів (найшвидше). Використовуйте SSR для персоналізованих дашбордів (найсвіжіше). Використовуйте ISR для оновлення статичних сторінок без повного перезбирання.",
+ "category": "Next.js",
+ "tip": "Починайте з SSG/ISR за замовчуванням для кращої продуктивності."
+ },
+ "5": {
+ "question": "Навіщо використовувати Generics у TypeScript?",
+ "answer": "Вони дозволяють писати перевикористовуваний код, який працює з будь-яким типом, зберігаючи повну безпеку типів. Це як аргументи функції, але для типів.",
+ "category": "TypeScript",
+ "tip": "Часто використовується в обгортках API, хуках та утилітах."
+ }
+ }
}
},
"qa": {
diff --git a/frontend/public/apparel.jpg b/frontend/public/apparel.jpg
deleted file mode 100644
index ade156ae..00000000
Binary files a/frontend/public/apparel.jpg and /dev/null differ
diff --git a/frontend/public/collectibles.jpg b/frontend/public/collectibles.jpg
deleted file mode 100644
index 23bfee58..00000000
Binary files a/frontend/public/collectibles.jpg and /dev/null differ
diff --git a/frontend/public/icons/code.svg b/frontend/public/icons/code.svg
new file mode 100644
index 00000000..aaec906f
--- /dev/null
+++ b/frontend/public/icons/code.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/public/icons/heart.svg b/frontend/public/icons/heart.svg
new file mode 100644
index 00000000..0f655e4a
--- /dev/null
+++ b/frontend/public/icons/heart.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/public/icons/palette.svg b/frontend/public/icons/palette.svg
new file mode 100644
index 00000000..c1046f28
--- /dev/null
+++ b/frontend/public/icons/palette.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/public/lifestyle.jpg b/frontend/public/lifestyle.jpg
deleted file mode 100644
index 3e726676..00000000
Binary files a/frontend/public/lifestyle.jpg and /dev/null differ