diff --git a/courses/index.md b/courses/index.md deleted file mode 100644 index 127fffc59..000000000 --- a/courses/index.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Welcome to our Courses -sidebar_label: Welcome to Courses -sidebar_position: 1 -description: Our courses are designed to help you learn new skills and advance your career. Whether you are a beginner or an experienced professional, our courses can help you gain the knowledge and skills you need to succeed. -tags: [courses] -keywoards: [courses, learning, tutorials, resources, web development, data science, collaboration, project management, security] -author: [CodeHarborHub, Ajay Dhangar] ---- - -Our courses are designed to help you learn new skills and advance your career. Whether you are a beginner or an experienced professional, our courses can help you gain the knowledge and skills you need to succeed. We cover a wide range of topics, including web development, data science, collaboration, project management, and security. - -## Why Choose Our Courses? - -- **Comprehensive Content**: Our courses cover a wide range of topics and provide in-depth knowledge and practical skills. -- **Experienced Instructors**: Our instructors are experts in their fields and have years of experience in teaching and industry. -- **Interactive Learning**: Our courses include interactive exercises, quizzes, and projects to help you apply what you learn. -- **Flexible Schedule**: You can learn at your own pace and schedule, making it convenient for working professionals and students. -- **Community Support**: Join our community of learners and instructors to get help, share ideas, and collaborate on projects. -- **Career Growth**: Our courses are designed to help you advance your career and stay ahead in the rapidly changing tech industry. -- **Affordable Pricing**: Our courses are free or affordable, making them accessible to everyone who wants to learn. - -## Our Courses - -Explore our courses to find the one that suits your interests and goals. Whether you are looking to learn a new programming language, build a web application, analyze data, or improve your project management skills, we have a course for you. Start your learning journey today! - - - - - - - - - -To get started, select a course from the list above or explore our recommended courses below. If you have any questions or need help, feel free to reach out to us. - -## Conclusion - -Our courses are designed to help you learn new skills, advance your career, and stay ahead in the rapidly changing tech industry. Whether you are a beginner or an experienced professional, our courses can help you gain the knowledge and skills you need to succeed. Start your learning journey today and unlock new opportunities for growth and success. \ No newline at end of file diff --git a/docusaurus.config.js b/docusaurus.config.js index f3bfeb3f9..291709a06 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -613,9 +613,9 @@ const config = { "@docusaurus/plugin-content-docs", /** @type {import('@docusaurus/plugin-content-docs').Options} */ { - id: "projects", - path: "projects", - routeBasePath: "projects", + id: "project", + path: "project", + routeBasePath: "project", // editUrl: "#", sidebarPath: require.resolve("./sidebarsCommunity.js"), remarkPlugins: [[npm2yarn, { sync: true }], remarkMath, rehypeKatex], diff --git a/package-lock.json b/package-lock.json index 74cb3c9c6..3b7f056e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -64,7 +64,7 @@ "raw-loader": "^4.0.2", "react": "^18.0.0", "react-dom": "^18.0.0", - "react-icons": "^5.2.1", + "react-icons": "^5.7.0", "react-lite-youtube-embed": "^3.3.3", "react-medium-image-zoom": "^5.4.0", "react-phone-input-2": "^2.15.1", @@ -24968,10 +24968,9 @@ } }, "node_modules/react-icons": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", - "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", - "license": "MIT", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.7.0.tgz", + "integrity": "sha512-LBLy340Rzqy6+/yVhZKT3B/QpP1BZaesGqasf09HPOBzRarcDIFH0WwXlXQfE7q7ipxK4MSiC5DIBWURCny6fw==", "peerDependencies": { "react": "*" } diff --git a/package.json b/package.json index ead3c8d76..d7627c53c 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "raw-loader": "^4.0.2", "react": "^18.0.0", "react-dom": "^18.0.0", - "react-icons": "^5.2.1", + "react-icons": "^5.7.0", "react-lite-youtube-embed": "^3.3.3", "react-medium-image-zoom": "^5.4.0", "react-phone-input-2": "^2.15.1", diff --git a/paths.md b/paths.md new file mode 100644 index 000000000..fe8d0e7a8 --- /dev/null +++ b/paths.md @@ -0,0 +1,1124 @@ + +# CodeHarborHub — Complete A–Z Routes & Pages + +Main domain: + +```text +https://codeharborhub.github.io/ +``` + +--- + +## A — Authentication + +### `/auth` + +```text +/auth +/auth/login +/auth/register +/auth/signup +/auth/forgot-password +/auth/reset-password +/auth/verify-email +/auth/verify-email/success +/auth/verify-email/failed +/auth/logout +``` + +### Pages + +| Route | Page | +| ----------------------- | --------------- | +| `/auth/login` | Login | +| `/auth/register` | Create Account | +| `/auth/forgot-password` | Forgot Password | +| `/auth/reset-password` | Reset Password | +| `/auth/verify-email` | Verify Email | + +--- + +## B — Home / Landing + +### `/` + +```text +/ +``` + +**Page:** CodeHarborHub Home + +Sections: + +* Hero +* Learning categories +* Popular courses +* Popular roadmaps +* Practice +* Projects +* AI Tutor +* Community +* Contributors +* CTA +* Footer + +--- + +## C — Courses + +### `/courses` + +```text +/courses +/courses/all +/courses/free +/courses/popular +/courses/new +/courses/trending +/courses/[course] +``` + +Example: + +```text +/courses/html +/courses/css +/courses/javascript +/courses/react +/courses/typescript +/courses/python +``` + +Course pages: + +```text +/courses/[course]/overview +/courses/[course]/curriculum +/courses/[course]/learn +/courses/[course]/projects +/courses/[course]/quizzes +/courses/[course]/reviews +/courses/[course]/certificate +``` + +--- + +# D — Documentation + +### `/docs` + +```text +/docs +/docs/html +/docs/css +/docs/javascript +/docs/typescript +/docs/react +/docs/nodejs +/docs/python +/docs/git +/docs/github +/docs/linux +``` + +Topics: + +```text +/docs/[technology]/[topic] +``` + +Example: + +```text +/docs/javascript/variables +/docs/javascript/functions +/docs/react/hooks +/docs/react/components +``` + +--- + +# E — Education / Learning + +### `/learning` + +```text +/learning +/learning/paths +/learning/paths/[path] +``` + +Example: + +```text +/learning/paths/frontend-developer +/learning/paths/backend-developer +/learning/paths/full-stack-developer +/learning/paths/ai-engineer +/learning/paths/ml-engineer +``` + +--- + +# F — Frontend + +You don't necessarily need `/frontend` as a separate product, but it can be a category: + +```text +/frontend +/frontend/html +/frontend/css +/frontend/javascript +/frontend/typescript +/frontend/react +/frontend/nextjs +/frontend/accessibility +``` + +--- + +# G — Git & GitHub + +```text +/git +/git/basics +/git/commands +/git/branching +/git/merging +/git/rebase +/git/workflows + +/github +/github/basics +/github/repositories +/github/pull-requests +/github/issues +/github/actions +/github/contributing +``` + +--- + +# H — HTML + +```text +/tutorials/html +/tutorials/html/basics +/tutorials/html/elements +/tutorials/html/forms +/tutorials/html/semantic-html +/tutorials/html/accessibility +/tutorials/html/seo +``` + +--- + +# I — Interview + +### `/interview` + +```text +/interview +/interview/questions +/interview/dsa +/interview/frontend +/interview/backend +/interview/full-stack +/interview/javascript +/interview/react +/interview/system-design +/interview/hr +/interview/mock +``` + +--- + +# J — JavaScript + +```text +/tutorials/javascript +/tutorials/javascript/basics +/tutorials/javascript/variables +/tutorials/javascript/functions +/tutorials/javascript/arrays +/tutorials/javascript/objects +/tutorials/javascript/dom +/tutorials/javascript/events +/tutorials/javascript/async +/tutorials/javascript/promises +/tutorials/javascript/fetch +/tutorials/javascript/modules +/tutorials/javascript/es6 +``` + +--- + +# K — Knowledge / Computer Science + +### `/computer-science` + +```text +/computer-science +/computer-science/programming +/computer-science/dsa +/computer-science/algorithms +/computer-science/data-structures +/computer-science/os +/computer-science/networks +/computer-science/databases +/computer-science/architecture +/computer-science/compiler-design +/computer-science/distributed-systems +/computer-science/system-design +``` + +--- + +# L — Learning Dashboard + +### `/dashboard` + +```text +/dashboard +/dashboard/overview +/dashboard/courses +/dashboard/learning +/dashboard/roadmaps +/dashboard/practice +/dashboard/projects +/dashboard/quizzes +/dashboard/progress +/dashboard/goals +/dashboard/streak +/dashboard/certificates +/dashboard/achievements +/dashboard/bookmarks +/dashboard/notes +``` + +This is the learner's personal control center. + +--- + +# M — Machine Learning + +```text +/machine-learning +/machine-learning/basics +/machine-learning/python +/machine-learning/numpy +/machine-learning/pandas +/machine-learning/statistics +/machine-learning/supervised-learning +/machine-learning/unsupervised-learning +/machine-learning/deep-learning +/machine-learning/nlp +/machine-learning/computer-vision +/machine-learning/projects +``` + +--- + +# N — News / Blog + +### `/blog` + +```text +/blog +/blog/all +/blog/programming +/blog/web-development +/blog/ai +/blog/career +/blog/open-source +/blog/tutorials +/blog/news +/blog/[slug] +``` + +Example: + +```text +/blog/how-to-learn-javascript +/blog/react-roadmap +``` + +--- + +# O — Open Source + +### `/open-source` + +```text +/open-source +/open-source/projects +/open-source/contribute +/open-source/good-first-issue +/open-source/hacktoberfest +/open-source/guidelines +/open-source/events +``` + +This is particularly important for CodeHarborHub. + +--- + +# P — Practice + +### `/practice` + +```text +/practice +/practice/problems +/practice/dsa +/practice/algorithms +/practice/sql +/practice/javascript +/practice/python +/practice/java +/practice/cpp +``` + +Problem: + +```text +/practice/problems/[problem] +``` + +Example: + +```text +/practice/problems/two-sum +/practice/problems/reverse-string +``` + +--- + +# Q — Quizzes + +### `/quizzes` + +```text +/quizzes +/quizzes/all +/quizzes/html +/quizzes/css +/quizzes/javascript +/quizzes/react +/quizzes/python +/quizzes/typescript +/quizzes/ai +/quizzes/[quiz] +``` + +Attempt: + +```text +/quizzes/[quiz]/attempt +/quizzes/[quiz]/result +``` + +--- + +# R — Roadmaps + +### `/roadmaps` + +```text +/roadmaps +/roadmaps/all +/roadmaps/beginner +/roadmaps/intermediate +/roadmaps/advanced +/roadmaps/frontend +/roadmaps/backend +/roadmaps/full-stack +/roadmaps/javascript +/roadmaps/react +/roadmaps/python +/roadmaps/ai +/roadmaps/cyber-security +``` + +Individual: + +```text +/roadmaps/[roadmap] +``` + +Progress: + +```text +/roadmaps/[roadmap]/progress +/roadmaps/[roadmap]/projects +``` + +--- + +# T — Tutorials + +### `/tutorials` + +```text +/tutorials +/tutorials/html +/tutorials/css +/tutorials/javascript +/tutorials/typescript +/tutorials/react +/tutorials/nextjs +/tutorials/nodejs +/tutorials/python +/tutorials/java +/tutorials/cpp +/tutorials/go +/tutorials/rust +``` + +Individual topics: + +```text +/tutorials/[technology]/[topic] +``` + +--- + +# U — User Profile + +### `/profile` + +```text +/profile +/profile/[username] +``` + +Example: + +```text +/profile/ajay-dhangar +``` + +Public profile: + +```text +/profile/[username]/about +/profile/[username]/skills +/profile/[username]/courses +/profile/[username]/projects +/profile/[username]/certificates +/profile/[username]/badges +/profile/[username]/achievements +/profile/[username]/activity +``` + +--- + +# W — Workshops + +### `/workshops` + +```text +/workshops +/workshops/upcoming +/workshops/live +/workshops/past +/workshops/[workshop] +``` + +--- + +# X — XP / Gamification + +### `/gamification` + +```text +/gamification +/xp +/levels +/streaks +/achievements +/badges +/rewards +``` + +Leaderboard: + +```text +/leaderboard +/leaderboard/global +/leaderboard/monthly +/leaderboard/weekly +/leaderboard/daily +``` + +--- + +# Y — Your Projects / Project Learning + +### `/projects` + +```text +/projects +/projects/all +/projects/beginner +/projects/intermediate +/projects/advanced +/projects/frontend +/projects/backend +/projects/full-stack +/projects/ai +/projects/ml +/projects/mobile +``` + +Individual: + +```text +/projects/[project] +``` + +Project workspace: + +```text +/projects/[project]/learn +/projects/[project]/requirements +/projects/[project]/solution +/projects/[project]/submission +/projects/[project]/reviews +``` + +--- + +# Z — Settings / User Management + +### `/settings` + +```text +/settings +/settings/profile +/settings/account +/settings/security +/settings/password +/settings/notifications +/settings/privacy +/settings/appearance +/settings/language +/settings/accessibility +/settings/billing +/settings/integrations +``` + +--- + +# ⭐ Additional Important CodeHarborHub Routes + +The A–Z structure above covers the learning ecosystem, but I'd add these routes too. + +## 🤖 AI + +```text +/ai +/ai/tutor +/ai/mentor +/ai/chat +/ai/explain +/ai/code-review +/ai/debug +/ai/quiz-generator +/ai/roadmap-generator +/ai/learning-plan +/ai/interview +``` + +--- + +# 💻 Online Code Editor + +```text +/editor +/editor/html +/editor/css +/editor/javascript +/editor/typescript +/editor/python +/editor/react +/editor/sql +/editor/projects +/editor/projects/[id] +``` + +--- + +# 🧪 Labs + +```text +/labs +/labs/html +/labs/css +/labs/javascript +/labs/react +/labs/python +/labs/sql +/labs/ai +/labs/[lab] +``` + +--- + +# 🏆 Certificates + +```text +/certificates +/certificates/my +/certificates/verify +/certificates/[id] +``` + +Important public URL: + +```text +/certificate/[certificate-id] +``` + +So a learner can share: + +```text +https://codeharborhub.github.io/certificate/CHH-2026-000123 +``` + +--- + +# 💼 Career + +```text +/career +/career/jobs +/career/internships +/career/freelancing +/career/resume +/career/portfolio +/career/companies +/career/resources +``` + +Jobs: + +```text +/career/jobs/[job] +``` + +--- + +# 👥 Community + +```text +/community +/community/discussions +/community/questions +/community/projects +/community/showcase +/community/events +/community/groups +/community/mentors +``` + +Question: + +```text +/community/questions/[id] +``` + +Discussion: + +```text +/community/discussions/[id] +``` + +--- + +# 🧑‍🏫 Contributors + +Because CodeHarborHub is open source: + +```text +/contributors +/contributors/[username] +/contribute +/contribute/start +/contribute/guidelines +/contribute/code +/contribute/docs +/contribute/content +/contribute/design +/contribute/translation +``` + +--- + +# 📅 Events + +```text +/events +/events/upcoming +/events/past +/events/hackathons +/events/workshops +/events/webinars +/events/bootcamps +/events/[event] +``` + +--- + +# 📚 Resources + +```text +/resources +/resources/books +/resources/websites +/resources/tools +/resources/cheatsheets +/resources/snippets +/resources/templates +/resources/datasets +/resources/apis +``` + +--- + +# 🛠️ Developer Tools + +```text +/tools +/tools/json +/tools/regex +/tools/markdown +/tools/base64 +/tools/url-encoder +/tools/timestamp +/tools/uuid +/tools/jwt +/tools/sql-formatter +/tools/code-formatter +``` + +--- + +# 📧 Newsletter + +```text +/newsletter +/newsletter/subscribe +/newsletter/archive +/newsletter/[issue] +``` + +--- + +# ❓ Help & Support + +```text +/help +/help/getting-started +/help/account +/help/courses +/help/tutorials +/help/practice +/help/certificates +/help/community +/help/technical +``` + +Other: + +```text +/support +/contact +/feedback +/faq +``` + +--- + +# 🏢 About CodeHarborHub + +```text +/about +/about/mission +/about/vision +/about/team +/about/community +/about/open-source +/about/contributors +``` + +--- + +# 🔐 Admin Panel + +Don't mix admin pages with learner pages. + +```text +/admin +/admin/dashboard +/admin/users +/admin/users/[id] +/admin/courses +/admin/courses/[id] +/admin/tutorials +/admin/docs +/admin/roadmaps +/admin/projects +/admin/problems +/admin/quizzes +/admin/certificates +/admin/blog +/admin/events +/admin/community +/admin/contributors +/admin/reports +/admin/analytics +/admin/moderation +/admin/settings +``` + +--- + +# 🗂️ Recommended CodeHarborHub Folder Structure + +If you're using **Docusaurus**, don't think of every route as a physical `pages` file. Docusaurus docs routes are generated from your docs structure. + +A good architecture would be: + +```text +codeharborhub/ +│ +├── docs/ +│ ├── html/ +│ ├── css/ +│ ├── javascript/ +│ ├── typescript/ +│ ├── react/ +│ ├── nodejs/ +│ ├── python/ +│ ├── git/ +│ ├── github/ +│ ├── linux/ +│ ├── dsa/ +│ ├── ai/ +│ ├── machine-learning/ +│ └── cyber-security/ +│ +├── blog/ +│ +├── src/ +│ ├── pages/ +│ │ ├── index.tsx +│ │ │ +│ │ ├── courses/ +│ │ ├── learning/ +│ │ ├── roadmaps/ +│ │ ├── tutorials/ +│ │ ├── practice/ +│ │ ├── projects/ +│ │ ├── quizzes/ +│ │ ├── certificates/ +│ │ ├── community/ +│ │ ├── contributors/ +│ │ ├── career/ +│ │ ├── ai/ +│ │ ├── editor/ +│ │ ├── labs/ +│ │ ├── tools/ +│ │ ├── events/ +│ │ ├── resources/ +│ │ ├── about/ +│ │ ├── help/ +│ │ ├── search/ +│ │ └── profile/ +│ │ +│ ├── components/ +│ ├── css/ +│ ├── theme/ +│ └── data/ +│ +└── static/ +``` + +--- + +# 🎯 CodeHarborHub Navigation + +I would **not put all these routes in the navbar**. + +Keep the primary navbar simple: + +```text +┌─────────────────────────────────────────────────────┐ +│ CodeHarborHub │ +│ │ +│ Learn Practice Build Roadmaps AI Community │ +│ Search Login │ +└─────────────────────────────────────────────────────┘ +``` + +### Learn + +```text +Learn +├── Courses +├── Tutorials +├── Documentation +├── Learning Paths +├── Roadmaps +└── Computer Science +``` + +### Practice + +```text +Practice +├── DSA +├── Coding Problems +├── Challenges +├── Quizzes +├── Assessments +└── Labs +``` + +### Build + +```text +Build +├── Projects +├── Code Editor +├── Developer Tools +└── Open Source +``` + +### Career + +```text +Career +├── Jobs +├── Internships +├── Interview +├── Resume +├── Portfolio +└── System Design +``` + +### Community + +```text +Community +├── Discussions +├── Questions +├── Projects +├── Events +├── Contributors +└── Mentorship +``` + +--- + +# 🧭 The Complete CodeHarborHub Ecosystem + +The final product architecture becomes: + +```text + CodeHarborHub + │ + ┌──────────────────────┼───────────────────────┐ + │ │ │ + LEARN PRACTICE BUILD + │ │ │ + ┌─────┼─────┐ ┌─────┼─────┐ ┌────┼────┐ + │ │ │ │ │ │ │ │ │ +Courses Docs Roadmaps DSA Quiz Challenges Projects Labs Editor + │ │ │ │ │ │ │ │ │ + └─────┴─────┘ └─────┴─────┘ └────┴────┘ + │ │ │ + └─────────────────┼──────────────────────┘ + │ + PROGRESS + │ + ┌───────────┼───────────┐ + │ │ │ + XP Achievements Streak + │ │ │ + └───────────┼───────────┘ + │ + CERTIFICATES + │ + CAREER + │ + ┌──────────────┼──────────────┐ + │ │ │ + Jobs Interview Portfolio + │ │ │ + └──────────────┼──────────────┘ + │ + COMMUNITY + │ + ┌──────────────┼──────────────┐ + │ │ │ + Questions Projects Open Source +``` + +## 🔥 The most important V1 routes + +If you're building CodeHarborHub **right now**, don't try to implement every route above. Start with these: + +```text +/ +├── /courses +├── /tutorials +├── /docs +├── /learning +├── /roadmaps +├── /practice +├── /practice/problems +├── /projects +├── /quizzes +├── /dashboard +├── /progress +├── /certificates +├── /community +├── /contributors +├── /blog +├── /search +├── /about +├── /contact +├── /help +├── /auth/* +└── /settings/* +``` + +Then add: + +```text +V2 +├── /ai +├── /editor +├── /labs +├── /assessments +├── /achievements +├── /leaderboard +└── /career +``` + +And later: + +```text +V3 +├── /mentorship +├── /events +├── /bootcamps +├── /jobs +├── /instructor +├── /teams +└── /enterprise +``` + +This gives **CodeHarborHub** a clean progression from an open-source learning/documentation platform into a full **Learn → Practice → Build → Prove → Career → Community** ecosystem without making the initial project unnecessarily complicated. diff --git a/project/index.md b/project/index.md new file mode 100644 index 000000000..ef686e086 --- /dev/null +++ b/project/index.md @@ -0,0 +1,7 @@ +--- +id: project +title: Welcome to our Projects +sidebar_label: WelCome to our Projects +sidebar_position: 1 +slug: / +--- diff --git a/projects/index.md b/projects/index.md index f39e76fc0..fd6c25a70 100644 --- a/projects/index.md +++ b/projects/index.md @@ -3,5 +3,5 @@ id: projects title: Welcome to our Projects sidebar_label: WelCome to our Projects sidebar_position: 1 -slug: / ---- +slug: intro +--- \ No newline at end of file diff --git a/src/components/Courses/MyChart.tsx b/src/components/Courses/MyChart.tsx deleted file mode 100644 index 819736cbd..000000000 --- a/src/components/Courses/MyChart.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React from 'react'; -import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Cell, Legend, ResponsiveContainer } from 'recharts'; - -const data = [ - { name: 'Javascript', language: 78 }, - { name: 'Python', language: 58 }, - { name: 'Java', language: 50 }, - { name: 'C#', language: 42 }, - { name: 'php', language: 38 }, - { name: 'C++', language: 35 }, - { name: 'TypeScript', language: 30 }, - { name: 'Ruby', language: 20 }, - { name: 'Swift', language: 18 }, - { name: 'go', language: 23 }, -]; - -const colors = [ - 'rgba(239,216,29,0.9)', - 'rgba(49,105,148,0.9)', - 'rgba(234,140,16,0.9)', - 'rgba(42,1,100,0.9)', - 'rgba(115,119,173,0.9)', - 'rgba(8,67,128,0.9)', - 'rgba(47,116,192,0.9)', - 'rgba(175,13,0,0.9)', - 'rgba(247,70,42,0.9)', - 'rgb(103,208,222,0.9)' -]; - -const CustomTooltip = ({ active, payload, label }) => { - if (active && payload && payload.length) { - return ( -
-

{label}

-
- ); - } - return null; -}; - -const MyChart: React.FC = () => { - return ( - <> -

Most Popular Programming Languages

- - - - - - } /> - - - {data.map((entry, index) => ( - - ))} - - - - - ); -}; - -export default MyChart; diff --git a/src/components/Courses/index.tsx b/src/components/Courses/index.tsx deleted file mode 100644 index d0b0f1baa..000000000 --- a/src/components/Courses/index.tsx +++ /dev/null @@ -1,216 +0,0 @@ -import React, { useState } from "react"; -import styled from "styled-components"; -import MyChart from "./MyChart"; - -// Define the Course interface to type the props -interface Course { - id: number; - title: string; - description: string; - category: string; - imageUrl: string; - author: string; - link: string; -} - -// Define the Props interface for the component's props -interface Props { - courses: Course[]; -} - -// Styled-components for various parts of the UI -const CoursesContainer = styled.div` - margin: 5px; -`; - -const FilterButtons = styled.div` - margin: 10px 0; - scroll-behavior: smooth; - overflow-x: auto; - white-space: nowrap; - -ms-overflow-style: none; - scrollbar-width: none; - gap: 10px; - border: 1px solid #ccc; - padding: 10px; - border-radius: 5px; - display: grid; - grid-auto-flow: column; - grid-auto-columns: max-content; -`; - -const Button = styled.button` - padding: 10px; - border: 1px solid #ccc; - border-radius: 5px; - cursor: pointer; - transition: background-color 0.3s; - - &:hover { - background-color: #007bff; - } -`; - -const CoursesList = styled.div` - display: grid; - grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); - grid-gap: 20px; - margin-top: 20px; -`; - -const CourseItem = styled.div` - border: 1px solid #ccc; - padding: 10px; - border-radius: 5px; - transition: transform 0.3s, box-shadow 0.3s; - - &:hover { - box-shadow: 0 0 10px 0 rgba(255, 64, 102, 1); - transform: scale(1.05); - border-color: red; - } -`; - -const CourseImage = styled.img` - width: 100%; - height: auto; - object-fit: cover; - background: linear-gradient(-30deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); - background-size: 150% 150%; -`; - -const CourseTitle = styled.h3` - margin-bottom: 5px; - padding: 0 5px; -`; - -const CourseDescription = styled.p` - margin-bottom: 5px; - padding: 0 8px; - text-align: justify; -`; - -const CourseAuthor = styled.span` - font-style: italic; - padding: 0 8px; -`; - -const VisitCourse = styled.div` - margin-top: 10px; - padding: 0 8px; - - a { - background-color: #007bff; - color: white; - padding: 10px; - border-radius: 5px; - text-decoration: none; - display: inline-block; - text-align: center; - width: 100%; - cursor: pointer; - transition: background-color 0.3s; - - &:hover { - background-color: #0056b3; - } - } -`; - -// Courses component with filter functionality -const Courses: React.FC = ({ courses }) => { - const [filter, setFilter] = useState("all"); - - // Filter courses based on the selected filter - const filteredCourses = - filter === "all" - ? courses - : courses.filter((course) => course.category === filter); - - return ( - - - {/* Chart */} - - - {/* Filter buttons */} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {/* Display the filtered list of courses */} - - {filteredCourses.map((course) => ( - - - {course.title} - {course.description} - - Author: {course.author} - - - - Visit Course - - - - ))} - - - ); -}; - -export default Courses; diff --git a/src/components/Roadmap/ProgressBar.tsx b/src/components/Roadmap/ProgressBar.tsx deleted file mode 100644 index 6c3662b31..000000000 --- a/src/components/Roadmap/ProgressBar.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from "react"; - -interface ProgressBarProps { - completed: number; - total: number; -} - -const ProgressBar: React.FC = ({ completed, total }) => { - const percentage = total > 0 ? (completed / total) * 100 : 0; - - return ( -
-
- - {completed} / {total} Completed - -
-
-
-
-
- ); -}; - -export default ProgressBar; \ No newline at end of file diff --git a/src/components/Roadmap/Roadmap.css b/src/components/Roadmap/Roadmap.css deleted file mode 100644 index 3eb8af48a..000000000 --- a/src/components/Roadmap/Roadmap.css +++ /dev/null @@ -1,117 +0,0 @@ - -.roadmap-container { - padding: 20px; -} - -.roadmap-container .roadmap-title { - text-align: center; - font-size: 2.5rem; - margin-bottom: 30px; - background: linear-gradient( - 90deg, - rgb(106, 0, 255) 0%, - rgb(152 0 255) 30%, - rgb(246 41 41) 65%, - rgb(255 169 8) 100% - ); - background-clip: text; - -webkit-text-fill-color: transparent; -} - -.roadmap-container .roadmap-controls { - display: flex; - justify-content: center; - margin-bottom: 20px; -} - -.roadmap-container .roadmap-search { - padding: 10px; - font-size: 1.2rem; - border: 1px solid var(--ifm-color-primary); - border-radius: 5px; - width: 100%; - max-width: 400px; -} - -.roadmap-container .roadmap-category { - margin-bottom: 30px; -} - -.roadmap-container .roadmap-category .roadmap-category-title { - text-align: center; - font-size: 1.5rem; - cursor: pointer; - color: var(--ifm-color-primary); - margin:40px 0; -} - - -.roadmap-container .roadmap-category .roadmap-category-title::after { - content: ""; - display: block; - width: 40%; - height: 1px; - background: linear-gradient(to left, var(--ifm-color-primary), transparent); - margin-top: -14px; - margin-left: auto; -} - -.roadmap-container .roadmap-category .roadmap-category-title::before { - content: ""; - display: block; - width: 40%; - height: 1px; - background: linear-gradient(to right, var(--ifm-color-primary), transparent); - margin-bottom: -20px; - -} - -.roadmap-container .roadmap-category .roadmap-cards { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); - gap: 20px; - list-style: none; - padding: 0; -} - -.roadmap-container .roadmap-category .roadmap-cards .roadmap-card { - border: 1px solid var(--ifm-color-primary); - border-radius: 8px; - padding: 15px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - transition: transform 0.3s ease, box-shadow 0.3s ease; - text-align: center; -} - -.roadmap-container .roadmap-category .roadmap-cards .roadmap-card:hover { - transform: translateY(-2px); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15); -} - -.roadmap-container .roadmap-category .roadmap-cards .roadmap-card .roadmap-link { - text-decoration: none; - color: var(--ifm-color-primary); - font-size: 1.1rem; -} - -.roadmap-container .roadmap-category .roadmap-cards .roadmap-card .roadmap-link:hover { - color: var(--ifm-color-primary-darkest); -} - -@media (min-width: 600px) { - .roadmap-container .roadmap-category .roadmap-cards { - grid-template-columns: repeat(2, 1fr); - } -} - -@media (min-width: 900px) { - .roadmap-container .roadmap-category .roadmap-cards { - grid-template-columns: repeat(3, 1fr); - } -} - -@media (min-width: 380px) { - .roadmap-container .roadmap-category .roadmap-cards { - grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); - } -} diff --git a/src/components/Roadmap/RoadmapCard.tsx b/src/components/Roadmap/RoadmapCard.tsx deleted file mode 100644 index 8b002f6a4..000000000 --- a/src/components/Roadmap/RoadmapCard.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React from "react"; -import Link from "@docusaurus/Link"; - -interface RoadmapCardProps { - section: { - title: string; - items: { text: string; status: string; link: string }[]; - }; - sectionIndex: number; - updateItemStatus: (sectionIndex: number, itemIndex: number) => void; -} - -const RoadmapCard: React.FC = ({ - section, - sectionIndex, - updateItemStatus, -}) => { - return ( -
-

- {section.title} -

-
    - {section.items.map((item, itemIndex) => ( -
  • - - {item.text} - - -
  • - ))} -
-
- ); -}; - -export default RoadmapCard; diff --git a/src/components/Roadmap/RoadmapList.tsx b/src/components/Roadmap/RoadmapList.tsx deleted file mode 100644 index 4bad02169..000000000 --- a/src/components/Roadmap/RoadmapList.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from "react"; -import RoadmapCard from './RoadmapCard'; - -interface RoadmapListProps { - roadmap: any[]; - updateItemStatus: (sectionIndex: number, itemIndex: number) => void; -} - -const RoadmapList: React.FC = ({ roadmap, updateItemStatus }) => { - return ( -
- {roadmap.map((section, sectionIndex) => ( - - ))} -
- ); -}; - -export default RoadmapList; \ No newline at end of file diff --git a/src/components/Roadmap/index.tsx b/src/components/Roadmap/index.tsx deleted file mode 100644 index e3ee7fe5d..000000000 --- a/src/components/Roadmap/index.tsx +++ /dev/null @@ -1,329 +0,0 @@ -import React, { useState } from "react"; -import "./Roadmap.css"; -import Link from "@docusaurus/Link"; - -interface TechCategory { - id: number; - title: string; - technologies: { id: number; name: string; link: string }[]; -} - -const techCategories: TechCategory[] = [ - { - id: 1, - title: "Frontend", - technologies: [ - { id: 1, name: "HTML", link: "/roadmap/html/" }, - { id: 2, name: "CSS", link: "#" }, - { id: 3, name: "JavaScript", link: "#" }, - { id: 4, name: "React", link: "https://roadmap.sh/react" }, - { id: 5, name: "Angular", link: "#" }, - { id: 6, name: "Vue.js", link: "#" }, - { id: 7, name: "Svelte", link: "#" }, - { id: 8, name: "TypeScript", link: "#" }, - { id: 9, name: "Bootstrap", link: "#" }, - { id: 10, name: "Tailwind CSS", link: "#" }, - { id: 11, name: "jQuery", link: "#" }, - { id: 12, name: "Ember.js", link: "#" }, - { id: 13, name: "Backbone.js", link: "#" }, - { id: 14, name: "Webpack", link: "#" }, - { id: 15, name: "Parcel", link: "#" }, - { id: 16, name: "Gatsby", link: "#" }, - { id: 17, name: "Next.js", link: "#" }, - ], - }, - { - id: 2, - title: "Backend", - technologies: [ - { id: 18, name: "Node.js", link: "#" }, - { id: 19, name: "Express.js", link: "#" }, - { id: 20, name: "Django", link: "#" }, - { id: 21, name: "Ruby on Rails", link: "#" }, - { id: 22, name: "Spring Boot", link: "#" }, - { id: 23, name: "Flask", link: "#" }, - { id: 24, name: "Laravel", link: "#" }, - { id: 25, name: "ASP.NET Core", link: "#" }, - { id: 26, name: "Koa.js", link: "#" }, - { id: 27, name: "Gin", link: "#" }, - { id: 28, name: "Phoenix", link: "#" }, - { id: 29, name: "FastAPI", link: "#" }, - { id: 30, name: "Hapi.js", link: "#" }, - { id: 31, name: "NestJS", link: "#" }, - ], - }, - { - id: 3, - title: "Mobile Development", - technologies: [ - { id: 32, name: "React Native", link: "#" }, - { id: 33, name: "Flutter", link: "#" }, - { id: 34, name: "Swift", link: "#" }, - { id: 35, name: "Kotlin", link: "#" }, - { id: 36, name: "Java", link: "#" }, - { id: 37, name: "Ionic", link: "#" }, - { id: 38, name: "Xamarin", link: "#" }, - { id: 39, name: "Cordova", link: "#" }, - { id: 40, name: "Objective-C", link: "#" }, - { id: 41, name: "PhoneGap", link: "#" }, - ], - }, - { - id: 4, - title: "DevOps", - technologies: [ - { id: 42, name: "Docker", link: "#" }, - { id: 43, name: "Kubernetes", link: "#" }, - { id: 44, name: "Jenkins", link: "#" }, - { id: 45, name: "Travis CI", link: "#" }, - { id: 46, name: "CircleCI", link: "#" }, - { id: 47, name: "GitLab CI/CD", link: "#" }, - { id: 48, name: "Terraform", link: "#" }, - { id: 49, name: "Ansible", link: "#" }, - { id: 50, name: "Puppet", link: "#" }, - { id: 51, name: "Chef", link: "#" }, - { id: 52, name: "Vagrant", link: "#" }, - { id: 53, name: "SaltStack", link: "#" }, - { id: 54, name: "Bamboo", link: "#" }, - ], - }, - { - id: 5, - title: "Database", - technologies: [ - { id: 55, name: "MySQL", link: "#" }, - { id: 56, name: "PostgreSQL", link: "#" }, - { id: 57, name: "MongoDB", link: "#" }, - { id: 58, name: "SQLite", link: "#" }, - { id: 59, name: "Redis", link: "#" }, - { id: 60, name: "MariaDB", link: "#" }, - { id: 61, name: "Oracle Database", link: "#" }, - { id: 62, name: "Microsoft SQL Server", link: "#" }, - { id: 63, name: "Firebase Realtime Database", link: "#" }, - { id: 64, name: "Elasticsearch", link: "#" }, - { id: 65, name: "Cassandra", link: "#" }, - { id: 66, name: "DynamoDB", link: "#" }, - { id: 67, name: "Neo4j", link: "#" }, - { id: 68, name: "CouchDB", link: "#" }, - ], - }, - { - id: 6, - title: "Cloud Platforms", - technologies: [ - { id: 69, name: "Amazon Web Services (AWS)", link: "#" }, - { id: 70, name: "Microsoft Azure", link: "#" }, - { id: 71, name: "Google Cloud Platform (GCP)", link: "#" }, - { id: 72, name: "IBM Cloud", link: "#" }, - { id: 73, name: "Oracle Cloud", link: "#" }, - { id: 74, name: "DigitalOcean", link: "#" }, - { id: 75, name: "Heroku", link: "#" }, - { id: 76, name: "Firebase", link: "#" }, - { id: 77, name: "Netlify", link: "#" }, - { id: 78, name: "Vercel", link: "#" }, - { id: 79, name: "Linode", link: "#" }, - { id: 80, name: "Vultr", link: "#" }, - ], - }, - { - id: 7, - title: "Version Control", - technologies: [ - { id: 81, name: "Git", link: "#" }, - { id: 82, name: "GitHub", link: "#" }, - { id: 83, name: "GitLab", link: "#" }, - { id: 84, name: "Bitbucket", link: "#" }, - { id: 85, name: "SVN", link: "#" }, - { id: 86, name: "Mercurial", link: "#" }, - { id: 87, name: "Perforce", link: "#" }, - ], - }, - { - id: 8, - title: "Testing", - technologies: [ - { id: 88, name: "Jest", link: "#" }, - { id: 89, name: "Mocha", link: "#" }, - { id: 90, name: "Chai", link: "#" }, - { id: 91, name: "Jasmine", link: "#" }, - { id: 92, name: "Cypress", link: "#" }, - { id: 93, name: "Puppeteer", link: "#" }, - { id: 94, name: "Selenium", link: "#" }, - { id: 95, name: "JUnit", link: "#" }, - { id: 96, name: "pytest", link: "#" }, - { id: 97, name: "TestNG", link: "#" }, - { id: 98, name: "Robot Framework", link: "#" }, - { id: 99, name: "Cucumber", link: "#" }, - { id: 100, name: "Karma", link: "#" }, - ], - }, - { - id: 9, - title: "Data Science & Machine Learning", - technologies: [ - { id: 101, name: "TensorFlow", link: "#" }, - { id: 102, name: "PyTorch", link: "#" }, - { id: 103, name: "Keras", link: "#" }, - { id: 104, name: "Scikit-learn", link: "#" }, - { id: 105, name: "Pandas", link: "#" }, - { id: 106, name: "NumPy", link: "#" }, - { id: 107, name: "Matplotlib", link: "#" }, - { id: 108, name: "Seaborn", link: "#" }, - { id: 109, name: "Apache Spark", link: "#" }, - { id: 110, name: "Dask", link: "#" }, - { id: 111, name: "NLTK", link: "#" }, - { id: 112, name: "spaCy", link: "#" }, - { id: 113, name: "H2O.ai", link: "#" }, - { id: 114, name: "Theano", link: "#" }, - ], - }, - { - id: 10, - title: "Cybersecurity", - technologies: [ - { id: 115, name: "Nmap", link: "#" }, - { id: 116, name: "Wireshark", link: "#" }, - { id: 117, name: "Metasploit", link: "#" }, - { id: 118, name: "Burp Suite", link: "#" }, - { id: 119, name: "OWASP ZAP", link: "#" }, - { id: 120, name: "Kali Linux", link: "#" }, - { id: 121, name: "Snort", link: "#" }, - { id: 122, name: "Suricata", link: "#" }, - { id: 123, name: "Nessus", link: "#" }, - { id: 124, name: "OpenVAS", link: "#" }, - { id: 125, name: "Acunetix", link: "#" }, - { id: 126, name: "Nikto", link: "#" }, - ], - }, - { - id: 11, - title: "Web Servers", - technologies: [ - { id: 127, name: "Apache HTTP Server", link: "#" }, - { id: 128, name: "Nginx", link: "#" }, - { id: 129, name: "LiteSpeed", link: "#" }, - { id: 130, name: "Caddy", link: "#" }, - { id: 131, name: "Tomcat", link: "#" }, - { id: 132, name: "Microsoft IIS", link: "#" }, - { id: 133, name: "Jetty", link: "#" }, - { id: 134, name: "WildFly", link: "#" }, - ], - }, - { - id: 12, - title: "Containerization", - technologies: [ - { id: 135, name: "Docker", link: "#" }, - { id: 136, name: "Kubernetes", link: "#" }, - { id: 137, name: "OpenShift", link: "#" }, - { id: 138, name: "Rancher", link: "#" }, - { id: 139, name: "Mesos", link: "#" }, - { id: 140, name: "LXC", link: "#" }, - { id: 141, name: "CRI-O", link: "#" }, - { id: 142, name: "Podman", link: "#" }, - ], - }, - { - id: 13, - title: "Big Data", - technologies: [ - { id: 143, name: "Hadoop", link: "#" }, - { id: 144, name: "Apache Spark", link: "#" }, - { id: 145, name: "Apache Flink", link: "#" }, - { id: 146, name: "Apache Storm", link: "#" }, - { id: 147, name: "Apache Kafka", link: "#" }, - { id: 148, name: "Apache Hive", link: "#" }, - { id: 149, name: "Apache HBase", link: "#" }, - { id: 150, name: "Apache NiFi", link: "#" }, - { id: 151, name: "Presto", link: "#" }, - { id: 152, name: "Druid", link: "#" }, - ], - }, - { - id: 14, - title: "Internet of Things (IoT)", - technologies: [ - { id: 153, name: "Arduino", link: "#" }, - { id: 154, name: "Raspberry Pi", link: "#" }, - { id: 155, name: "ESP8266", link: "#" }, - { id: 156, name: "ESP32", link: "#" }, - { id: 157, name: "MQTT", link: "#" }, - { id: 158, name: "Zigbee", link: "#" }, - { id: 159, name: "LoRaWAN", link: "#" }, - { id: 160, name: "Particle", link: "#" }, - { id: 161, name: "ThingSpeak", link: "#" }, - ], - }, - { - id: 15, - title: "Blockchain", - technologies: [ - { id: 162, name: "Ethereum", link: "#" }, - { id: 163, name: "Hyperledger Fabric", link: "#" }, - { id: 164, name: "Solidity", link: "#" }, - { id: 165, name: "Truffle", link: "#" }, - { id: 166, name: "Ganache", link: "#" }, - { id: 167, name: "Corda", link: "#" }, - { id: 168, name: "Quorum", link: "#" }, - { id: 169, name: "Polkadot", link: "#" }, - { id: 170, name: "Chainlink", link: "#" }, - ], - }, -]; -const Roadmap: React.FC = () => { - const [searchTerm, setSearchTerm] = useState(""); - const [collapsedCategories, setCollapsedCategories] = useState([]); - - const toggleCollapse = (id: number) => { - setCollapsedCategories((prev) => - prev.includes(id) ? prev.filter((cid) => cid !== id) : [...prev, id] - ); - }; - - const filteredCategories = techCategories - .map((category) => ({ - ...category, - technologies: category.technologies.filter((tech) => - tech.name.toLowerCase().includes(searchTerm.toLowerCase()) - ), - })) - .filter((category) => category.technologies.length > 0); - - return ( -
-

Technology Roadmap

-
- setSearchTerm(e.target.value)} - className="roadmap-search" - /> -
- {filteredCategories.map((category) => ( -
-

toggleCollapse(category.id)} - > - {category.title} -

- {!collapsedCategories.includes(category.id) && ( -
    - {category.technologies.map((tech) => ( -
  • - - {tech.name} - -
  • - ))} -
- )} -
- ))} -
- ); -}; - -export default Roadmap; diff --git a/src/css/custom.css b/src/css/custom.css index 28a0cbd2d..c8d74aa28 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -357,4 +357,93 @@ mark { [data-theme="dark"] .navbar { background: rgba(15, 23, 42, 0.862); border-bottom: 1px solid #4e8da0db; +} + +.button--secondary { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + + min-height: 44px; + padding: 0.7rem 1.15rem; + + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 12px; + + background: var(--ifm-background-surface-color); + color: var(--ifm-font-color-base); + + font-size: 0.95rem; + font-weight: 700; + line-height: 1; + text-decoration: none; + + box-shadow: 0 1px 2px rgb(0 0 0 / 6%); + + transition: + background-color 180ms ease, + border-color 180ms ease, + color 180ms ease, + box-shadow 180ms ease, + transform 180ms ease; +} + +.button--secondary:hover { + background: var(--ifm-hover-overlay); + border-color: var(--ifm-color-primary); + color: var(--ifm-color-primary); + + box-shadow: + 0 6px 18px rgb(0 0 0 / 8%); + + text-decoration: none; + transform: translateY(-2px); +} + +.button--secondary:active { + transform: translateY(0); + box-shadow: 0 2px 8px rgb(0 0 0 / 8%); +} + +.button--secondary:focus-visible { + outline: 3px solid + color-mix(in srgb, var(--ifm-color-primary) 30%, transparent); + outline-offset: 3px; +} + +.button--secondary:disabled, +.button--secondary[aria-disabled="true"] { + opacity: 0.55; + cursor: not-allowed; + pointer-events: none; +} + +/* Dark mode */ +[data-theme="dark"] .button--secondary { + background: var(--ifm-background-surface-color); + border-color: var(--ifm-color-emphasis-400); + color: var(--ifm-font-color-base); + + box-shadow: 0 1px 2px rgb(0 0 0 / 20%); +} + +[data-theme="dark"] .button--secondary:hover { + background: var(--ifm-hover-overlay); + border-color: var(--ifm-color-primary-light); + color: var(--ifm-color-primary-light); + + box-shadow: + 0 8px 24px rgb(0 0 0 / 25%); +} + +/* Reduced motion */ +@media (prefers-reduced-motion: reduce) { + .button--secondary { + transition: none; + } + + .button--secondary:hover { + transform: none; + } } \ No newline at end of file diff --git a/src/data/roadmaps/html.tsx b/src/data/roadmaps/html.tsx deleted file mode 100644 index 1d8580f7f..000000000 --- a/src/data/roadmaps/html.tsx +++ /dev/null @@ -1,74 +0,0 @@ -export const htmlRoadmapData = [ - { - title: "HTML Basics", - items: [ - { text: "Introduction to HTML", link: "#", status: "todo" }, - { text: "HTML Documents Structure", link: "#", status: "todo" }, - { text: "Basic HTML Tags", link: "#", status: "todo" }, - { text: "Attributes in HTML", link: "#", status: "todo" }, - { - text: "HTML Paragraphs and Text Formatting", - link: "#", - status: "todo", - }, - { text: "Links and Images in HTML", link: "#", status: "todo" }, - { text: "HTML Lists", link: "#", status: "todo" }, - ], - }, - { - title: "HTML Forms", - items: [ - { text: "Introduction to HTML Forms", link: "#", status: "todo" }, - { text: "Form Elements and Attributes", link: "#", status: "todo" }, - { text: "Input Types in HTML", link: "#", status: "todo" }, - { text: "Form Action and Method", link: "#", status: "todo" }, - { text: "HTML Form Validation", link: "#", status: "todo" }, - ], - }, - { - title: "HTML5 Elements", - items: [ - { text: "HTML5 Semantic Elements", link: "#", status: "todo" }, - { text: "HTML5 Media Elements", link: "#", status: "todo" }, - { text: "HTML5 Graphics Elements", link: "#", status: "todo" }, - { text: "HTML5 Form Types", link: "#", status: "todo" }, - { text: "HTML5 New Attributes", link: "#", status: "todo" }, - { text: "Web Storage in HTML5", link: "#", status: "todo" }, - ], - }, - { - title: "HTML Tables", - items: [ - { text: "Basic HTML Table Structure", link: "#", status: "todo" }, - { text: "HTML Table Attributes", link: "#", status: "todo" }, - { text: "Row and Colspan in HTML", link: "#", status: "todo" }, - { text: "Table Caption and Summary", link: "#", status: "todo" }, - { text: "Complex Tables in HTML", link: "#", status: "todo" }, - ], - }, - { - title: "HTML and SEO", - items: [ - { text: "Basic SEO Concepts", link: "#", status: "todo" }, - { text: "HTML Tags and SEO", link: "#", status: "todo" }, - { text: "SEO and HTML Meta Tags", link: "#", status: "todo" }, - { text: "SEO and HTML Sitemap", link: "#", status: "todo" }, - { text: "SEO and HTML Robots", link: "#", status: "todo" }, - ], - }, - { - title: "Responsive Web Design", - items: [ - { - text: "Understanding Responsive Web Design", - link: "#", - status: "todo", - }, - { text: "Media Queries in CSS", link: "#", status: "todo" }, - { text: "Responsive Images", link: "#", status: "todo" }, - { text: "CSS Flexbox", link: "#", status: "todo" }, - { text: "CSS Grid", link: "#", status: "todo" }, - { text: "CSS Frameworks", link: "#", status: "todo" }, - ], - }, -]; \ No newline at end of file diff --git a/src/data/roadmaps/index.tsx b/src/data/roadmaps/index.tsx deleted file mode 100644 index ec6f7d5b3..000000000 --- a/src/data/roadmaps/index.tsx +++ /dev/null @@ -1,57 +0,0 @@ -export interface Lesson { - id: string; - title: string; - duration: string; - link: string; -} - -export interface MyRoadmap { - id: string; - title: string; - description: string; - lessons: Lesson[]; -} - -export const roadmaps: MyRoadmap[] = [ - { - id: "html", - title: "HTML Basics", - description: "Learn the basics of HTML", - lessons: [ - { - id: "html_intro", - title: "Introduction to HTML", - duration: "1 hour", - link: "https://www.w3schools.com/html/", - }, - { - id: "html_elements", - title: "HTML Elements", - duration: "2 hours", - link: "https://www.w3schools.com/html/html_elements.asp", - }, - // Add more lessons as needed - ], - }, - { - id: "css", - title: "CSS Styling", - description: "Learn CSS for styling web pages", - lessons: [ - { - id: "css_intro", - title: "Introduction to CSS", - duration: "1.5 hours", - link: "https://www.w3schools.com/css/", - }, - { - id: "css_selectors", - title: "CSS Selectors", - duration: "2.5 hours", - link: "https://www.w3schools.com/css/css_selectors.asp", - }, - // Add more lessons as needed - ], - }, - // Add more courses (React, Node.js, etc.) -]; diff --git a/src/data/roadmaps/javascript/index.tsx b/src/data/roadmaps/javascript/index.tsx deleted file mode 100644 index f43fa8d5c..000000000 --- a/src/data/roadmaps/javascript/index.tsx +++ /dev/null @@ -1,191 +0,0 @@ - -export interface Topic { - title: string; - description: string; - } - -export interface RoadmapItem { - title: string; - description: string; - topics: Topic[]; - } - - const roadmapJavaScript: RoadmapItem[] = [ - { - title: "Beginner Topics", - description: "Start with these!", - topics: [ - { - title: "Introduction to JavaScript", - description: "Learn the basics of JavaScript", - }, - { - title: "Variables", - description: "Learn how to declare variables", - }, - { - title: "Data Types", - description: "Learn about the different data types in JavaScript", - }, - { - title: "Operators", - description: "Learn about the different operators in JavaScript", - }, - { - title: "Control Structures", - description: "Learn about control structures in JavaScript", - }, - { - title: "Functions", - description: "Learn about functions in JavaScript", - }, - { - title: "Arrays", - description: "Learn about arrays in JavaScript", - }, - { - title: "Objects", - description: "Learn about objects in JavaScript", - }, - { - title: "Classes", - description: "Learn about classes in JavaScript", - }, - { - title: "DOM Manipulation", - description: "Learn about manipulating the DOM in JavaScript", - }, - { - title: "Events", - description: "Learn about events in JavaScript", - }, - { - title: "AJAX", - description: "Learn about AJAX in JavaScript", - }, - { - title: "ES6 Features", - description: "Learn about the new features in ES6", - }, - ], - }, - { - title: "Intermediate Topics", - description: "Pick these after beginner topics", - topics: [ - { - title: "Promises", - description: "Learn about promises in JavaScript", - }, - { - title: "Async/Await", - description: "Learn about async/await in JavaScript", - }, - { - title: "Modules", - description: "Learn about modules in JavaScript", - }, - { - title: "Error Handling", - description: "Learn about error handling in JavaScript", - }, - { - title: "Regular Expressions", - description: "Learn about regular expressions in JavaScript", - }, - { - title: "Closures", - description: "Learn about closures in JavaScript", - }, - { - title: "Scope", - description: "Learn about scope in JavaScript", - }, - { - title: "This Keyword", - description: "Learn about the this keyword in JavaScript", - }, - { - title: "Prototype", - description: "Learn about prototype in JavaScript", - }, - { - title: "Functional Programming", - description: "Learn about functional programming in JavaScript", - }, - { - title: "Testing", - description: "Learn about testing in JavaScript", - }, - { - title: "Debugging", - description: "Learn about debugging in JavaScript", - }, - { - title: "Performance", - description: "Learn about performance in JavaScript", - }, - ], - }, - { - title: "Advanced Topics", - description: "Pick these after intermediate topics", - topics: [ - { - title: "Web Components", - description: "Learn about web components in JavaScript", - }, - { - title: "Web Workers", - description: "Learn about web workers in JavaScript", - }, - { - title: "Service Workers", - description: "Learn about service workers in JavaScript", - }, - { - title: "Web Assembly", - description: "Learn about web assembly in JavaScript", - }, - { - title: "Web Sockets", - description: "Learn about web sockets in JavaScript", - }, - { - title: "WebRTC", - description: "Learn about webRTC in JavaScript", - }, - { - title: "Node.js", - description: "Learn about Node.js", - }, - { - title: "Express.js", - description: "Learn about Express.js", - }, - { - title: "GraphQL", - description: "Learn about GraphQL", - }, - { - title: "React", - description: "Learn about React", - }, - { - title: "Vue", - description: "Learn about Vue", - }, - { - title: "Angular", - description: "Learn about Angular", - }, - { - title: "TypeScript", - description: "Learn about TypeScript", - }, - ], - }, - // Add more items as needed - ]; - - export default roadmapJavaScript; diff --git a/src/pages/License/index.tsx b/src/pages/License/index.tsx index d3c1172a9..f06ecbb3a 100644 --- a/src/pages/License/index.tsx +++ b/src/pages/License/index.tsx @@ -1,80 +1,533 @@ -import React from 'react'; -import Layout from '@theme/Layout'; -import styled from 'styled-components'; - -// Styled Components -const LicensingContainer = styled.div` - max-width: 800px; - margin: 0 auto; - padding: 20px; - border-radius: 5px; - box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1); - margin-top: 20px; - margin-bottom: 20px; - font-size: 16px; - line-height: 1.6; - font-family: 'Open Sans', sans-serif; - text-align: justify; -`; - -const Title = styled.h2` - margin-bottom: 24px; - font-family: 'Open Sans', sans-serif; - font-weight: 700; - line-height: 1.6; - text-align: center; - font-size: 27px; -`; - -const SubTitle = styled.h3` - margin-bottom: 20px; - font-weight: 700; -`; - -const Content = styled.p` - margin-bottom: 20px; -`; - -// Licensing Component -const Licensing: React.FC = () => { +import React from "react"; +// @ts-ignore +import Layout from "@theme/Layout"; +// @ts-ignore +import Link from "@docusaurus/Link"; + +import { + ArrowLeft, + ArrowRight, + Check, + ChevronRight, + Code2, + Copy, + ExternalLink, + FileCode2, + GitBranch, + Info, + Scale, + ShieldCheck, + Sparkles, +} from "lucide-react"; + +// @ts-ignore +import styles from "./styles.module.css"; + +const permissions = [ + "Use the software", + "Copy the software", + "Modify the software", + "Merge the software", + "Publish the software", + "Distribute the software", + "Sublicense the software", + "Sell copies of the software", +]; + +const licenseConditions = [ + "Include the original copyright notice.", + "Include the MIT License permission notice.", + "Keep the notices in copies or substantial portions of the Software.", +]; + +const disclaimerItems = [ + "No warranty is provided.", + 'The Software is provided "AS IS".', + "The authors make no guarantees regarding merchantability.", + "The authors make no guarantees regarding fitness for a particular purpose.", + "The authors are not liable for claims, damages, or other liability arising from the Software.", +]; + +export default function LicensePage(): React.JSX.Element { + const copyLicense = async () => { + const licenseText = `MIT License + +Copyright (c) 2024 CodeHarborHub + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE.`; + + try { + await navigator.clipboard.writeText(licenseText); + } catch { + // Clipboard access may be unavailable in some browser contexts. + } + }; + return ( - - Licensing - - Welcome to CodeHarborHub. This project is licensed under the MIT License. This page outlines the terms of the license and provides details on how you can use, modify, and distribute our project. - - - MIT License - - Copyright (c) 2024 CodeHarborHub -

- Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: -

- The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. -

- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -

-
-
-
+
+ {/* Breadcrumb */} +
+ +
+ + {/* Hero */} +
+
+
+
+
+ + Open source licensing +
+ +

+ CodeHarborHub is + MIT licensed. +

+ +

+ This project is licensed under the MIT License. You are free + to use, copy, modify, publish, distribute, sublicense, and + sell the software, subject to the terms of the license. +

+ +
+ + View LICENSE file + + + + + Contribute + + +
+
+ + {/* License Visual */} +
+
+ +
+
+
+ +
+ + Open Source +
+ +
MIT
+ +
+
+ Copyright + 2024 CodeHarborHub +
+ +
+ Permissions + Broad +
+
+ +
+ + LICENSE +
+
+
+
+
+
+ + {/* Quick Summary */} +
+
+
+
+
+ +
+
+ Use freely + Personal and commercial use is permitted. +
+
+ +
+
+ +
+
+ Modify & distribute + You can adapt and distribute the Software. +
+
+ +
+
+ +
+
+ Keep the notice + Include the copyright and license notice. +
+
+ +
+
+ +
+
+ No warranty + The Software is provided without warranty. +
+
+
+
+
+ + {/* Main Content */} +
+
+
+ {/* Sidebar */} + + + {/* Article */} +
+
+
+
+ +
+ +
+ 01 +

Licensing

+
+
+ +

+ Welcome to CodeHarborHub. This project is licensed under the + MIT License. This page outlines the terms of the license and + provides details on how you can use, modify, and distribute + our project. +

+ +
+ + +
+ What this means +

+ The MIT License is a permissive open-source license that + allows broad use of the Software while requiring + preservation of the copyright and license notice. +

+
+
+
+ +
+
+
+ +
+ +
+ 02 +

What you can do

+
+
+ +

+ Under the MIT License, permission is granted to deal with + the Software without restriction, subject to the license + conditions. +

+ +
+ {permissions.map((permission) => ( +
+ + {permission} +
+ ))} +
+
+ +
+
+
+ +
+ +
+ 03 +

License conditions

+
+
+ +

+ The MIT License contains a small number of conditions that + must be followed when using or distributing the Software. +

+ +
+ {licenseConditions.map((condition, index) => ( +
+ {String(index + 1).padStart(2, "0")} +

{condition}

+
+ ))} +
+
+ +
+
+
+ +
+ +
+ 04 +

Warranty & liability

+
+
+ +

+ The Software is provided "AS IS", without warranty + of any kind, express or implied. +

+ +
+
+ + No warranty is provided +
+ +
+ {disclaimerItems.map((item) => ( +
+ +

{item}

+
+ ))} +
+
+
+ + {/* Full License */} +
+
+
+ +
+ +
+ 05 +

MIT License

+
+
+ +
+
+ MIT License + Copyright (c) 2024 CodeHarborHub +
+ + +
+ +
+
+                      
+                        {`MIT License
+
+Copyright (c) 2024 CodeHarborHub
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.`}
+                      
+                    
+
+
+
+
+
+
+ + {/* Repository CTA */} +
+
+
+
+ +
+ +
+ Open source +

Explore the source code

+

+ CodeHarborHub is developed openly. Explore the repository, + review the source, report issues, and contribute improvements. +

+
+ + + GitHub Repository + + +
+
+
+ + {/* Related Links */} +
+
+
+ Continue exploring +

CodeHarborHub resources

+
+ +
+ + + +
+

Contributing

+

Learn how to contribute to CodeHarborHub.

+
+ + + + + + + +
+

Code of Conduct

+

Help us maintain a respectful community.

+
+ + + + + + + +
+

Privacy Policy

+

Learn how CodeHarborHub handles information.

+
+ + + +
+
+
+ + {/* Bottom CTA */} +
+
+
+
+ + MIT License +
+ +

Build, learn, modify, and contribute.

+ +

+ Use CodeHarborHub as a foundation for learning and building, + while following the terms of the MIT License. +

+ +
+ + Start learning + + + + + Contribute to CodeHarborHub + + +
+
+
+
+
); -}; - -export default Licensing; +} diff --git a/src/pages/License/styles.module.css b/src/pages/License/styles.module.css new file mode 100644 index 000000000..bb084b04a --- /dev/null +++ b/src/pages/License/styles.module.css @@ -0,0 +1,1037 @@ +.page { + min-height: 100vh; + overflow: hidden; +} + +/* ===================================================== + Breadcrumb +===================================================== */ + +.breadcrumb { + display: flex; + align-items: center; + gap: 7px; + padding: 18px 0 8px; + color: var(--ifm-color-emphasis-600); + font-size: 0.84rem; +} + +.breadcrumb a { + color: var(--ifm-color-primary); + text-decoration: none; +} + +.breadcrumb a:hover { + text-decoration: underline; +} + +/* ===================================================== + Hero +===================================================== */ + +.hero { + position: relative; + padding: 3rem 0 2rem; + background: + radial-gradient( + circle at 8% 20%, + color-mix(in srgb, var(--ifm-color-primary) 13%, transparent), + transparent 33% + ), + radial-gradient( + circle at 88% 30%, + color-mix(in srgb, #7c3aed 10%, transparent), + transparent 32% + ); +} + +.hero::after { + content: ""; + position: absolute; + right: 0; + bottom: 0; + left: 0; + height: 1px; + background: var(--ifm-color-emphasis-200); +} + +.heroGrid { + display: grid; + grid-template-columns: minmax(0, 1.15fr) minmax(340px, 0.85fr); + gap: 70px; + align-items: center; +} + +.heroContent { + max-width: 760px; +} + +.eyebrow { + display: inline-flex; + align-items: center; + gap: 7px; + color: var(--ifm-color-primary); + font-size: 0.76rem; + font-weight: 800; + letter-spacing: 0.09em; + text-transform: uppercase; +} + +.hero h1 { + margin: 18px 0 20px; + font-size: clamp(2.8rem, 6vw, 5rem); + line-height: 0.98; + letter-spacing: -0.06em; +} + +.hero h1 span { + display: block; + color: var(--ifm-color-primary); +} + +.heroContent > p { + max-width: 690px; + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 1.08rem; + line-height: 1.75; +} + +.heroActions { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: 30px; +} + +.primaryButton, +.secondaryButton, +.repositoryButton { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 9px; + min-height: 46px; + padding: 0 18px; + border-radius: 11px; + font-size: 0.85rem; + font-weight: 750; + text-decoration: none; + transition: + transform 180ms ease, + border-color 180ms ease, + box-shadow 180ms ease; +} + +.primaryButton { + color: #fff; + background: var(--ifm-color-primary); + box-shadow: 0 12px 30px + color-mix(in srgb, var(--ifm-color-primary) 20%, transparent); +} + +.primaryButton:hover { + color: #fff; + text-decoration: none; + transform: translateY(-2px); + box-shadow: 0 16px 36px + color-mix(in srgb, var(--ifm-color-primary) 28%, transparent); +} + +.secondaryButton { + color: var(--ifm-font-color-base); + border: 1px solid var(--ifm-color-emphasis-300); + background: var(--ifm-background-surface-color); +} + +.secondaryButton:hover { + color: var(--ifm-color-primary); + border-color: var(--ifm-color-primary); + text-decoration: none; + transform: translateY(-2px); +} + +/* ===================================================== + License Visual +===================================================== */ + +.licenseVisual { + position: relative; + display: flex; + min-height: 330px; + align-items: center; + justify-content: center; +} + +.visualGlow { + position: absolute; + width: 250px; + height: 250px; + border-radius: 50%; + background: color-mix( + in srgb, + var(--ifm-color-primary) 10%, + transparent + ); + filter: blur(50px); +} + +.licenseCard { + position: relative; + width: min(100%, 410px); + padding: 27px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 23px; + background: color-mix( + in srgb, + var(--ifm-background-surface-color) 94%, + transparent + ); + box-shadow: 0 30px 80px color-mix(in srgb, #000 12%, transparent); +} + +.licenseCardTop { + display: flex; + align-items: center; + justify-content: space-between; +} + +.licenseCardTop > span { + padding: 6px 9px; + color: var(--ifm-color-primary); + border-radius: 999px; + background: color-mix( + in srgb, + var(--ifm-color-primary) 9%, + transparent + ); + font-size: 0.67rem; + font-weight: 750; +} + +.licenseIcon { + display: grid; + width: 50px; + height: 50px; + place-items: center; + color: var(--ifm-color-primary); + border: 1px solid + color-mix(in srgb, var(--ifm-color-primary) 20%, transparent); + border-radius: 14px; + background: color-mix( + in srgb, + var(--ifm-color-primary) 8%, + transparent + ); +} + +.licenseName { + margin-top: 34px; + font-size: 4.3rem; + font-weight: 900; + line-height: 0.9; + letter-spacing: -0.08em; +} + +.licenseMeta { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px; + margin-top: 27px; +} + +.licenseMeta div { + padding: 13px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 11px; +} + +.licenseMeta span, +.licenseMeta strong { + display: block; +} + +.licenseMeta span { + color: var(--ifm-color-emphasis-600); + font-size: 0.65rem; +} + +.licenseMeta strong { + margin-top: 4px; + font-size: 0.76rem; +} + +.licenseCode { + display: flex; + align-items: center; + gap: 7px; + margin-top: 15px; + padding-top: 15px; + border-top: 1px solid var(--ifm-color-emphasis-200); + color: var(--ifm-color-emphasis-600); + font-family: var(--ifm-font-family-monospace); + font-size: 0.7rem; +} + +/* ===================================================== + Summary +===================================================== */ + +.summarySection { + padding: 24px 0; + border-bottom: 1px solid var(--ifm-color-emphasis-200); +} + +.summaryGrid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 12px; +} + +.summaryCard { + display: flex; + align-items: flex-start; + gap: 10px; + padding: 15px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 13px; + background: var(--ifm-background-surface-color); +} + +.summaryIcon { + display: grid; + width: 36px; + height: 36px; + flex: 0 0 36px; + place-items: center; + color: var(--ifm-color-primary); + border-radius: 9px; + background: color-mix( + in srgb, + var(--ifm-color-primary) 9%, + transparent + ); +} + +.summaryCard strong, +.summaryCard span { + display: block; +} + +.summaryCard strong { + font-size: 0.82rem; +} + +.summaryCard span { + margin-top: 3px; + color: var(--ifm-color-emphasis-600); + font-size: 0.69rem; + line-height: 1.45; +} + +/* ===================================================== + Content +===================================================== */ + +.contentSection { + padding: 78px 0 60px; +} + +.contentLayout { + display: grid; + grid-template-columns: 220px minmax(0, 800px); + justify-content: center; + gap: 55px; +} + +.sidebar { + position: relative; +} + +.sidebarCard { + position: sticky; + top: 90px; + display: flex; + flex-direction: column; + padding: 17px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 14px; + background: var(--ifm-background-surface-color); +} + +.sidebarTitle { + margin-bottom: 10px; + color: var(--ifm-color-emphasis-600); + font-size: 0.66rem; + font-weight: 800; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.sidebarCard a { + padding: 8px 9px; + color: var(--ifm-color-emphasis-700); + border-radius: 7px; + font-size: 0.77rem; + text-decoration: none; +} + +.sidebarCard a:hover { + color: var(--ifm-color-primary); + background: color-mix( + in srgb, + var(--ifm-color-primary) 6%, + transparent + ); +} + +/* ===================================================== + Article +===================================================== */ + +.article { + min-width: 0; +} + +.articleSection { + scroll-margin-top: 90px; + margin-bottom: 70px; +} + +.articleSection:last-child { + margin-bottom: 0; +} + +.sectionHeading { + display: flex; + align-items: center; + gap: 13px; + margin-bottom: 18px; +} + +.headingIcon { + display: grid; + width: 42px; + height: 42px; + flex: 0 0 42px; + place-items: center; + color: var(--ifm-color-primary); + border: 1px solid + color-mix(in srgb, var(--ifm-color-primary) 18%, transparent); + border-radius: 11px; + background: color-mix( + in srgb, + var(--ifm-color-primary) 7%, + transparent + ); +} + +.sectionHeading span { + display: block; + color: var(--ifm-color-primary); + font-size: 0.64rem; + font-weight: 800; + letter-spacing: 0.08em; +} + +.sectionHeading h2 { + margin: 3px 0 0; + font-size: 1.65rem; + letter-spacing: -0.03em; +} + +.articleSection > p { + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.94rem; + line-height: 1.8; +} + +/* ===================================================== + Info Box +===================================================== */ + +.infoBox { + display: flex; + gap: 12px; + margin-top: 23px; + padding: 17px; + border: 1px solid + color-mix(in srgb, var(--ifm-color-primary) 20%, transparent); + border-radius: 13px; + background: color-mix( + in srgb, + var(--ifm-color-primary) 5%, + transparent + ); +} + +.infoBox > svg { + flex: 0 0 auto; + margin-top: 2px; + color: var(--ifm-color-primary); +} + +.infoBox strong { + font-size: 0.82rem; +} + +.infoBox p { + margin: 4px 0 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.78rem; + line-height: 1.6; +} + +/* ===================================================== + Permissions +===================================================== */ + +.permissionGrid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 9px; + margin-top: 23px; +} + +.permissionItem { + display: flex; + align-items: center; + gap: 9px; + padding: 13px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 10px; + background: var(--ifm-background-surface-color); +} + +.permissionItem svg { + flex: 0 0 auto; + color: var(--ifm-color-primary); +} + +.permissionItem span { + color: var(--ifm-color-emphasis-800); + font-size: 0.78rem; +} + +/* ===================================================== + Conditions +===================================================== */ + +.conditionList { + display: flex; + flex-direction: column; + gap: 10px; + margin-top: 23px; +} + +.conditionItem { + display: flex; + align-items: flex-start; + gap: 14px; + padding: 15px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 11px; +} + +.conditionItem > span { + color: var(--ifm-color-primary); + font-family: var(--ifm-font-family-monospace); + font-size: 0.7rem; + font-weight: 800; +} + +.conditionItem p { + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.8rem; + line-height: 1.55; +} + +/* ===================================================== + Disclaimer +===================================================== */ + +.disclaimerBox { + margin-top: 23px; + padding: 19px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 14px; + background: var(--ifm-background-surface-color); +} + +.disclaimerHeader { + display: flex; + align-items: center; + gap: 9px; + color: var(--ifm-color-emphasis-900); + font-size: 0.83rem; +} + +.disclaimerHeader svg { + color: var(--ifm-color-primary); +} + +.disclaimerList { + display: flex; + flex-direction: column; + gap: 9px; + margin-top: 16px; + padding-top: 15px; + border-top: 1px solid var(--ifm-color-emphasis-200); +} + +.disclaimerList div { + display: flex; + align-items: flex-start; + gap: 9px; +} + +.disclaimerList div > span { + width: 5px; + height: 5px; + flex: 0 0 5px; + margin-top: 7px; + border-radius: 50%; + background: var(--ifm-color-primary); +} + +.disclaimerList p { + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.78rem; + line-height: 1.5; +} + +/* ===================================================== + Full License +===================================================== */ + +.licenseHeader { + display: flex; + align-items: center; + justify-content: space-between; + gap: 15px; + margin-top: 23px; + padding: 14px 15px; + border: 1px solid var(--ifm-color-emphasis-200); + border-bottom: 0; + border-radius: 13px 13px 0 0; + background: color-mix( + in srgb, + var(--ifm-color-emphasis-100) 50%, + transparent + ); +} + +.licenseHeader strong, +.licenseHeader span { + display: block; +} + +.licenseHeader strong { + font-size: 0.82rem; +} + +.licenseHeader span { + margin-top: 3px; + color: var(--ifm-color-emphasis-600); + font-size: 0.68rem; +} + +.copyButton { + display: inline-flex; + align-items: center; + gap: 6px; + min-height: 34px; + padding: 0 10px; + color: var(--ifm-color-emphasis-700); + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 8px; + background: var(--ifm-background-surface-color); + font-size: 0.7rem; + font-weight: 700; + cursor: pointer; +} + +.copyButton:hover { + color: var(--ifm-color-primary); + border-color: var(--ifm-color-primary); +} + +.licenseText { + overflow-x: auto; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 0 0 13px 13px; + background: var(--ifm-color-emphasis-100); +} + +.licenseText pre { + min-width: 680px; + margin: 0; + padding: 23px; + background: transparent; +} + +.licenseText code { + color: var(--ifm-color-emphasis-800); + font-family: var(--ifm-font-family-monospace); + font-size: 0.73rem; + line-height: 1.75; +} + +/* ===================================================== + Repository CTA +===================================================== */ + +.repositorySection { + padding: 30px 0 75px; +} + +.repositoryCard { + display: flex; + align-items: center; + gap: 17px; + padding: 24px; + border: 1px solid + color-mix(in srgb, var(--ifm-color-primary) 18%, transparent); + border-radius: 19px; + background: + linear-gradient( + 135deg, + color-mix(in srgb, var(--ifm-color-primary) 6%, transparent), + transparent + ), + var(--ifm-background-surface-color); +} + +.repositoryIcon { + display: grid; + width: 46px; + height: 46px; + flex: 0 0 46px; + place-items: center; + color: var(--ifm-color-primary); + border-radius: 12px; + background: color-mix( + in srgb, + var(--ifm-color-primary) 10%, + transparent + ); +} + +.repositoryContent { + flex: 1; +} + +.repositoryContent > span { + color: var(--ifm-color-primary); + font-size: 0.68rem; + font-weight: 800; + letter-spacing: 0.06em; + text-transform: uppercase; +} + +.repositoryContent h2 { + margin: 4px 0 4px; + font-size: 1.15rem; +} + +.repositoryContent p { + max-width: 700px; + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.78rem; + line-height: 1.55; +} + +.repositoryButton { + flex: 0 0 auto; + color: #fff; + background: var(--ifm-color-primary); +} + +.repositoryButton:hover { + color: #fff; + text-decoration: none; + transform: translateY(-2px); +} + +/* ===================================================== + Related +===================================================== */ + +.relatedSection { + padding: 0 0 75px; +} + +.relatedHeader { + margin-bottom: 20px; +} + +.relatedHeader > span { + color: var(--ifm-color-primary); + font-size: 0.68rem; + font-weight: 800; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.relatedHeader h2 { + margin: 6px 0 0; + font-size: 1.65rem; + letter-spacing: -0.03em; +} + +.relatedGrid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 12px; +} + +.relatedCard { + display: flex; + align-items: center; + gap: 11px; + padding: 17px; + color: inherit; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 13px; + background: var(--ifm-background-surface-color); + text-decoration: none; + transition: + transform 180ms ease, + border-color 180ms ease; +} + +.relatedCard:hover { + color: inherit; + border-color: var(--ifm-color-primary); + text-decoration: none; + transform: translateY(-2px); +} + +.relatedCard > svg:first-child { + flex: 0 0 auto; + color: var(--ifm-color-primary); +} + +.relatedCard div { + flex: 1; + min-width: 0; +} + +.relatedCard h3 { + margin: 0; + font-size: 0.82rem; +} + +.relatedCard p { + margin: 3px 0 0; + color: var(--ifm-color-emphasis-600); + font-size: 0.69rem; + line-height: 1.45; +} + +.relatedCard > svg:last-child { + color: var(--ifm-color-emphasis-500); +} + +/* ===================================================== + Final CTA +===================================================== */ + +.finalSection { + padding: 0 0 90px; +} + +.finalCard { + padding: 58px 25px; + text-align: center; + border: 1px solid + color-mix(in srgb, var(--ifm-color-primary) 20%, transparent); + border-radius: 24px; + background: + radial-gradient( + circle at 50% 0, + color-mix(in srgb, var(--ifm-color-primary) 13%, transparent), + transparent 55% + ), + var(--ifm-background-surface-color); +} + +.finalBadge { + display: inline-flex; + align-items: center; + gap: 7px; + padding: 7px 10px; + color: var(--ifm-color-primary); + border-radius: 999px; + background: color-mix( + in srgb, + var(--ifm-color-primary) 8%, + transparent + ); + font-size: 0.68rem; + font-weight: 800; +} + +.finalCard h2 { + max-width: 750px; + margin: 14px auto 9px; + font-size: clamp(2rem, 4vw, 3rem); + letter-spacing: -0.045em; +} + +.finalCard > p { + max-width: 630px; + margin: 0 auto; + color: var(--ifm-color-emphasis-700); + font-size: 0.88rem; + line-height: 1.65; +} + +.finalActions { + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 11px; + margin-top: 27px; +} + +/* ===================================================== + Responsive +===================================================== */ + +@media (max-width: 1050px) { + .heroGrid { + grid-template-columns: 1fr; + } + + .licenseVisual { + justify-content: flex-start; + } + + .summaryGrid { + grid-template-columns: repeat(2, 1fr); + } + + .contentLayout { + grid-template-columns: 190px minmax(0, 1fr); + gap: 35px; + } +} + +@media (max-width: 800px) { + .hero { + padding: 52px 0 58px; + } + + .hero h1 { + font-size: clamp(2.5rem, 11vw, 4rem); + } + + .heroActions { + flex-direction: column; + } + + .primaryButton, + .secondaryButton { + width: 100%; + } + + .contentLayout { + display: block; + } + + .sidebar { + display: none; + } + + .permissionGrid { + grid-template-columns: 1fr; + } + + .relatedGrid { + grid-template-columns: 1fr; + } + + .repositoryCard { + align-items: flex-start; + flex-wrap: wrap; + } + + .repositoryContent { + min-width: calc(100% - 65px); + } + + .repositoryButton { + width: 100%; + margin-top: 3px; + } +} + +@media (max-width: 560px) { + .breadcrumb { + padding-top: 13px; + } + + .summaryGrid { + grid-template-columns: 1fr; + } + + .licenseCard { + padding: 22px; + } + + .licenseName { + font-size: 3.5rem; + } + + .licenseMeta { + grid-template-columns: 1fr; + } + + .contentSection { + padding-top: 55px; + } + + .articleSection { + margin-bottom: 55px; + } + + .sectionHeading h2 { + font-size: 1.4rem; + } + + .licenseHeader { + align-items: flex-start; + } + + .finalCard { + padding: 43px 18px; + border-radius: 18px; + } + + .finalActions { + flex-direction: column; + } + + .finalActions .primaryButton, + .finalActions .secondaryButton { + width: 100%; + } +} + +/* ===================================================== + Reduced Motion +===================================================== */ + +@media (prefers-reduced-motion: reduce) { + .primaryButton, + .secondaryButton, + .repositoryButton, + .relatedCard { + transition: none; + } +} \ No newline at end of file diff --git a/src/pages/about/index.tsx b/src/pages/about/index.tsx index 3c099a531..c4ced6598 100644 --- a/src/pages/about/index.tsx +++ b/src/pages/about/index.tsx @@ -1,15 +1,165 @@ -import Layout from "@theme/Layout"; -import AboutUsSection from "../../components/Aboutpage"; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import React from "react"; +// @ts-ignore +import Layout from "@theme/Layout"; +// @ts-ignore +import Link from "@docusaurus/Link"; +// @ts-ignore import Head from "@docusaurus/Head"; -export default function About(): React.JSX.Element { - const { siteConfig } = useDocusaurusContext(); +import { + ArrowRight, + ArrowUpRight, + BookOpen, + BrainCircuit, + CheckCircle2, + Code2, + Compass, + GitBranch, + Github, + Globe2, + Heart, + Layers3, + Lightbulb, + Rocket, + Sparkles, + Target, + Trophy, + Users, + Zap, +} from "lucide-react"; + +// @ts-ignore +import styles from "./styles.module.css"; + +const VALUES = [ + { + icon: , + title: "Learning first", + description: + "We focus on clear explanations, practical examples and learning paths that help people move from fundamentals to real skills.", + }, + { + icon: , + title: "Build by doing", + description: + "Tutorials are only the beginning. Practice, projects, challenges and experimentation turn knowledge into capability.", + }, + { + icon: , + title: "Open source", + description: + "CodeHarborHub is built in the open. Developers can contribute code, documentation, ideas, fixes and educational content.", + }, + { + icon: , + title: "Community driven", + description: + "We believe learners and developers become stronger when they learn, build and share knowledge together.", + }, + { + icon: , + title: "Always improving", + description: + "Technology changes quickly. Our content, tools and learning experiences should continuously evolve with it.", + }, + { + icon: , + title: "For everyone", + description: + "Our goal is to make quality technology education accessible to learners regardless of their starting point.", + }, +]; + +const LEARNING_PILLARS = [ + { + number: "01", + icon: , + title: "Learn", + description: + "Understand concepts through structured tutorials, documentation and learning resources.", + href: "/tutorials/", + }, + { + number: "02", + icon: , + title: "Practice", + description: + "Strengthen your knowledge with coding problems, DSA, quizzes and challenges.", + href: "/practice/", + }, + { + number: "03", + icon: , + title: "Build", + description: + "Apply what you learn by creating real-world projects and practical applications.", + href: "/projects/", + }, + { + number: "04", + icon: , + title: "Contribute", + description: + "Improve the ecosystem by contributing code, documentation, ideas and community knowledge.", + href: "/contributors/", + }, +]; + +const AREAS = [ + { + icon: , + title: "Programming", + items: ["HTML", "CSS", "JavaScript", "TypeScript", "Python"], + }, + { + icon: , + title: "Development", + items: ["React", "Node.js", "Backend", "Full Stack", "APIs"], + }, + { + icon: , + title: "Computer Science", + items: ["DSA", "Algorithms", "Databases", "Operating Systems", "Networks"], + }, + { + icon: , + title: "Emerging Tech", + items: ["AI", "Machine Learning", "Cloud", "Cybersecurity", "DevTools"], + }, +]; + +const MILESTONES = [ + { + label: "The idea", + title: "Learning should be accessible.", + description: + "CodeHarborHub started with a simple idea: create a place where anyone can learn technology without feeling lost or limited by expensive resources.", + }, + { + label: "The community", + title: "Build in the open.", + description: + "The project evolved into an open-source ecosystem where developers and learners can contribute, collaborate and improve the platform together.", + }, + { + label: "The platform", + title: "Learning beyond tutorials.", + description: + "The vision expanded from documentation into roadmaps, practice, projects, developer tools, community experiences and career-focused learning.", + }, + { + label: "The future", + title: "A complete developer learning ecosystem.", + description: + "The long-term goal is to connect learning, practice, building, open source and career development in one accessible platform.", + }, +]; + +export default function AboutPage(): React.JSX.Element { return ( + + +
+ {/* ============================================================ + HERO + ============================================================ */} + +
+
+
+ +
+
+ CodeHarborHub + / + Our Team +
+ +
+
+ + THE PEOPLE BEHIND THE PLATFORM +
+ +

+ Built by people who + love technology. +

+ +

+ Meet the builders, contributors and community members helping + shape CodeHarborHub into an open, practical and accessible + learning platform for developers everywhere. +

+ +
+ + Meet Our Contributors + + + + + Contribute to CodeHarborHub + + +
+ +
+ + + Open source + + + + + Community driven + + + + + Built in public + +
+
+ +
+
+ {teamCount || "Open"} + Core team members +
+ +
+ Open + Contribution model +
+ +
+ Global + Community mindset +
+
- {/* --- Leadership / Bento Grid --- */} -
-
- {coreTeam.map((member, i) => ( -
-
- - {/* Avatar & Status */} -
- {member.name} -
-
+ {/* ============================================================ + TEAM + ============================================================ */} - {/* Content */} -

- {member.name} -

-

- {member.role} -

-

- {member.bio} -

- - {/* Skill Tags */} -
- {member.skills.map((skill, si) => ( - - {skill} - - ))} -
+
+
+
+
+ + CORE TEAM + - {/* Social Footer */} - +

Small team. Big mission.

+ +

+ CodeHarborHub is built by people who care about practical + learning, developer experience and open-source collaboration. +

+
+ +
+ + {teamCount} core contributor{teamCount === 1 ? "" : "s"} +
+
+ + {teamMembers.length > 0 ? ( +
+ {teamMembers.map((member) => ( + + ))} +
+ ) : ( +
+
+
+ +

Our contributor network is growing.

+ +

+ CodeHarborHub is an open-source project. Meet the wider + contributor community and help us build the next generation + of developer education. +

+ + + Explore Contributors + +
- ))} + )}
- {/* --- Values / Organization DNA --- */} -
-
-
-
-

Our Core Principles

-
- {[ - { title: "Radical Transparency", desc: "Every decision, from code to strategy, happens in the open.", icon: }, - { title: "Global Inclusion", desc: "Empowering developers from underserved regions with high-tier tech.", icon: }, - { title: "Obsessive Quality", desc: "We don't ship 'good enough'. We ship industry-defining standards.", icon: } - ].map((val, i) => ( -
-
{val.icon}
-
-

{val.title}

-

{val.desc}

-
-
- ))} + {/* ============================================================ + FOCUS AREAS + ============================================================ */} + +
+
+
+ + WHAT WE BUILD + + +

Different skills. One direction.

+ +

+ Our work connects education, software engineering and community + to create a complete developer learning experience. +

+
+ +
+ {focusAreas.map((item) => ( + + ))} +
+
+
+ + {/* ============================================================ + PRINCIPLES + ============================================================ */} + +
+
+ +
+
+
+ + OUR CULTURE + + +

+ Principles that guide + how we build. +

+ +

+ CodeHarborHub is more than a collection of tutorials. We are + building an ecosystem where developers can learn openly, + practice consistently and contribute meaningfully. +

+ +
+
+ +
+ +
+ Our north star +

+ Make high-quality technical learning more accessible, + practical and community-driven. +

+
-
-
-
-
- + +
+ {principles.map((principle) => ( +
+
+ {principle.icon}
-
+ +

{principle.title}

+ +

{principle.description}

+ + ))}
- {/* --- Join Us CTA --- */} -
-
-

Want to make an impact?

-

- We're always looking for passionate maintainers, content creators, and community leads. -

-
- - Contact Us - - - Browse Open Roles - + {/* ============================================================ + OPEN SOURCE CTA + ============================================================ */} + +
+
+
+
+ +
+ +
+ +
+ + OPEN SOURCE COMMUNITY + + +

+ You don't have to be + on the team to contribute. +

+ +

+ CodeHarborHub grows through developers, writers, designers, + educators and open-source contributors who share knowledge + and improve the platform. +

+
+ +
+ + Start Contributing + + + + + Explore GitHub + + +
+ {/* ============================================================ + CONTACT CTA + ============================================================ */} + +
+
+
+
+ + HAVE AN IDEA? + + +

Let's build something useful.

+ +

+ Whether you want to contribute, collaborate, improve the + learning experience or simply share an idea, we'd love to + hear from you. +

+
+ +
+ + Contact the Team + + + + + Join the Community + + +
+
+
+
); diff --git a/src/pages/about/teams.module.css b/src/pages/about/teams.module.css new file mode 100644 index 000000000..ea0c48837 --- /dev/null +++ b/src/pages/about/teams.module.css @@ -0,0 +1,1133 @@ +.page { + min-height: 100vh; + overflow: hidden; + background: var(--ifm-background-color); + color: var(--ifm-font-color-base); +} + +.container { + margin: 0 1rem; +} + +/* ================================================================ + HERO +================================================================ */ + +.hero { + position: relative; + isolation: isolate; + overflow: hidden; + padding: 1rem 0; + border-bottom: 1px solid var(--ifm-color-emphasis-200); + background: + radial-gradient( + circle at 12% 20%, + color-mix(in srgb, var(--ifm-color-primary) 12%, transparent), + transparent 31% + ), + radial-gradient( + circle at 88% 25%, + color-mix(in srgb, #8b5cf6 9%, transparent), + transparent 30% + ), + var(--ifm-background-color); +} + +.heroGrid { + position: absolute; + inset: 0; + z-index: -2; + pointer-events: none; + background-image: + linear-gradient( + to right, + color-mix(in srgb, var(--ifm-color-emphasis-300) 18%, transparent) 1px, + transparent 1px + ), + linear-gradient( + to bottom, + color-mix(in srgb, var(--ifm-color-emphasis-300) 18%, transparent) 1px, + transparent 1px + ); + + background-size: 52px 52px; + + mask-image: linear-gradient( + to bottom, + black 0%, + transparent 82% + ); +} + +.heroGlow { + position: absolute; + top: -320px; + left: 50%; + width: 650px; + height: 650px; + z-index: -1; + transform: translateX(-50%); + border-radius: 50%; + pointer-events: none; + + background: color-mix( + in srgb, + var(--ifm-color-primary) 9%, + transparent + ); + + filter: blur(110px); +} + +.breadcrumb { + display: flex; + align-items: center; + gap: 9px; + margin-bottom: 75px; + color: var(--ifm-color-emphasis-600); + font-size: 0.72rem; +} + +.breadcrumb a { + color: var(--ifm-color-emphasis-700); + font-weight: 650; + text-decoration: none; +} + +.breadcrumb a:hover { + color: var(--ifm-color-primary); +} + +.breadcrumb span:nth-child(2) { + opacity: 0.45; +} + +.heroContent { + margin: 0 auto; + text-align: center; +} + +.eyebrow, +.sectionEyebrow { + display: inline-flex; + align-items: center; + gap: 7px; + color: var(--ifm-color-primary); + font-size: 0.7rem; + font-weight: 850; + letter-spacing: 0.13em; + text-transform: uppercase; +} + +.eyebrow { + padding: 8px 11px; + border: 1px solid + color-mix(in srgb, var(--ifm-color-primary) 24%, transparent); + border-radius: 999px; + background: color-mix( + in srgb, + var(--ifm-color-primary) 6%, + transparent + ); +} + +.hero h1 { + margin: 1.2rem 0; + font-size: clamp(2.5rem, 6vw, 5rem); + line-height: 0.97; + letter-spacing: -0.065em; + font-weight: 900; +} + +.hero h1 span { + display: block; + color: var(--ifm-color-primary); +} + +.heroContent > p { + max-width: 720px; + margin: 0 auto; + color: var(--ifm-color-emphasis-700); + font-size: 1.08rem; + line-height: 1.75; +} + +.heroActions { + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 11px; + margin-top: 30px; +} + +.primaryButton, +.secondaryButton, +.outlineButton, +.textButton { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; + min-height: 45px; + padding: 0 17px; + border-radius: 10px; + font-size: 0.82rem; + font-weight: 750; + text-decoration: none; + transition: + transform 180ms ease, + border-color 180ms ease, + box-shadow 180ms ease, + background 180ms ease; +} + +.primaryButton { + color: #fff; + background: var(--ifm-color-primary); + border: 1px solid var(--ifm-color-primary); + box-shadow: + 0 12px 28px + color-mix(in srgb, var(--ifm-color-primary) 20%, transparent); +} + +.primaryButton:hover { + color: #fff; + text-decoration: none; + transform: translateY(-2px); + box-shadow: + 0 17px 36px + color-mix(in srgb, var(--ifm-color-primary) 27%, transparent); +} + +.secondaryButton, +.outlineButton { + color: var(--ifm-font-color-base); + border: 1px solid var(--ifm-color-emphasis-300); + background: var(--ifm-background-surface-color); +} + +.secondaryButton:hover, +.outlineButton:hover { + color: var(--ifm-color-primary); + text-decoration: none; + border-color: var(--ifm-color-primary); + transform: translateY(-2px); +} + +.heroMeta { + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 18px; + margin-top: 25px; + color: var(--ifm-color-emphasis-600); + font-size: 0.7rem; +} + +.heroMeta span { + display: inline-flex; + align-items: center; + gap: 6px; +} + +.metaDot { + width: 6px; + height: 6px; + border-radius: 50%; + background: var(--ifm-color-primary); +} + +.heroStats { + display: grid; + grid-template-columns: repeat(3, 1fr); + max-width: 750px; + margin: 70px auto 0; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 14px; + background: color-mix( + in srgb, + var(--ifm-background-surface-color) 88%, + transparent + ); + backdrop-filter: blur(12px); +} + +.heroStats div { + padding: 19px 15px; + text-align: center; + border-right: 1px solid var(--ifm-color-emphasis-200); +} + +.heroStats div:last-child { + border-right: 0; +} + +.heroStats strong, +.heroStats span { + display: block; +} + +.heroStats strong { + font-size: 1.1rem; +} + +.heroStats span { + margin-top: 4px; + color: var(--ifm-color-emphasis-600); + font-size: 0.67rem; +} + +/* ================================================================ + TEAM +================================================================ */ + +.teamSection { + padding: 100px 0; +} + +.sectionHeader { + display: flex; + align-items: flex-end; + justify-content: space-between; + gap: 30px; + margin-bottom: 38px; +} + +.sectionHeader h2, +.sectionHeaderCentered h2 { + margin: 9px 0 9px; + font-size: clamp(2rem, 4vw, 3rem); + line-height: 1.05; + letter-spacing: -0.045em; +} + +.sectionHeader p, +.sectionHeaderCentered p { + max-width: 620px; + margin: 0; + color: var(--ifm-color-emphasis-700); + line-height: 1.65; + font-size: 0.87rem; +} + +.teamHeaderBadge { + display: inline-flex; + align-items: center; + gap: 7px; + flex-shrink: 0; + padding: 8px 11px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 999px; + color: var(--ifm-color-emphasis-700); + background: var(--ifm-background-surface-color); + font-size: 0.68rem; + font-weight: 700; +} + +.teamHeaderBadge svg { + color: var(--ifm-color-primary); +} + +.teamGrid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 18px; +} + +.memberCard { + position: relative; + overflow: hidden; + display: flex; + flex-direction: column; + min-height: 100%; + padding: 25px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 18px; + background: var(--ifm-background-surface-color); + transition: + transform 200ms ease, + border-color 200ms ease, + box-shadow 200ms ease; +} + +.memberCard:hover { + transform: translateY(-5px); + border-color: color-mix( + in srgb, + var(--ifm-color-primary) 45%, + var(--ifm-color-emphasis-200) + ); + box-shadow: + 0 20px 45px + color-mix(in srgb, var(--ifm-color-primary) 9%, transparent); +} + +.memberCardFeatured { + border-color: color-mix( + in srgb, + var(--ifm-color-primary) 30%, + var(--ifm-color-emphasis-200) + ); +} + +.memberVisual { + position: relative; + width: 90px; + height: 90px; + margin-bottom: 21px; +} + +.avatarFrame { + width: 100%; + height: 100%; + overflow: hidden; + border-radius: 22px; + border: 1px solid var(--ifm-color-emphasis-200); + background: var(--ifm-background-color); +} + +.avatarFrame img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; + filter: saturate(0.85); + transition: + transform 300ms ease, + filter 300ms ease; +} + +.memberCard:hover .avatarFrame img { + transform: scale(1.06); + filter: saturate(1); +} + +.availability { + position: absolute; + right: -3px; + bottom: -3px; + width: 17px; + height: 17px; + border: 4px solid var(--ifm-background-surface-color); + border-radius: 50%; + background: #22c55e; +} + +.memberContent { + display: flex; + flex-direction: column; + flex: 1; +} + +.memberHeading { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 10px; +} + +.memberHeading h3 { + margin: 0; + font-size: 1.28rem; + letter-spacing: -0.025em; +} + +.memberHeading p { + margin: 5px 0 0; + color: var(--ifm-color-primary); + font-size: 0.68rem; + font-weight: 800; + letter-spacing: 0.07em; + text-transform: uppercase; +} + +.featuredBadge { + display: inline-flex; + align-items: center; + gap: 4px; + flex-shrink: 0; + padding: 5px 7px; + border-radius: 6px; + color: var(--ifm-color-primary); + background: color-mix( + in srgb, + var(--ifm-color-primary) 8%, + transparent + ); + font-size: 0.59rem; + font-weight: 800; +} + +.memberBio { + margin: 17px 0 18px; + color: var(--ifm-color-emphasis-700); + font-size: 0.8rem; + line-height: 1.65; +} + +.contribution { + padding: 11px 12px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 9px; + background: color-mix( + in srgb, + var(--ifm-background-color) 60%, + transparent + ); +} + +.contribution span, +.contribution strong { + display: block; +} + +.contribution span { + margin-bottom: 3px; + color: var(--ifm-color-emphasis-500); + font-size: 0.59rem; + font-weight: 750; + text-transform: uppercase; + letter-spacing: 0.08em; +} + +.contribution strong { + font-size: 0.71rem; +} + +.location { + display: flex; + align-items: center; + gap: 6px; + margin-top: 12px; + color: var(--ifm-color-emphasis-600); + font-size: 0.68rem; +} + +.location svg { + color: var(--ifm-color-primary); +} + +.skills { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-top: 17px; +} + +.skills span { + padding: 5px 7px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 6px; + color: var(--ifm-color-emphasis-700); + font-size: 0.62rem; + font-weight: 650; +} + +.memberFooter { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + margin-top: auto; + padding-top: 19px; +} + +.socials { + display: flex; + gap: 5px; +} + +.socialLink { + display: grid; + place-items: center; + width: 32px; + height: 32px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 8px; + color: var(--ifm-color-emphasis-600); + transition: + color 160ms ease, + border-color 160ms ease, + background 160ms ease; +} + +.socialLink:hover { + color: var(--ifm-color-primary); + border-color: var(--ifm-color-primary); + background: color-mix( + in srgb, + var(--ifm-color-primary) 7%, + transparent + ); +} + +.cardArrow { + color: var(--ifm-color-emphasis-400); + transition: + transform 180ms ease, + color 180ms ease; +} + +.memberCard:hover .cardArrow { + color: var(--ifm-color-primary); + transform: translate(2px, -2px); +} + +/* ================================================================ + EMPTY TEAM STATE +================================================================ */ + +.teamEmpty { + max-width: 720px; + margin: 0 auto; + padding: 55px 30px; + text-align: center; + border: 1px dashed var(--ifm-color-emphasis-300); + border-radius: 18px; + background: var(--ifm-background-surface-color); +} + +.emptyIcon { + display: grid; + place-items: center; + width: 52px; + height: 52px; + margin: 0 auto 17px; + border-radius: 14px; + color: var(--ifm-color-primary); + background: color-mix( + in srgb, + var(--ifm-color-primary) 8%, + transparent + ); +} + +.teamEmpty h3 { + margin: 0 0 9px; + font-size: 1.25rem; +} + +.teamEmpty p { + max-width: 570px; + margin: 0 auto 23px; + color: var(--ifm-color-emphasis-700); + font-size: 0.82rem; + line-height: 1.65; +} + +/* ================================================================ + FOCUS +================================================================ */ + +.focusSection { + padding: 100px 0; + border-top: 1px solid var(--ifm-color-emphasis-200); + border-bottom: 1px solid var(--ifm-color-emphasis-200); + background: + linear-gradient( + 180deg, + color-mix(in srgb, var(--ifm-color-emphasis-100) 32%, transparent), + transparent + ); +} + +.sectionHeaderCentered { + max-width: 700px; + margin: 0 auto 42px; + text-align: center; +} + +.sectionHeaderCentered p { + margin: 0 auto; +} + +.focusGrid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 14px; +} + +.focusCard { + display: flex; + gap: 14px; + padding: 22px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 14px; + background: var(--ifm-background-surface-color); + transition: + transform 180ms ease, + border-color 180ms ease; +} + +.focusCard:hover { + transform: translateY(-3px); + border-color: var(--ifm-color-primary); +} + +.focusIcon { + display: grid; + place-items: center; + width: 42px; + height: 42px; + flex: 0 0 42px; + border-radius: 10px; + color: var(--ifm-color-primary); + background: color-mix( + in srgb, + var(--ifm-color-primary) 8%, + transparent + ); +} + +.focusCard h3 { + margin: 1px 0 6px; + font-size: 0.92rem; +} + +.focusCard p { + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.72rem; + line-height: 1.55; +} + +/* ================================================================ + PRINCIPLES +================================================================ */ + +.principlesSection { + position: relative; + isolation: isolate; + overflow: hidden; + padding: 110px 0; + background: #020617; + color: #fff; +} + +.principlesBackground { + position: absolute; + inset: 0; + z-index: -1; + opacity: 0.25; + + background-image: + linear-gradient( + to right, + rgba(255, 255, 255, 0.06) 1px, + transparent 1px + ), + linear-gradient( + to bottom, + rgba(255, 255, 255, 0.06) 1px, + transparent 1px + ); + + background-size: 48px 48px; +} + +.principlesLayout { + display: grid; + grid-template-columns: 0.85fr 1.15fr; + gap: 75px; + align-items: center; +} + +.principlesIntro h2 { + max-width: 500px; + margin: 10px 0 17px; + font-size: clamp(2.2rem, 4vw, 3.4rem); + line-height: 1.03; + letter-spacing: -0.05em; +} + +.principlesIntro h2 span { + display: block; + color: #60a5fa; +} + +.principlesIntro > p { + max-width: 510px; + margin: 0; + color: #94a3b8; + line-height: 1.7; + font-size: 0.88rem; +} + +.principleQuote { + display: flex; + gap: 12px; + margin-top: 30px; + padding: 16px; + border: 1px solid rgba(148, 163, 184, 0.15); + border-radius: 12px; + background: rgba(255, 255, 255, 0.035); +} + +.quoteIcon { + display: grid; + place-items: center; + width: 38px; + height: 38px; + flex: 0 0 38px; + border-radius: 9px; + color: #60a5fa; + background: rgba(59, 130, 246, 0.1); +} + +.principleQuote strong { + font-size: 0.76rem; +} + +.principleQuote p { + margin: 4px 0 0; + color: #94a3b8; + font-size: 0.7rem; + line-height: 1.5; +} + +.principlesGrid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 13px; +} + +.principleCard { + padding: 24px; + border: 1px solid rgba(148, 163, 184, 0.13); + border-radius: 14px; + background: rgba(255, 255, 255, 0.035); + transition: + transform 180ms ease, + background 180ms ease, + border-color 180ms ease; +} + +.principleCard:hover { + transform: translateY(-3px); + border-color: rgba(96, 165, 250, 0.3); + background: rgba(255, 255, 255, 0.055); +} + +.principleIcon { + display: grid; + place-items: center; + width: 43px; + height: 43px; + margin-bottom: 18px; + border-radius: 10px; + color: #60a5fa; + background: rgba(59, 130, 246, 0.1); +} + +.principleCard h3 { + margin: 0 0 7px; + font-size: 0.95rem; +} + +.principleCard p { + margin: 0; + color: #94a3b8; + font-size: 0.72rem; + line-height: 1.6; +} + +/* ================================================================ + JOIN +================================================================ */ + +.joinSection { + padding: 100px 0 50px; +} + +.joinCard { + position: relative; + isolation: isolate; + overflow: hidden; + display: grid; + grid-template-columns: auto 1fr auto; + align-items: center; + gap: 25px; + padding: 34px; + border: 1px solid + color-mix(in srgb, var(--ifm-color-primary) 25%, var(--ifm-color-emphasis-200)); + border-radius: 19px; + background: + radial-gradient( + circle at 100% 0, + color-mix(in srgb, var(--ifm-color-primary) 9%, transparent), + transparent 36% + ), + var(--ifm-background-surface-color); +} + +.joinGlow { + position: absolute; + right: -100px; + bottom: -160px; + width: 330px; + height: 330px; + z-index: -1; + border-radius: 50%; + background: color-mix( + in srgb, + var(--ifm-color-primary) 10%, + transparent + ); + filter: blur(70px); +} + +.joinIcon { + display: grid; + place-items: center; + width: 58px; + height: 58px; + border-radius: 14px; + color: var(--ifm-color-primary); + background: color-mix( + in srgb, + var(--ifm-color-primary) 9%, + transparent + ); +} + +.joinContent h2 { + max-width: 680px; + margin: 9px 0 8px; + font-size: 1.55rem; + letter-spacing: -0.035em; +} + +.joinContent h2 span { + color: var(--ifm-color-primary); +} + +.joinContent p { + max-width: 680px; + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.78rem; + line-height: 1.6; +} + +.joinActions { + display: flex; + flex-direction: column; + gap: 9px; +} + +/* ================================================================ + CONTACT +================================================================ */ + +.contactSection { + padding: 50px 0 110px; +} + +.contactCard { + display: flex; + align-items: center; + justify-content: space-between; + gap: 40px; + padding: 35px 0; + border-top: 1px solid var(--ifm-color-emphasis-200); +} + +.contactCard h2 { + margin: 9px 0 8px; + font-size: 1.7rem; + letter-spacing: -0.035em; +} + +.contactCard p { + max-width: 680px; + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.8rem; + line-height: 1.65; +} + +.contactActions { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 8px; + flex-shrink: 0; +} + +.textButton { + color: var(--ifm-color-primary); + border: 0; + background: transparent; +} + +.textButton:hover { + color: var(--ifm-color-primary); + text-decoration: none; +} + +/* ================================================================ + RESPONSIVE +================================================================ */ + +@media (max-width: 1050px) { + .teamGrid { + grid-template-columns: repeat(2, 1fr); + } + + .focusGrid { + grid-template-columns: repeat(2, 1fr); + } + + .principlesLayout { + grid-template-columns: 1fr; + gap: 45px; + } +} + +@media (max-width: 850px) { + .hero { + padding-bottom: 65px; + } + + .breadcrumb { + margin-bottom: 55px; + } + + .sectionHeader { + align-items: flex-start; + flex-direction: column; + } + + .joinCard { + grid-template-columns: auto 1fr; + } + + .joinActions { + grid-column: 1 / -1; + flex-direction: row; + } + + .contactCard { + flex-direction: column; + align-items: flex-start; + } +} + +@media (max-width: 640px) { + .container { + width: min(100% - 28px, 1180px); + } + + .hero { + padding-top: 25px; + } + + .breadcrumb { + margin-bottom: 50px; + } + + .hero h1 { + font-size: clamp(2.7rem, 13vw, 4rem); + } + + .heroContent > p { + font-size: 0.92rem; + } + + .heroActions { + flex-direction: column; + } + + .heroActions a { + width: 100%; + } + + .heroMeta { + flex-direction: column; + align-items: center; + gap: 8px; + } + + .heroStats { + grid-template-columns: 1fr; + } + + .heroStats div { + border-right: 0; + border-bottom: 1px solid var(--ifm-color-emphasis-200); + } + + .heroStats div:last-child { + border-bottom: 0; + } + + .teamSection, + .focusSection, + .principlesSection { + padding: 75px 0; + } + + .teamGrid, + .focusGrid, + .principlesGrid { + grid-template-columns: 1fr; + } + + .memberCard { + padding: 21px; + } + + .principlesIntro h2 { + font-size: 2.4rem; + } + + .joinSection { + padding-top: 75px; + } + + .joinCard { + grid-template-columns: 1fr; + padding: 25px; + } + + .joinActions { + grid-column: auto; + flex-direction: column; + } + + .joinActions a { + width: 100%; + } + + .contactSection { + padding-bottom: 75px; + } + + .contactActions { + width: 100%; + flex-direction: column; + align-items: stretch; + } + + .contactActions a { + width: 100%; + } +} + +/* ================================================================ + ACCESSIBILITY +================================================================ */ + +@media (prefers-reduced-motion: reduce) { + .primaryButton, + .secondaryButton, + .outlineButton, + .memberCard, + .avatarFrame img, + .socialLink, + .cardArrow, + .focusCard, + .principleCard { + transition: none; + } +} \ No newline at end of file diff --git a/src/pages/blogs/index.tsx b/src/pages/blogs/index.tsx new file mode 100644 index 000000000..429057833 --- /dev/null +++ b/src/pages/blogs/index.tsx @@ -0,0 +1,955 @@ +import React, { useMemo, useState } from "react"; +import Layout from "@theme/Layout"; +import Link from "@docusaurus/Link"; +import { + ArrowRight, + ArrowUpRight, + BookOpen, + CalendarDays, + Check, + ChevronDown, + Clock3, + Code2, + ExternalLink, + Filter, + Github, + Hash, + Layers3, + Mail, + Search, + Sparkles, + TrendingUp, + Users, + X, +} from "lucide-react"; + +import styles from "./styles.module.css"; + +type BlogCategory = + | "All" + | "Web Development" + | "JavaScript" + | "React" + | "AI & ML" + | "DevOps" + | "Career" + | "Open Source"; + +type BlogArticle = { + id: string; + title: string; + description: string; + slug: string; + category: Exclude; + tags: string[]; + author: string; + authorRole: string; + authorAvatar: string; + date: string; + isoDate: string; + readTime: number; + image: string; + featured?: boolean; + popular?: boolean; +}; + +const categories: BlogCategory[] = [ + "All", + "Web Development", + "JavaScript", + "React", + "AI & ML", + "DevOps", + "Career", + "Open Source", +]; + +const articles: BlogArticle[] = [ + { + id: "modern-web-development", + title: "Modern Web Development: From Fundamentals to Production", + description: + "Understand the complete journey from HTML and CSS fundamentals to building maintainable, scalable, production-ready web applications.", + slug: "#", // /blog/modern-web-development + category: "Web Development", + tags: ["HTML", "CSS", "JavaScript", "Frontend"], + author: "Ajay Dhangar", + authorRole: "Founder · CodeHarborHub", + authorAvatar: + "https://github.com/ajay-dhangar.png", + date: "Sep 12, 2026", + isoDate: "2026-09-12", + readTime: 10, + image: "/img/blog-modern-web-development.jpg", + featured: true, + popular: true, + }, + { + id: "javascript-event-loop", + title: "Understanding the JavaScript Event Loop", + description: + "Learn how JavaScript handles asynchronous operations, callbacks, promises, microtasks, and the event loop.", + slug: "#", // /blog/javascript-event-loop + category: "JavaScript", + tags: ["JavaScript", "Async", "Runtime"], + author: "CodeHarborHub", + authorRole: "Engineering Team", + authorAvatar: "/img/nav-logo.jpg", + date: "Sep 08, 2026", + isoDate: "2026-09-08", + readTime: 8, + image: "/img/blog-javascript-event-loop.jpg", + popular: true, + }, + { + id: "react-architecture", + title: "Designing Scalable React Applications", + description: + "Explore practical patterns for structuring React applications as projects grow from prototypes into production systems.", + slug: "#", // /blog/scalable-react-applications + category: "React", + tags: ["React", "Architecture", "TypeScript"], + author: "CodeHarborHub", + authorRole: "Engineering Team", + authorAvatar: "/img/nav-logo.jpg", + date: "Sep 04, 2026", + isoDate: "2026-09-04", + readTime: 12, + image: "/img/blog-react-architecture.jpg", + popular: true, + }, + { + id: "ai-developer-tools", + title: "How AI Is Changing the Developer Workflow", + description: + "A practical look at how developers can use AI for research, coding, debugging, documentation, testing, and learning.", + slug: "#", // /blog/ai-developer-workflow + category: "AI & ML", + tags: ["AI", "Developer Tools", "Productivity"], + author: "CodeHarborHub", + authorRole: "Research & Education", + authorAvatar: "/img/nav-logo.jpg", + date: "Aug 29, 2026", + isoDate: "2026-08-29", + readTime: 9, + image: "/img/blog-ai-developer-tools.jpg", + }, + { + id: "open-source-contributing", + title: "A Practical Guide to Your First Open Source Contribution", + description: + "Learn how to discover projects, understand repositories, choose issues, create pull requests, and become a useful contributor.", + slug: "#", // /blog/first-open-source-contribution + category: "Open Source", + tags: ["GitHub", "Open Source", "Contributing"], + author: "Ajay Dhangar", + authorRole: "Open Source Maintainer", + authorAvatar: + "https://github.com/ajay-dhangar.png", + date: "Aug 22, 2026", + isoDate: "2026-08-22", + readTime: 11, + image: "/img/blog-open-source.jpg", + }, + { + id: "developer-career", + title: "Building a Strong Developer Portfolio in 2026", + description: + "What actually makes a developer portfolio useful to recruiters, hiring managers, clients, and open-source communities.", + slug: "#", // /blog/developer-portfolio-2026 + category: "Career", + tags: ["Career", "Portfolio", "Jobs"], + author: "CodeHarborHub", + authorRole: "Career & Community", + authorAvatar: "/img/nav-logo.jpg", + date: "Aug 17, 2026", + isoDate: "2026-08-17", + readTime: 7, + image: "/img/blog-developer-career.jpg", + }, + { + id: "docker-development", + title: "Docker for Developers: From Local Setup to Deployment", + description: + "Understand containers, images, Dockerfiles, Compose, networking, volumes, and practical development workflows.", + slug: "#", // /blog/docker-for-developers + category: "DevOps", + tags: ["Docker", "DevOps", "Deployment"], + author: "CodeHarborHub", + authorRole: "Engineering Team", + authorAvatar: "/img/nav-logo.jpg", + date: "Aug 10, 2026", + isoDate: "2026-08-10", + readTime: 13, + image: "/img/blog-docker.jpg", + }, + { + id: "typescript-best-practices", + title: "TypeScript Practices That Make Large Codebases Better", + description: + "Practical TypeScript patterns for safer APIs, reusable types, maintainability, and better developer experience.", + slug: "#", // /blog/typescript-best-practices + category: "Web Development", + tags: ["TypeScript", "JavaScript", "Best Practices"], + author: "CodeHarborHub", + authorRole: "Engineering Team", + authorAvatar: "/img/nav-logo.jpg", + date: "Aug 04, 2026", + isoDate: "2026-08-04", + readTime: 10, + image: "/img/blog-typescript.jpg", + }, +]; + +const popularArticles = articles.filter((article) => article.popular); + +function BlogImage({ + article, + featured = false, +}: { + article: BlogArticle; + featured?: boolean; +}) { + return ( +
+ { + event.currentTarget.style.display = "none"; + }} + /> + +
+ +
+ + {article.category} +
+ + {featured && ( +
+ + Featured +
+ )} +
+ ); +} + +function ArticleMeta({ article }: { article: BlogArticle }) { + return ( +
+ + + + + + + + {article.readTime} min read + +
+ ); +} + +function Author({ + article, + compact = false, +}: { + article: BlogArticle; + compact?: boolean; +}) { + return ( +
+ { + event.currentTarget.src = "/img/nav-logo.jpg"; + }} + /> + +
+ {article.author} + {!compact && {article.authorRole}} +
+
+ ); +} + +function ArticleCard({ article }: { article: BlogArticle }) { + return ( +
+ + + + +
+ + + +

{article.title}

+ + +

{article.description}

+ +
+ {article.tags.slice(0, 3).map((tag) => ( + {tag} + ))} +
+ +
+ + + + + +
+
+
+ ); +} + +export default function BlogsPage(): JSX.Element { + const [activeCategory, setActiveCategory] = + useState("All"); + const [searchQuery, setSearchQuery] = useState(""); + const [sortBy, setSortBy] = useState<"latest" | "shortest">("latest"); + + const filteredArticles = useMemo(() => { + const query = searchQuery.trim().toLowerCase(); + + const result = articles.filter((article) => { + const matchesCategory = + activeCategory === "All" || + article.category === activeCategory; + + if (!query) { + return matchesCategory; + } + + const searchableText = [ + article.title, + article.description, + article.category, + ...article.tags, + article.author, + ] + .join(" ") + .toLowerCase(); + + return matchesCategory && searchableText.includes(query); + }); + + return [...result].sort((a, b) => { + if (sortBy === "shortest") { + return a.readTime - b.readTime; + } + + return ( + new Date(b.isoDate).getTime() - + new Date(a.isoDate).getTime() + ); + }); + }, [activeCategory, searchQuery, sortBy]); + + const featuredArticle = + articles.find((article) => article.featured) ?? articles[0]; + + return ( + +
+ {/* ===================================================== + HERO + ===================================================== */} +
+
+
+ +
+
+
+
+ + CodeHarborHub Blog +
+ +

+ Ideas for developers + who build. +

+ +

+ Practical engineering knowledge, tutorials, career + insights, open-source stories, and ideas to help you + build better software. +

+ +
+
+ {articles.length}+ + Articles +
+ +
+ 8 + Topics +
+ +
+ Free + Always +
+
+
+ +
+
+
+ + + +
+ + developer@codeharborhub:~ + + +
+ +
+

+ $ cat + learning.md +

+ +
+ # Learn. Build. Share. +
+ +

+ Technical knowledge should be +
+ practical, accessible, and open. +

+ +
+ + tutorials +
+ +
+ + engineering +
+ +
+ + open source +
+ +
+ + career +
+ +

+ ${" "} + +

+
+
+
+
+
+ + {/* ===================================================== + FEATURED ARTICLE + ===================================================== */} +
+
+
+
+ + + Editor's pick + + +

Featured from the community

+
+ + + View all posts + + +
+ +
+ + + + +
+
+ + {featuredArticle.category} + + + +
+ + +

{featuredArticle.title}

+ + +

{featuredArticle.description}

+ +
+ {featuredArticle.tags.map((tag) => ( + {tag} + ))} +
+ +
+ + + + Read article + + +
+
+
+
+
+ + {/* ===================================================== + POPULAR + ===================================================== */} +
+
+
+
+ + + Popular now + + +

What developers are reading

+
+
+ +
+ {popularArticles.slice(0, 3).map((article, index) => ( + + + {String(index + 1).padStart(2, "0")} + + +
+ + {article.category} + + +

{article.title}

+ + +
+ + + + ))} +
+
+
+ + {/* ===================================================== + ARTICLES + ===================================================== */} +
+
+
+
+ + + Explore the library + + +

Latest articles

+
+ +
+ {filteredArticles.length}{" "} + {filteredArticles.length === 1 + ? "article" + : "articles"} +
+
+ + {/* Search */} +
+
+ + + + setSearchQuery(event.target.value) + } + placeholder="Search articles, topics, technologies..." + aria-label="Search articles" + /> + + {searchQuery && ( + + )} +
+ +
+ + + + + +
+
+ + {/* Category filters */} +
+ {categories.map((category) => ( + + ))} +
+ + {/* Results */} + {filteredArticles.length > 0 ? ( +
+ {filteredArticles.map((article) => ( + + ))} +
+ ) : ( +
+
+ +
+ +

No articles found

+ +

+ Try a different keyword or choose another + category. +

+ + +
+ )} +
+
+ + {/* ===================================================== + TOPICS + ===================================================== */} +
+
+
+
+ + + Explore by topic + + +

Find your next rabbit hole.

+ +

+ Go deeper into the technologies and skills that + matter to your development journey. +

+
+ +
+ {categories + .filter((category) => category !== "All") + .map((category) => { + const count = articles.filter( + (article) => article.category === category + ).length; + + return ( + + ); + })} +
+
+
+
+ + {/* ===================================================== + NEWSLETTER + ===================================================== */} +
+
+
+
+ +
+ +
+ + + Stay in the loop + + +

+ Useful developer content. + No noise. +

+ +

+ Get new tutorials, engineering articles, open-source + updates, and learning resources when they are + published. +

+ +
+ + Join the newsletter + + + + + + Free · Developer focused + +
+
+
+
+ + {/* ===================================================== + COMMUNITY CTA + ===================================================== */} +
+
+
+
+
+ +
+ + + Build in the open + + +

+ Don't just read. + Contribute. +

+ +

+ Improve documentation, write tutorials, fix examples, + share ideas, and help developers around the world + learn through open source. +

+ +
+ + Contribute on GitHub + + + + + Meet contributors + + +
+
+ +
+
+
+
+ + + +
+ + contribution + + +
+ +
+ main + + docs + + tutorial + + PR #128 + + merged ✓ +
+
+
+
+
+
+ + {/* ===================================================== + FINAL CTA + ===================================================== */} +
+
+
+ + +

+ Learn something today. + Build something tomorrow. +

+ +

+ Explore CodeHarborHub tutorials, roadmaps, practice + challenges, and projects. +

+ +
+ + Start learning + + + + + Explore roadmaps + + +
+
+
+
+
+
+ ); +} \ No newline at end of file diff --git a/src/pages/blogs/styles.module.css b/src/pages/blogs/styles.module.css new file mode 100644 index 000000000..186e898c4 --- /dev/null +++ b/src/pages/blogs/styles.module.css @@ -0,0 +1,1437 @@ +.page { + --blog-accent: var(--ifm-color-primary); + --blog-accent-soft: color-mix( + in srgb, + var(--blog-accent) 12%, + transparent + ); + + min-height: 100vh; + color: var(--ifm-font-color-base); + background: var(--ifm-background-color); +} + +.container { + width: min(1180px, calc(100% - 40px)); + margin: 0 auto; +} + +/* ========================================================= + COMMON +========================================================= */ + +.sectionEyebrow { + display: inline-flex; + align-items: center; + gap: 7px; + color: var(--blog-accent); + font-size: 0.72rem; + font-weight: 850; + letter-spacing: 0.11em; + text-transform: uppercase; +} + +.sectionMiniHeader { + display: flex; + align-items: end; + justify-content: space-between; + gap: 25px; + margin-bottom: 30px; +} + +.sectionMiniHeader h2, +.articlesHeader h2 { + margin: 9px 0 0; + font-size: clamp(1.8rem, 4vw, 2.7rem); + line-height: 1.08; + letter-spacing: -0.04em; +} + +.textLink { + display: inline-flex; + align-items: center; + gap: 7px; + color: var(--ifm-color-emphasis-700); + font-size: 0.85rem; + font-weight: 800; + text-decoration: none; +} + +.textLink:hover { + color: var(--blog-accent); + text-decoration: none; +} + +.primaryButton, +.secondaryButton { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; + min-height: 46px; + padding: 0 17px; + border-radius: 11px; + font-size: 0.86rem; + font-weight: 800; + text-decoration: none; + transition: + transform 180ms ease, + border-color 180ms ease, + box-shadow 180ms ease; +} + +.primaryButton { + border: 1px solid var(--blog-accent); + background: var(--blog-accent); + color: white; + box-shadow: 0 10px 26px + color-mix(in srgb, var(--blog-accent) 20%, transparent); +} + +.primaryButton:hover { + color: white; + text-decoration: none; + transform: translateY(-2px); + box-shadow: 0 15px 32px + color-mix(in srgb, var(--blog-accent) 28%, transparent); +} + +.secondaryButton { + border: 1px solid var(--ifm-color-emphasis-300); + background: var(--ifm-background-surface-color); + color: var(--ifm-font-color-base); +} + +.secondaryButton:hover { + color: var(--ifm-font-color-base); + border-color: var(--blog-accent); + text-decoration: none; + transform: translateY(-2px); +} + +/* ========================================================= + HERO +========================================================= */ + +.hero { + position: relative; + overflow: hidden; + padding: 2rem 0 3rem; + border-bottom: 1px solid var(--ifm-color-emphasis-200); + background: + radial-gradient( + circle at 90% 20%, + var(--blog-accent-soft), + transparent 28% + ), + var(--ifm-background-color); +} + +.heroGrid { + position: absolute; + inset: 0; + opacity: 0.25; + pointer-events: none; + background-image: + linear-gradient( + to right, + var(--ifm-color-emphasis-200) 1px, + transparent 1px + ), + linear-gradient( + to bottom, + var(--ifm-color-emphasis-200) 1px, + transparent 1px + ); + background-size: 55px 55px; + mask-image: linear-gradient(to bottom, black, transparent 75%); +} + +.heroGlow { + position: absolute; + right: 15%; + top: 0; + width: 420px; + height: 420px; + border-radius: 50%; + background: var(--blog-accent); + opacity: 0.07; + filter: blur(90px); + pointer-events: none; +} + +.heroInner { + position: relative; + z-index: 1; + display: grid; + grid-template-columns: minmax(0, 1fr) 430px; + gap: 90px; + align-items: center; +} + +.eyebrow { + display: inline-flex; + align-items: center; + gap: 9px; + color: var(--blog-accent); + font-size: 0.74rem; + font-weight: 850; + letter-spacing: 0.12em; + text-transform: uppercase; +} + +.eyebrow span { + width: 7px; + height: 7px; + border-radius: 50%; + background: currentColor; + box-shadow: 0 0 0 5px var(--blog-accent-soft); +} + +.heroCopy h1 { + max-width: 850px; + margin: 22px 0 22px; + font-size: clamp(3.3rem, 7vw, 6.4rem); + line-height: 0.92; + letter-spacing: -0.065em; +} + +.heroCopy h1 span { + display: block; + color: var(--blog-accent); +} + +.heroCopy > p { + max-width: 700px; + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: clamp(1rem, 2vw, 1.2rem); + line-height: 1.75; +} + +.heroStats { + display: flex; + flex-wrap: wrap; + gap: 0; + margin-top: 36px; +} + +.heroStats > div { + display: grid; + gap: 3px; + min-width: 100px; + padding-right: 25px; + margin-right: 25px; + border-right: 1px solid var(--ifm-color-emphasis-300); +} + +.heroStats > div:last-child { + border-right: 0; +} + +.heroStats strong { + font-size: 1.2rem; +} + +.heroStats span { + color: var(--ifm-color-emphasis-600); + font-size: 0.72rem; + font-weight: 700; +} + +/* ========================================================= + TERMINAL +========================================================= */ + +.heroTerminal, +.communityTerminal { + overflow: hidden; + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 18px; + background: var(--ifm-background-surface-color); + box-shadow: 0 30px 70px rgb(0 0 0 / 12%); +} + +.terminalHeader { + display: flex; + align-items: center; + gap: 10px; + padding: 13px 15px; + border-bottom: 1px solid var(--ifm-color-emphasis-200); + color: var(--ifm-color-emphasis-600); + font-family: var(--ifm-font-family-monospace); + font-size: 0.68rem; +} + +.terminalHeader > span { + flex: 1; + text-align: center; +} + +.terminalDots { + display: flex; + gap: 5px; +} + +.terminalDots span { + width: 8px; + height: 8px; + border-radius: 50%; + background: var(--ifm-color-emphasis-400); +} + +.terminalBody { + padding: 30px; + font-family: var(--ifm-font-family-monospace); + font-size: 0.76rem; + line-height: 1.8; +} + +.terminalBody p { + margin: 0 0 18px; +} + +.prompt { + color: var(--blog-accent); +} + +.terminalTitle { + margin-bottom: 15px; + color: var(--ifm-font-color-base); + font-size: 1.05rem; + font-weight: 800; +} + +.terminalTitle span { + color: var(--blog-accent); +} + +.terminalMuted { + color: var(--ifm-color-emphasis-600); +} + +.terminalLine { + display: flex; + gap: 10px; + color: var(--ifm-color-emphasis-800); +} + +.green { + color: #35b56a; +} + +.cursorLine { + margin-top: 18px !important; +} + +.cursor { + animation: blink 1.1s steps(2, start) infinite; + color: var(--blog-accent); +} + +@keyframes blink { + 50% { + opacity: 0; + } +} + +/* ========================================================= + FEATURED +========================================================= */ + +.featuredSection { + padding: 90px 0 70px; +} + +.featuredCard { + display: grid; + grid-template-columns: 1fr 1fr; + overflow: hidden; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 22px; + background: var(--ifm-background-surface-color); + box-shadow: 0 18px 55px rgb(0 0 0 / 6%); +} + +.featuredImageLink { + display: block; + min-height: 470px; + overflow: hidden; +} + +.articleImage { + position: relative; + height: 245px; + overflow: hidden; + background: + linear-gradient( + 135deg, + var(--blog-accent-soft), + var(--ifm-background-surface-color) + ); +} + +.featuredImage { + height: 100%; + min-height: 470px; +} + +.articleImage img { + width: 100%; + height: 100%; + object-fit: cover; + transition: transform 500ms ease; +} + +.articleCard:hover .articleImage img, +.featuredCard:hover .articleImage img { + transform: scale(1.04); +} + +.imageOverlay { + position: absolute; + inset: 0; + background: linear-gradient( + to top, + rgb(0 0 0 / 45%), + transparent 65% + ); +} + +.imageCategory, +.featuredLabel { + position: absolute; + top: 15px; + display: inline-flex; + align-items: center; + gap: 6px; + padding: 7px 10px; + border: 1px solid rgb(255 255 255 / 20%); + border-radius: 999px; + background: rgb(0 0 0 / 35%); + color: white; + font-size: 0.67rem; + font-weight: 800; + backdrop-filter: blur(8px); +} + +.imageCategory { + left: 15px; +} + +.featuredLabel { + right: 15px; +} + +.featuredContent { + display: flex; + flex-direction: column; + justify-content: center; + padding: 48px; +} + +.featuredTop { + display: flex; + align-items: center; + justify-content: space-between; + gap: 15px; + flex-wrap: wrap; +} + +.categoryPill { + display: inline-flex; + align-items: center; + padding: 6px 10px; + border-radius: 999px; + background: var(--blog-accent-soft); + color: var(--blog-accent); + font-size: 0.68rem; + font-weight: 800; +} + +.articleMeta { + display: flex; + flex-wrap: wrap; + gap: 12px; + color: var(--ifm-color-emphasis-600); + font-size: 0.7rem; + font-weight: 700; +} + +.articleMeta span { + display: inline-flex; + align-items: center; + gap: 5px; +} + +.featuredTitleLink { + color: inherit; + text-decoration: none; +} + +.featuredTitleLink:hover { + color: inherit; + text-decoration: none; +} + +.featuredContent h2 { + max-width: 650px; + margin: 18px 0 14px; + font-size: clamp(2rem, 4vw, 3.25rem); + line-height: 1.05; + letter-spacing: -0.045em; +} + +.featuredContent > p { + max-width: 610px; + margin: 0; + color: var(--ifm-color-emphasis-700); + line-height: 1.75; +} + +.featuredTags, +.tagList { + display: flex; + flex-wrap: wrap; + gap: 7px; +} + +.featuredTags { + margin-top: 24px; +} + +.featuredTags span, +.tagList span { + padding: 5px 8px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 6px; + color: var(--ifm-color-emphasis-600); + font-size: 0.65rem; + font-weight: 700; +} + +.featuredFooter { + display: flex; + align-items: center; + justify-content: space-between; + gap: 20px; + margin-top: 34px; + padding-top: 25px; + border-top: 1px solid var(--ifm-color-emphasis-200); +} + +/* ========================================================= + AUTHOR +========================================================= */ + +.author { + display: flex; + align-items: center; + gap: 10px; +} + +.author img { + width: 38px; + height: 38px; + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 50%; + object-fit: cover; +} + +.author strong, +.author span { + display: block; +} + +.author strong { + font-size: 0.76rem; +} + +.author span { + margin-top: 2px; + color: var(--ifm-color-emphasis-600); + font-size: 0.65rem; +} + +.authorCompact img { + width: 31px; + height: 31px; +} + +.authorCompact strong { + font-size: 0.69rem; +} + +/* ========================================================= + POPULAR +========================================================= */ + +.popularSection { + padding: 35px 0 85px; +} + +.popularGrid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 13px; +} + +.popularCard { + display: grid; + grid-template-columns: auto 1fr auto; + gap: 17px; + align-items: start; + padding: 23px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 15px; + background: var(--ifm-background-surface-color); + color: inherit; + text-decoration: none; + transition: + transform 180ms ease, + border-color 180ms ease; +} + +.popularCard:hover { + color: inherit; + text-decoration: none; + border-color: color-mix( + in srgb, + var(--blog-accent) 40%, + transparent + ); + transform: translateY(-3px); +} + +.popularNumber { + color: var(--blog-accent); + font-family: var(--ifm-font-family-monospace); + font-size: 0.7rem; + font-weight: 800; +} + +.popularCategory { + color: var(--blog-accent); + font-size: 0.65rem; + font-weight: 800; + text-transform: uppercase; +} + +.popularCard h3 { + margin: 6px 0 13px; + font-size: 0.98rem; + line-height: 1.4; +} + +.popularCard > svg { + color: var(--ifm-color-emphasis-500); +} + +/* ========================================================= + ARTICLES +========================================================= */ + +.articlesSection { + padding: 90px 0; + background: + radial-gradient( + circle at 90% 10%, + var(--blog-accent-soft), + transparent 24% + ), + var(--ifm-background-surface-color); +} + +.articlesHeader { + display: flex; + align-items: end; + justify-content: space-between; + margin-bottom: 28px; +} + +.resultCount { + color: var(--ifm-color-emphasis-600); + font-size: 0.75rem; + font-weight: 750; +} + +.controls { + display: grid; + grid-template-columns: 1fr auto; + gap: 10px; + margin-bottom: 17px; +} + +.searchBox, +.sortBox { + display: flex; + align-items: center; + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 11px; + background: var(--ifm-background-color); +} + +.searchBox { + min-height: 48px; + padding: 0 13px; + color: var(--ifm-color-emphasis-600); +} + +.searchBox:focus-within { + border-color: var(--blog-accent); + box-shadow: 0 0 0 3px var(--blog-accent-soft); +} + +.searchBox input { + width: 100%; + height: 46px; + padding: 0 10px; + border: 0; + outline: 0; + background: transparent; + color: var(--ifm-font-color-base); + font: inherit; + font-size: 0.82rem; +} + +.searchBox button { + display: grid; + width: 28px; + height: 28px; + place-items: center; + border: 0; + border-radius: 7px; + background: transparent; + color: var(--ifm-color-emphasis-600); + cursor: pointer; +} + +.sortBox { + position: relative; + min-width: 160px; + padding: 0 12px; + color: var(--ifm-color-emphasis-600); +} + +.sortBox select { + width: 100%; + height: 46px; + padding: 0 8px; + appearance: none; + border: 0; + outline: 0; + background: transparent; + color: var(--ifm-font-color-base); + font: inherit; + font-size: 0.8rem; + cursor: pointer; +} + +.sortBox > svg:last-child { + pointer-events: none; +} + +.categoryScroller { + display: flex; + gap: 7px; + margin-bottom: 32px; + overflow-x: auto; + scrollbar-width: none; +} + +.categoryScroller::-webkit-scrollbar { + display: none; +} + +.categoryScroller button { + display: inline-flex; + align-items: center; + gap: 6px; + min-height: 36px; + flex: 0 0 auto; + padding: 0 13px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 999px; + background: var(--ifm-background-color); + color: var(--ifm-color-emphasis-700); + font-size: 0.73rem; + font-weight: 750; + cursor: pointer; + transition: + color 180ms ease, + background 180ms ease, + border-color 180ms ease; +} + +.categoryScroller button:hover { + border-color: var(--blog-accent); + color: var(--blog-accent); +} + +.categoryScroller .categoryActive { + border-color: var(--blog-accent); + background: var(--blog-accent); + color: white; +} + +.articleGrid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 20px; +} + +.articleCard { + overflow: hidden; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 17px; + background: var(--ifm-background-color); + transition: + transform 200ms ease, + border-color 200ms ease, + box-shadow 200ms ease; +} + +.articleCard:hover { + border-color: color-mix( + in srgb, + var(--blog-accent) 35%, + transparent + ); + box-shadow: 0 20px 50px rgb(0 0 0 / 8%); + transform: translateY(-5px); +} + +.cardImageLink { + display: block; + color: inherit; +} + +.articleCardBody { + padding: 22px; +} + +.articleTitleLink { + display: block; + color: inherit; + text-decoration: none; +} + +.articleTitleLink:hover { + color: inherit; + text-decoration: none; +} + +.articleCard h3 { + margin: 12px 0 10px; + font-size: 1.08rem; + line-height: 1.3; + letter-spacing: -0.02em; +} + +.articleCardBody > p { + display: -webkit-box; + margin: 0 0 17px; + overflow: hidden; + color: var(--ifm-color-emphasis-700); + font-size: 0.82rem; + line-height: 1.7; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; +} + +.cardFooter { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + margin-top: 21px; + padding-top: 17px; + border-top: 1px solid var(--ifm-color-emphasis-200); +} + +.readButton { + display: grid; + width: 34px; + height: 34px; + place-items: center; + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 9px; + color: var(--ifm-color-emphasis-700); + transition: + color 180ms ease, + background 180ms ease, + border-color 180ms ease; +} + +.readButton:hover { + border-color: var(--blog-accent); + background: var(--blog-accent-soft); + color: var(--blog-accent); +} + +/* ========================================================= + EMPTY +========================================================= */ + +.emptyState { + display: grid; + justify-items: center; + padding: 80px 20px; + border: 1px dashed var(--ifm-color-emphasis-300); + border-radius: 18px; + text-align: center; +} + +.emptyIcon { + display: grid; + width: 52px; + height: 52px; + margin-bottom: 16px; + place-items: center; + border-radius: 14px; + background: var(--blog-accent-soft); + color: var(--blog-accent); +} + +.emptyState h3 { + margin: 0 0 8px; +} + +.emptyState p { + margin: 0 0 20px; + color: var(--ifm-color-emphasis-600); +} + +/* ========================================================= + TOPICS +========================================================= */ + +.topicsSection { + padding: 95px 0; +} + +.topicLayout { + display: grid; + grid-template-columns: 0.72fr 1.28fr; + gap: 80px; + align-items: start; +} + +.topicLayout h2 { + max-width: 450px; + margin: 12px 0; + font-size: clamp(2rem, 4vw, 3rem); + line-height: 1.05; + letter-spacing: -0.045em; +} + +.topicLayout > div:first-child p { + max-width: 430px; + margin: 0; + color: var(--ifm-color-emphasis-700); + line-height: 1.7; +} + +.topicGrid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 10px; +} + +.topicCard { + position: relative; + display: grid; + grid-template-columns: 1fr auto; + gap: 5px; + padding: 20px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 14px; + background: var(--ifm-background-surface-color); + color: var(--ifm-font-color-base); + text-align: left; + cursor: pointer; + transition: + transform 180ms ease, + border-color 180ms ease; +} + +.topicCard:hover { + border-color: var(--blog-accent); + transform: translateY(-3px); +} + +.topicCard span { + grid-column: 1; + font-size: 0.88rem; + font-weight: 800; +} + +.topicCard small { + grid-column: 1; + color: var(--ifm-color-emphasis-600); + font-size: 0.66rem; +} + +.topicCard svg { + grid-column: 2; + grid-row: 1 / span 2; + align-self: center; + color: var(--blog-accent); +} + +/* ========================================================= + NEWSLETTER +========================================================= */ + +.newsletterSection { + padding: 10px 0 90px; +} + +.newsletterCard { + position: relative; + overflow: hidden; + padding: 65px 30px; + border: 1px solid + color-mix(in srgb, var(--blog-accent) 30%, var(--ifm-color-emphasis-200)); + border-radius: 25px; + background: + radial-gradient( + circle at 80% 0, + var(--blog-accent-soft), + transparent 35% + ), + var(--ifm-background-surface-color); + text-align: center; +} + +.newsletterGlow { + position: absolute; + right: -120px; + bottom: -180px; + width: 350px; + height: 350px; + border-radius: 50%; + background: var(--blog-accent); + opacity: 0.06; + filter: blur(70px); +} + +.newsletterIcon { + position: relative; + display: grid; + width: 52px; + height: 52px; + margin: 0 auto 20px; + place-items: center; + border-radius: 15px; + background: var(--blog-accent-soft); + color: var(--blog-accent); +} + +.newsletterCard h2 { + position: relative; + max-width: 700px; + margin: 12px auto; + font-size: clamp(2.1rem, 5vw, 3.5rem); + line-height: 1.05; + letter-spacing: -0.045em; +} + +.newsletterCard h2 span { + color: var(--blog-accent); +} + +.newsletterCard > p { + position: relative; + max-width: 650px; + margin: 0 auto; + color: var(--ifm-color-emphasis-700); + line-height: 1.75; +} + +.newsletterActions { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + gap: 15px; + margin-top: 28px; +} + +.newsletterNote { + display: inline-flex; + align-items: center; + gap: 6px; + color: var(--ifm-color-emphasis-600); + font-size: 0.7rem; + font-weight: 700; +} + +.newsletterNote svg { + color: #35b56a; +} + +/* ========================================================= + COMMUNITY +========================================================= */ + +.communitySection { + padding: 0 0 90px; +} + +.communityCard { + display: grid; + grid-template-columns: 1fr 0.72fr; + gap: 55px; + align-items: center; + padding: 52px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 24px; + background: var(--ifm-background-surface-color); +} + +.communityIcon { + display: grid; + width: 50px; + height: 50px; + margin-bottom: 22px; + place-items: center; + border-radius: 14px; + background: var(--blog-accent-soft); + color: var(--blog-accent); +} + +.communityContent h2 { + max-width: 650px; + margin: 11px 0 15px; + font-size: clamp(2rem, 4vw, 3rem); + line-height: 1.05; + letter-spacing: -0.04em; +} + +.communityContent h2 span { + color: var(--blog-accent); +} + +.communityContent > p { + max-width: 620px; + margin: 0; + color: var(--ifm-color-emphasis-700); + line-height: 1.75; +} + +.communityActions { + display: flex; + flex-wrap: wrap; + gap: 10px; + margin-top: 28px; +} + +.contributionTree { + display: grid; + gap: 10px; + padding: 25px; + color: var(--ifm-color-emphasis-700); + font-family: var(--ifm-font-family-monospace); + font-size: 0.72rem; +} + +.contributionTree span, +.contributionTree b, +.contributionTree strong { + display: block; + padding: 9px 12px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 8px; + background: var(--ifm-background-color); +} + +.contributionTree b { + color: var(--blog-accent); +} + +.contributionTree strong { + color: #35b56a; +} + +.contributionTree i { + width: 1px; + height: 10px; + margin-left: 15px; + background: var(--ifm-color-emphasis-300); +} + +/* ========================================================= + FINAL +========================================================= */ + +.finalSection { + padding: 0 0 110px; +} + +.finalCard { + display: grid; + justify-items: center; + padding: 60px 25px; + border-top: 1px solid var(--ifm-color-emphasis-200); + text-align: center; +} + +.finalCard > svg { + margin-bottom: 20px; + color: var(--blog-accent); +} + +.finalCard h2 { + max-width: 750px; + margin: 0 auto 15px; + font-size: clamp(2.2rem, 5vw, 3.7rem); + line-height: 1.03; + letter-spacing: -0.05em; +} + +.finalCard h2 span { + color: var(--blog-accent); +} + +.finalCard p { + max-width: 600px; + margin: 0 auto; + color: var(--ifm-color-emphasis-700); + line-height: 1.7; +} + +.finalActions { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 10px; + margin-top: 27px; +} + +/* ========================================================= + DARK MODE +========================================================= */ + +[data-theme="dark"] .hero { + background: + radial-gradient( + circle at 90% 20%, + color-mix(in srgb, var(--blog-accent) 13%, transparent), + transparent 30% + ), + var(--ifm-background-color); +} + +[data-theme="dark"] .heroTerminal, +[data-theme="dark"] .communityTerminal, +[data-theme="dark"] .featuredCard { + box-shadow: 0 30px 80px rgb(0 0 0 / 30%); +} + +/* ========================================================= + RESPONSIVE +========================================================= */ + +@media (max-width: 1050px) { + .heroInner { + grid-template-columns: 1fr; + gap: 50px; + } + + .heroTerminal { + max-width: 600px; + } + + .featuredCard { + grid-template-columns: 1fr; + } + + .featuredImageLink, + .featuredImage { + min-height: 380px; + } + + .topicLayout { + grid-template-columns: 1fr; + gap: 40px; + } + + .communityCard { + grid-template-columns: 1fr; + } +} + +@media (max-width: 850px) { + .container { + width: min(100% - 30px, 720px); + } + + .hero { + padding: 65px 0 75px; + } + + .popularGrid, + .articleGrid { + grid-template-columns: repeat(2, 1fr); + } + + .articleGrid .articleCard:last-child { + grid-column: span 2; + } + + .articleGrid .articleCard:last-child .articleImage { + height: 300px; + } + + .principleGrid { + grid-template-columns: 1fr; + } + + .communityCard { + padding: 40px 30px; + } +} + +@media (max-width: 600px) { + .container { + width: min(100% - 24px, 520px); + } + + .hero { + padding: 52px 0 60px; + } + + .heroCopy h1 { + font-size: 3.25rem; + } + + .heroStats { + display: grid; + grid-template-columns: repeat(3, 1fr); + } + + .heroStats > div { + min-width: 0; + padding-right: 10px; + margin-right: 10px; + } + + .heroStats strong { + font-size: 1rem; + } + + .heroStats span { + font-size: 0.62rem; + } + + .terminalBody { + padding: 22px; + } + + .featuredSection, + .popularSection, + .articlesSection, + .topicsSection { + padding-top: 65px; + padding-bottom: 65px; + } + + .sectionMiniHeader, + .articlesHeader { + align-items: start; + flex-direction: column; + } + + .featuredContent { + padding: 30px 22px; + } + + .featuredImageLink, + .featuredImage { + min-height: 280px; + } + + .featuredContent h2 { + font-size: 2rem; + } + + .featuredFooter { + align-items: stretch; + flex-direction: column; + } + + .featuredFooter .primaryButton { + width: 100%; + } + + .popularGrid, + .articleGrid, + .topicGrid { + grid-template-columns: 1fr; + } + + .articleGrid .articleCard:last-child { + grid-column: auto; + } + + .articleGrid .articleCard:last-child .articleImage { + height: 245px; + } + + .controls { + grid-template-columns: 1fr; + } + + .sortBox { + width: 100%; + } + + .communityCard { + padding: 30px 20px; + border-radius: 19px; + } + + .communityActions, + .newsletterActions, + .finalActions { + display: grid; + grid-template-columns: 1fr; + width: 100%; + } + + .communityActions .primaryButton, + .communityActions .secondaryButton, + .newsletterActions .primaryButton, + .finalActions .primaryButton, + .finalActions .secondaryButton { + width: 100%; + } + + .newsletterCard { + padding: 48px 20px; + border-radius: 20px; + } + + .newsletterCard h2 { + font-size: 2.2rem; + } + + .finalSection { + padding-bottom: 70px; + } +} + +@media (prefers-reduced-motion: reduce) { + .cursor, + .primaryButton, + .secondaryButton, + .articleCard, + .articleImage img, + .popularCard, + .topicCard { + animation: none; + transition: none; + } +} \ No newline at end of file diff --git a/src/pages/careers/community-intern/index.tsx b/src/pages/careers/community-intern/index.tsx new file mode 100644 index 000000000..a21fff4b2 --- /dev/null +++ b/src/pages/careers/community-intern/index.tsx @@ -0,0 +1,840 @@ +import React, { useState } from "react"; +import Layout from "@theme/Layout"; +import Link from "@docusaurus/Link"; +import { + ArrowLeft, + ArrowRight, + ArrowUpRight, + CalendarDays, + Check, + ChevronDown, + Code2, + Compass, + ExternalLink, + Github, + Globe2, + Heart, + Lightbulb, + MessageCircle, + Megaphone, + Network, + Rocket, + Sparkles, + Target, + Users, +} from "lucide-react"; + +import styles from "./styles.module.css"; + +type FAQ = { + question: string; + answer: string; +}; + +const responsibilities = [ + "Help grow and maintain a welcoming developer community around CodeHarborHub.", + "Welcome new contributors and help them understand how to participate in the project.", + "Support community discussions across GitHub, Discord, social platforms, and other community channels.", + "Help organize online events, workshops, learning sessions, contributor activities, and community campaigns.", + "Identify common questions, blockers, and feedback from learners and contributors.", + "Create community announcements, event posts, contributor updates, and educational content.", + "Help maintain contributor documentation, onboarding resources, FAQs, and community guidelines.", + "Encourage developers to participate in open-source projects, challenges, discussions, and learning activities.", + "Track community engagement and identify opportunities to improve participation and retention.", + "Work with engineering, content, design, and education contributors to turn community feedback into useful improvements.", +]; + +const requirements = [ + "Strong communication skills and willingness to interact with developers and learners.", + "Genuine interest in technology, developer communities, education, or open source.", + "Comfortable communicating through written messages, discussions, and community platforms.", + "Basic understanding of GitHub and the open-source contribution workflow.", + "Ability to organize tasks, events, conversations, and community activities.", + "Ability to listen to community feedback and communicate it clearly to the team.", + "Positive, respectful, inclusive, and learner-first mindset.", + "Ability to work independently and take ownership of assigned community initiatives.", +]; + +const niceToHave = [ + "Previous experience managing a student, developer, coding, or open-source community.", + "Experience with Discord, GitHub Discussions, Slack, WhatsApp communities, or similar platforms.", + "Experience organizing hackathons, workshops, meetups, webinars, or developer events.", + "Basic knowledge of social media content and community growth.", + "Experience contributing to open-source projects.", + "Basic understanding of web development or programming.", + "Experience creating Canva/Figma graphics, short videos, or community announcements.", + "Understanding of community analytics and engagement metrics.", +]; + +const communityPillars = [ + { + icon: Heart, + title: "Welcome", + description: + "Make every learner and contributor feel that they have a place here.", + }, + { + icon: Network, + title: "Connect", + description: + "Bring developers together around learning, collaboration, projects, and open source.", + }, + { + icon: Rocket, + title: "Activate", + description: + "Turn passive visitors into learners, contributors, builders, and community members.", + }, + { + icon: Lightbulb, + title: "Listen", + description: + "Collect feedback and help the product evolve around real community needs.", + }, +]; + +const workflow = [ + { + number: "01", + title: "Discover", + description: + "Understand what learners, contributors, and developers need from the community.", + icon: Compass, + }, + { + number: "02", + title: "Plan", + description: + "Turn ideas into events, discussions, campaigns, content, and community initiatives.", + icon: Target, + }, + { + number: "03", + title: "Engage", + description: + "Start conversations, welcome members, answer questions, and encourage participation.", + icon: MessageCircle, + }, + { + number: "04", + title: "Organize", + description: + "Help run workshops, contributor programs, challenges, and developer events.", + icon: CalendarDays, + }, + { + number: "05", + title: "Measure", + description: + "Look at participation, feedback, retention, and other useful community signals.", + icon: Network, + }, + { + number: "06", + title: "Improve", + description: + "Use what you learn to make the community more useful, welcoming, and active.", + icon: Sparkles, + }, +]; + +const faqs: FAQ[] = [ + { + question: "Do I need professional community-management experience?", + answer: + "No. This internship is designed for people who want to learn community building. What matters most is communication, initiative, empathy, organization, and genuine interest in helping developers.", + }, + { + question: "Do I need to be a programmer?", + answer: + "You do not need to be an advanced programmer. However, familiarity with programming, GitHub, or developer communities will help you understand the people you are supporting.", + }, + { + question: "What platforms will I work with?", + answer: + "Depending on the community's needs, you may work with GitHub, Discord, social platforms, newsletters, event tools, documentation, and other collaboration channels.", + }, + { + question: "Can I organize my own community initiative?", + answer: + "Yes. Ownership is encouraged. If you identify a useful workshop, contributor campaign, event, discussion, or onboarding improvement, you can propose it and help take it from idea to execution.", + }, + { + question: "Is this only about social media?", + answer: + "No. Social media is only one part of community work. The role also includes contributor onboarding, events, discussions, feedback collection, documentation, open-source engagement, and improving the overall community experience.", + }, + { + question: "Can community work lead to other roles?", + answer: + "Community experience can build valuable skills in developer relations, developer advocacy, content, product, education, operations, event management, and open-source program management.", + }, +]; + +function SectionHeader({ + eyebrow, + title, + description, +}: { + eyebrow: string; + title: string; + description?: string; +}) { + return ( +
+ {eyebrow} +

{title}

+ {description &&

{description}

} +
+ ); +} + +export default function CommunityInternPage(): JSX.Element { + const [openFaq, setOpenFaq] = useState(0); + + return ( + +
+ {/* ===================================================== + HERO + ===================================================== */} +
+
+
+ +
+ + + Back to careers + + +
+
+
+ + Community · Internship +
+ +

+ Community + Intern +

+ +

+ Help developers learn, connect, contribute, and build + together in one of the most important parts of CodeHarborHub: + its community. +

+ +
+ + + Remote + + + + + Internship + + + + + Developer Community + +
+ +
+ + Apply for this role + + + + + Explore the role + + +
+
+ + {/* Community visual */} +
+
+
+
+ + + +
+ + community + + +
+ +
+
+
+ +
+ +
+ Developer Community + CodeHarborHub +
+
+ +
+
+ A + R + S + + +
+ + Developers building together +
+ +
+
+ A + +
+ Ajay +

Welcome to the contributor community! 👋

+
+
+ +
+ D + +
+ Developer +

+ I just opened my first documentation PR. +

+
+
+ +
+ C + +
+ Community +

That's awesome. Let's get it reviewed 🚀

+
+
+
+ +
+ + Start a conversation... +
+
+
+ +
+ + People first +
+
+
+
+
+ + {/* ===================================================== + ROLE SNAPSHOT + ===================================================== */} +
+
+
+
+ Role + Community Intern +
+ +
+ Level + Internship +
+ +
+ Work model + Remote-first +
+ +
+ Primary focus + Developer Community +
+
+
+
+ + {/* ===================================================== + ROLE OVERVIEW + ===================================================== */} +
+
+
+
+ + +

+ As a Community Intern, you will help create an environment + where developers feel comfortable asking questions, sharing + ideas, contributing to open source, attending events, and + learning together. +

+ +

+ You will work across community engagement, contributor + onboarding, events, communication, feedback collection, and + community programs. +

+ +

+ This is a hands-on role. Instead of simply posting content, + you will learn how communities actually grow: by creating + useful experiences, listening carefully, and helping people + take their next step. +

+
+ + +
+
+
+ + {/* ===================================================== + RESPONSIBILITIES + ===================================================== */} +
+
+ + +
+ {responsibilities.map((item, index) => ( +
+
+ {String(index + 1).padStart(2, "0")} +
+ +
+ +

{item}

+
+
+ ))} +
+
+
+ + {/* ===================================================== + REQUIREMENTS + ===================================================== */} +
+
+
+
+
+
+ +
+ +
+ Required +

What you should bring

+
+
+ +
    + {requirements.map((item) => ( +
  • + + {item} +
  • + ))} +
+
+ +
+
+
+ +
+ +
+ Bonus +

Great if you also have

+
+
+ +
    + {niceToHave.map((item) => ( +
  • + + {item} +
  • + ))} +
+
+
+
+
+ + {/* ===================================================== + COMMUNITY PILLARS + ===================================================== */} +
+
+ + +
+ {communityPillars.map((pillar) => { + const Icon = pillar.icon; + + return ( +
+
+ +
+ +

{pillar.title}

+ +

{pillar.description}

+
+ ); + })} +
+
+
+ + {/* ===================================================== + WORKFLOW + ===================================================== */} +
+
+ + +
+ {workflow.map((step, index) => { + const Icon = step.icon; + + return ( +
+
+ {step.number} + +
+ +
+
+ +

{step.title}

+ +

{step.description}

+ + {index !== workflow.length - 1 && ( + + )} +
+ ); + })} +
+
+
+ + {/* ===================================================== + POSSIBLE PROJECTS + ===================================================== */} +
+
+
+
+ Build something real + +

+ Your internship can become more than a list of tasks. +

+ +

+ We encourage interns to identify community problems and + propose solutions. You could own a contributor onboarding + improvement, a developer event series, a community campaign, + or a new learning-community program. +

+ +
+
+ + Contributor onboarding +
+ +
+ + Developer workshops +
+ +
+ + Community campaigns +
+ +
+ + Open-source programs +
+ +
+ + Learner feedback systems +
+ +
+ + Community documentation +
+
+
+ +
+
+
+ COMMUNITY EVENT + +
+ +

Open Source Learning Night

+ +

+ Learn how to make your first contribution and meet other + developers building in public. +

+ +
+ + + 120+ registered + + + + + Online + +
+ +
+ Join community + +
+
+
+
+
+
+ + {/* ===================================================== + OPEN SOURCE + ===================================================== */} +
+
+
+
+ +
+ +
+ + Open-source experience + + +

Learn community building in the open.

+ +

+ CodeHarborHub is built around open-source collaboration. + Community work can happen directly alongside developers, + contributors, educators, and maintainers. +

+ +
+ + Explore GitHub + + + + + Meet contributors + + +
+
+
+
+
+ + {/* ===================================================== + FAQ + ===================================================== */} +
+
+
+ + +
+ {faqs.map((faq, index) => { + const isOpen = openFaq === index; + + return ( +
+ + +
+

{faq.answer}

+
+
+ ); + })} +
+
+
+
+ + {/* ===================================================== + FINAL CTA + ===================================================== */} +
+
+
+
+ +
+ +
+ + + Build with the community + + +

+ Help create a place where + developers want to belong. +

+ +

+ If you enjoy bringing people together, helping others, and + creating meaningful developer experiences, this could be your + opportunity to start building real community experience. +

+ +
+ + Apply for this role + + + + + View all opportunities + + +
+ + + Community experience, event work, open-source contributions, + student communities, clubs, or personal community projects + can all demonstrate your potential. + +
+
+
+
+
+ ); +} \ No newline at end of file diff --git a/src/pages/careers/community-intern/styles.module.css b/src/pages/careers/community-intern/styles.module.css new file mode 100644 index 000000000..0ec691c09 --- /dev/null +++ b/src/pages/careers/community-intern/styles.module.css @@ -0,0 +1,1389 @@ +.page { + --career-accent: var(--ifm-color-primary); + --career-accent-soft: color-mix( + in srgb, + var(--career-accent) 12%, + transparent + ); + + color: var(--ifm-font-color-base); + background: var(--ifm-background-color); +} + +/* ========================================================= + COMMON +========================================================= */ + +.container { + width: min(1180px, calc(100% - 40px)); + margin: 0 auto; +} + +.section { + position: relative; + padding: 100px 0; +} + +.sectionMuted { + background: + radial-gradient( + circle at 10% 20%, + var(--career-accent-soft), + transparent 30% + ), + var(--ifm-background-surface-color); +} + +.sectionHeader { + max-width: 800px; + margin-bottom: 50px; +} + +.eyebrow { + display: inline-flex; + align-items: center; + gap: 7px; + color: var(--career-accent); + font-size: 0.74rem; + font-weight: 850; + letter-spacing: 0.12em; + text-transform: uppercase; +} + +.sectionHeader h2 { + margin: 11px 0 15px; + font-size: clamp(2rem, 4vw, 3.45rem); + line-height: 1.07; + letter-spacing: -0.045em; +} + +.sectionHeader p { + max-width: 730px; + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 1.05rem; + line-height: 1.75; +} + +/* ========================================================= + HERO +========================================================= */ + +.hero { + position: relative; + overflow: hidden; + padding: 52px 0 92px; + border-bottom: 1px solid var(--ifm-color-emphasis-200); + background: var(--ifm-background-color); +} + +.heroGrid { + position: absolute; + inset: 0; + opacity: 0.3; + pointer-events: none; + background-image: + linear-gradient( + to right, + var(--ifm-color-emphasis-200) 1px, + transparent 1px + ), + linear-gradient( + to bottom, + var(--ifm-color-emphasis-200) 1px, + transparent 1px + ); + background-size: 54px 54px; + mask-image: linear-gradient(to bottom, black, transparent 80%); +} + +.heroGlow { + position: absolute; + top: 70px; + right: 8%; + width: 430px; + height: 430px; + border-radius: 50%; + background: var(--career-accent); + opacity: 0.07; + filter: blur(80px); + pointer-events: none; +} + +.backLink { + position: relative; + z-index: 2; + display: inline-flex; + align-items: center; + gap: 8px; + margin-bottom: 58px; + color: var(--ifm-color-emphasis-700); + font-size: 0.9rem; + font-weight: 750; + text-decoration: none; + transition: + color 180ms ease, + transform 180ms ease; +} + +.backLink:hover { + color: var(--career-accent); + text-decoration: none; + transform: translateX(-3px); +} + +.heroLayout { + position: relative; + z-index: 1; + display: grid; + grid-template-columns: minmax(0, 1.05fr) minmax(400px, 0.95fr); + gap: 75px; + align-items: center; +} + +.badge { + display: inline-flex; + align-items: center; + gap: 9px; + padding: 7px 12px; + border: 1px solid + color-mix(in srgb, var(--career-accent) 30%, transparent); + border-radius: 999px; + background: var(--career-accent-soft); + color: var(--career-accent); + font-size: 0.76rem; + font-weight: 800; +} + +.badgeDot { + width: 7px; + height: 7px; + border-radius: 50%; + background: currentColor; + box-shadow: 0 0 0 4px + color-mix(in srgb, var(--career-accent) 15%, transparent); +} + +.heroContent h1 { + margin: 24px 0 22px; + font-size: clamp(3.3rem, 7vw, 6.1rem); + line-height: 0.92; + letter-spacing: -0.065em; +} + +.heroContent h1 span { + display: block; + color: var(--career-accent); +} + +.heroLead { + max-width: 690px; + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: clamp(1.05rem, 2vw, 1.25rem); + line-height: 1.75; +} + +.meta { + display: flex; + flex-wrap: wrap; + gap: 19px; + margin-top: 28px; +} + +.meta span { + display: inline-flex; + align-items: center; + gap: 8px; + color: var(--ifm-color-emphasis-700); + font-size: 0.9rem; + font-weight: 700; +} + +.meta svg { + color: var(--career-accent); +} + +.heroActions { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: 34px; +} + +.primaryButton, +.secondaryButton { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 9px; + min-height: 48px; + padding: 0 18px; + border-radius: 12px; + font-size: 0.9rem; + font-weight: 800; + text-decoration: none; + transition: + transform 180ms ease, + box-shadow 180ms ease, + border-color 180ms ease; +} + +.primaryButton { + border: 1px solid var(--career-accent); + background: var(--career-accent); + color: white; + box-shadow: 0 12px 28px + color-mix(in srgb, var(--career-accent) 22%, transparent); +} + +.primaryButton:hover { + color: white; + text-decoration: none; + transform: translateY(-2px); + box-shadow: 0 16px 36px + color-mix(in srgb, var(--career-accent) 30%, transparent); +} + +.secondaryButton { + border: 1px solid var(--ifm-color-emphasis-300); + background: var(--ifm-background-surface-color); + color: var(--ifm-font-color-base); +} + +.secondaryButton:hover { + color: var(--ifm-font-color-base); + text-decoration: none; + border-color: var(--career-accent); + transform: translateY(-2px); +} + +/* ========================================================= + COMMUNITY HERO VISUAL +========================================================= */ + +.communityVisual { + position: relative; + min-height: 450px; + display: grid; + place-items: center; +} + +.networkCard { + width: min(100%, 500px); + overflow: hidden; + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 20px; + background: var(--ifm-background-surface-color); + box-shadow: 0 35px 90px rgb(0 0 0 / 12%); + transform: rotate(1deg); +} + +.networkHeader { + display: flex; + align-items: center; + gap: 10px; + padding: 13px 15px; + border-bottom: 1px solid var(--ifm-color-emphasis-200); + color: var(--ifm-color-emphasis-600); + font-family: var(--ifm-font-family-monospace); + font-size: 0.7rem; +} + +.networkHeader > span { + flex: 1; +} + +.windowDots { + display: flex; + gap: 5px; +} + +.windowDots span { + width: 8px; + height: 8px; + border-radius: 50%; + background: var(--ifm-color-emphasis-400); +} + +.networkBody { + padding: 24px; +} + +.networkTitle { + display: flex; + align-items: center; + gap: 12px; +} + +.communityIcon { + display: grid; + width: 43px; + height: 43px; + place-items: center; + border-radius: 12px; + background: var(--career-accent-soft); + color: var(--career-accent); +} + +.networkTitle strong, +.networkTitle span { + display: block; +} + +.networkTitle strong { + margin-bottom: 3px; + font-size: 0.88rem; +} + +.networkTitle span { + color: var(--ifm-color-emphasis-600); + font-size: 0.7rem; +} + +.members { + display: flex; + align-items: center; + gap: 12px; + margin: 22px 0; +} + +.avatarStack { + display: flex; + padding-left: 7px; +} + +.avatarStack span { + display: grid; + width: 29px; + height: 29px; + margin-left: -7px; + place-items: center; + border: 2px solid var(--ifm-background-surface-color); + border-radius: 50%; + background: var(--career-accent-soft); + color: var(--career-accent); + font-size: 0.62rem; + font-weight: 850; +} + +.members small { + color: var(--ifm-color-emphasis-600); + font-size: 0.68rem; +} + +.messageList { + display: grid; + gap: 10px; +} + +.message { + display: flex; + gap: 10px; + padding: 11px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 11px; + background: var(--ifm-background-color); +} + +.messageAvatar { + display: grid; + width: 29px; + height: 29px; + flex: 0 0 auto; + place-items: center; + border-radius: 50%; + background: var(--career-accent-soft); + color: var(--career-accent); + font-size: 0.62rem; + font-weight: 850; +} + +.message strong { + display: block; + margin-bottom: 2px; + font-size: 0.68rem; +} + +.message p { + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.68rem; + line-height: 1.5; +} + +.communityInput { + display: flex; + align-items: center; + gap: 8px; + margin-top: 14px; + padding: 12px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 10px; + color: var(--ifm-color-emphasis-500); + font-size: 0.7rem; +} + +.floatingBadge { + position: absolute; + right: -5px; + bottom: 12px; + display: flex; + align-items: center; + gap: 8px; + padding: 12px 14px; + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 12px; + background: color-mix( + in srgb, + var(--ifm-background-surface-color) 96%, + transparent + ); + box-shadow: 0 18px 45px rgb(0 0 0 / 14%); + backdrop-filter: blur(14px); + color: var(--ifm-color-emphasis-800); + font-size: 0.76rem; + font-weight: 750; +} + +.floatingBadge svg { + color: var(--career-accent); +} + +/* ========================================================= + SUMMARY +========================================================= */ + +.summary { + border-bottom: 1px solid var(--ifm-color-emphasis-200); + background: var(--ifm-background-surface-color); +} + +.summaryGrid { + display: grid; + grid-template-columns: repeat(4, 1fr); +} + +.summaryGrid > div { + display: grid; + gap: 6px; + padding: 24px; + border-right: 1px solid var(--ifm-color-emphasis-200); +} + +.summaryGrid > div:first-child { + padding-left: 0; +} + +.summaryGrid > div:last-child { + border-right: 0; +} + +.summaryGrid span { + color: var(--ifm-color-emphasis-600); + font-size: 0.7rem; + font-weight: 800; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.summaryGrid strong { + font-size: 0.92rem; +} + +/* ========================================================= + ROLE / IMPACT +========================================================= */ + +.twoColumn { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(320px, 0.68fr); + gap: 80px; + align-items: start; +} + +.bodyText { + max-width: 760px; + margin: 0 0 18px; + color: var(--ifm-color-emphasis-700); + font-size: 1rem; + line-height: 1.8; +} + +.impactPanel { + position: sticky; + top: 110px; + padding: 32px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 22px; + background: + radial-gradient( + circle at 100% 0, + var(--career-accent-soft), + transparent 45% + ), + var(--ifm-background-surface-color); + box-shadow: 0 20px 60px rgb(0 0 0 / 7%); +} + +.impactIcon { + display: grid; + width: 48px; + height: 48px; + margin-bottom: 28px; + place-items: center; + border-radius: 14px; + background: var(--career-accent-soft); + color: var(--career-accent); +} + +.panelEyebrow { + color: var(--ifm-color-emphasis-600); + font-size: 0.7rem; + font-weight: 800; + letter-spacing: 0.1em; + text-transform: uppercase; +} + +.impactPanel h3 { + margin: 10px 0 14px; + font-size: 1.5rem; + line-height: 1.25; + letter-spacing: -0.025em; +} + +.impactPanel > p { + margin: 0; + color: var(--ifm-color-emphasis-700); + line-height: 1.7; +} + +.impactStats { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; + margin-top: 28px; +} + +.impactStats > div { + padding: 15px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 12px; + background: var(--ifm-background-color); +} + +.impactStats strong, +.impactStats span { + display: block; +} + +.impactStats strong { + margin-bottom: 4px; + color: var(--career-accent); + font-size: 1rem; +} + +.impactStats span { + color: var(--ifm-color-emphasis-600); + font-size: 0.7rem; +} + +/* ========================================================= + RESPONSIBILITIES +========================================================= */ + +.responsibilityGrid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 0 30px; + border-top: 1px solid var(--ifm-color-emphasis-200); +} + +.responsibilityItem { + display: grid; + grid-template-columns: 42px 1fr; + gap: 14px; + padding: 22px 0; + border-bottom: 1px solid var(--ifm-color-emphasis-200); +} + +.itemNumber { + color: var(--career-accent); + font-family: var(--ifm-font-family-monospace); + font-size: 0.7rem; + font-weight: 800; +} + +.itemContent { + display: flex; + gap: 10px; +} + +.itemContent svg { + flex: 0 0 auto; + margin-top: 3px; + color: var(--career-accent); +} + +.itemContent p { + margin: 0; + color: var(--ifm-color-emphasis-800); + font-size: 0.92rem; + line-height: 1.65; +} + +/* ========================================================= + REQUIREMENTS +========================================================= */ + +.requirementGrid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 22px; +} + +.requirementCard { + padding: 32px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 20px; + background: var(--ifm-background-surface-color); +} + +.cardHeader { + display: flex; + align-items: center; + gap: 14px; + margin-bottom: 28px; +} + +.cardIcon { + display: grid; + width: 46px; + height: 46px; + flex: 0 0 auto; + place-items: center; + border-radius: 13px; + background: var(--career-accent-soft); + color: var(--career-accent); +} + +.cardHeader span { + display: block; + margin-bottom: 3px; + color: var(--career-accent); + font-size: 0.69rem; + font-weight: 800; + letter-spacing: 0.1em; + text-transform: uppercase; +} + +.cardHeader h3 { + margin: 0; + font-size: 1.1rem; +} + +.requirementList { + display: grid; + gap: 15px; + padding: 0; + margin: 0; + list-style: none; +} + +.requirementList li { + display: flex; + gap: 10px; + color: var(--ifm-color-emphasis-700); + font-size: 0.88rem; + line-height: 1.6; +} + +.requirementList svg { + flex: 0 0 auto; + margin-top: 3px; + color: var(--career-accent); +} + +/* ========================================================= + COMMUNITY PILLARS +========================================================= */ + +.pillarsGrid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 1px; + overflow: hidden; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 20px; + background: var(--ifm-color-emphasis-200); +} + +.pillarCard { + min-height: 235px; + padding: 30px; + background: var(--ifm-background-color); +} + +.pillarIcon { + display: grid; + width: 44px; + height: 44px; + margin-bottom: 26px; + place-items: center; + border-radius: 12px; + background: var(--career-accent-soft); + color: var(--career-accent); +} + +.pillarCard h3 { + margin: 0 0 10px; + font-size: 1.05rem; +} + +.pillarCard p { + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.87rem; + line-height: 1.7; +} + +/* ========================================================= + WORKFLOW +========================================================= */ + +.workflow { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 16px; +} + +.workflowItem { + position: relative; + min-height: 235px; + padding: 25px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 17px; + background: var(--ifm-background-surface-color); + transition: + transform 180ms ease, + border-color 180ms ease, + box-shadow 180ms ease; +} + +.workflowItem:hover { + transform: translateY(-4px); + border-color: color-mix(in srgb, var(--career-accent) 40%, transparent); + box-shadow: 0 18px 45px rgb(0 0 0 / 8%); +} + +.workflowTop { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 26px; +} + +.workflowTop > span { + color: var(--career-accent); + font-family: var(--ifm-font-family-monospace); + font-size: 0.7rem; + font-weight: 800; +} + +.workflowIcon { + display: grid; + width: 40px; + height: 40px; + place-items: center; + border-radius: 11px; + background: var(--career-accent-soft); + color: var(--career-accent); +} + +.workflowItem h3 { + margin: 0 0 9px; + font-size: 1.05rem; +} + +.workflowItem p { + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.85rem; + line-height: 1.7; +} + +.workflowArrow { + position: absolute; + right: -27px; + top: 41px; + z-index: 2; + color: var(--career-accent); +} + +/* ========================================================= + PROJECTS +========================================================= */ + +.projectSection { + padding: 20px 0 100px; +} + +.projectCard { + display: grid; + grid-template-columns: 1fr 0.82fr; + gap: 55px; + align-items: center; + padding: 55px; + overflow: hidden; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 26px; + background: + radial-gradient( + circle at 0 0, + var(--career-accent-soft), + transparent 40% + ), + var(--ifm-background-surface-color); +} + +.projectContent h2 { + max-width: 620px; + margin: 11px 0 15px; + font-size: clamp(2rem, 4vw, 3rem); + line-height: 1.08; + letter-spacing: -0.04em; +} + +.projectContent > p { + max-width: 650px; + margin: 0; + color: var(--ifm-color-emphasis-700); + line-height: 1.75; +} + +.projectList { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; + margin-top: 27px; +} + +.projectList div { + display: flex; + align-items: center; + gap: 8px; + color: var(--ifm-color-emphasis-800); + font-size: 0.78rem; + font-weight: 700; +} + +.projectList svg { + color: var(--career-accent); +} + +.projectVisual { + display: flex; + justify-content: center; +} + +.eventCard { + width: min(100%, 380px); + padding: 25px; + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 18px; + background: var(--ifm-background-color); + box-shadow: 0 25px 65px rgb(0 0 0 / 10%); +} + +.eventTop { + display: flex; + align-items: center; + justify-content: space-between; + color: var(--career-accent); + font-size: 0.67rem; + font-weight: 850; + letter-spacing: 0.09em; +} + +.eventCard h3 { + margin: 25px 0 10px; + font-size: 1.35rem; + line-height: 1.2; +} + +.eventCard > p { + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.82rem; + line-height: 1.65; +} + +.eventMeta { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: 22px; +} + +.eventMeta span { + display: inline-flex; + align-items: center; + gap: 6px; + color: var(--ifm-color-emphasis-600); + font-size: 0.7rem; +} + +.eventButton { + display: flex; + align-items: center; + justify-content: center; + gap: 7px; + margin-top: 22px; + padding: 11px; + border-radius: 10px; + background: var(--career-accent); + color: white; + font-size: 0.75rem; + font-weight: 800; +} + +/* ========================================================= + OPEN SOURCE +========================================================= */ + +.openSourceCard { + display: grid; + grid-template-columns: auto 1fr; + gap: 22px; + padding: 42px; + border: 1px solid + color-mix(in srgb, var(--career-accent) 28%, var(--ifm-color-emphasis-200)); + border-radius: 24px; + background: + radial-gradient( + circle at 100% 0, + var(--career-accent-soft), + transparent 40% + ), + var(--ifm-background-surface-color); +} + +.openSourceIcon { + display: grid; + width: 52px; + height: 52px; + place-items: center; + border-radius: 14px; + background: var(--career-accent-soft); + color: var(--career-accent); +} + +.openSourceContent h2 { + margin: 11px 0 13px; + font-size: clamp(2rem, 4vw, 2.8rem); + line-height: 1.1; + letter-spacing: -0.04em; +} + +.openSourceContent p { + max-width: 720px; + margin: 0; + color: var(--ifm-color-emphasis-700); + line-height: 1.75; +} + +.openSourceActions { + display: flex; + flex-wrap: wrap; + gap: 11px; + margin-top: 25px; +} + +/* ========================================================= + FAQ +========================================================= */ + +.faqLayout { + display: grid; + grid-template-columns: 0.65fr 1fr; + gap: 80px; + align-items: start; +} + +.faqList { + border-top: 1px solid var(--ifm-color-emphasis-200); +} + +.faqItem { + border-bottom: 1px solid var(--ifm-color-emphasis-200); +} + +.faqButton { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + gap: 20px; + padding: 21px 0; + border: 0; + background: transparent; + color: var(--ifm-font-color-base); + text-align: left; + font: inherit; + font-size: 0.94rem; + font-weight: 750; + cursor: pointer; +} + +.chevron { + flex: 0 0 auto; + color: var(--ifm-color-emphasis-500); + transition: transform 180ms ease; +} + +.faqOpen .chevron { + color: var(--career-accent); + transform: rotate(180deg); +} + +.faqAnswer { + display: grid; + grid-template-rows: 0fr; + transition: grid-template-rows 220ms ease; +} + +.faqAnswer p { + overflow: hidden; + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.88rem; + line-height: 1.7; +} + +.faqOpen .faqAnswer { + grid-template-rows: 1fr; +} + +.faqOpen .faqAnswer p { + padding: 0 45px 22px 0; +} + +/* ========================================================= + FINAL CTA +========================================================= */ + +.application { + padding: 20px 0 110px; +} + +.applicationCard { + position: relative; + overflow: hidden; + padding: 70px 40px; + border: 1px solid + color-mix(in srgb, var(--career-accent) 30%, var(--ifm-color-emphasis-200)); + border-radius: 28px; + background: + radial-gradient( + circle at 85% 15%, + color-mix(in srgb, var(--career-accent) 18%, transparent), + transparent 35% + ), + var(--ifm-background-surface-color); + text-align: center; +} + +.applicationGlow { + position: absolute; + right: -170px; + bottom: -180px; + width: 340px; + height: 340px; + border-radius: 50%; + background: var(--career-accent); + opacity: 0.08; + filter: blur(60px); + pointer-events: none; +} + +.applicationIcon { + position: relative; + display: grid; + width: 58px; + height: 58px; + margin: 0 auto 24px; + place-items: center; + border: 1px solid + color-mix(in srgb, var(--career-accent) 30%, transparent); + border-radius: 17px; + background: var(--career-accent-soft); + color: var(--career-accent); +} + +.applicationCard h2 { + position: relative; + max-width: 820px; + margin: 12px auto 16px; + font-size: clamp(2.1rem, 5vw, 3.8rem); + line-height: 1.05; + letter-spacing: -0.045em; +} + +.applicationCard h2 span { + color: var(--career-accent); +} + +.applicationCard > p { + position: relative; + max-width: 660px; + margin: 0 auto; + color: var(--ifm-color-emphasis-700); + line-height: 1.75; +} + +.applicationActions { + position: relative; + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 12px; + margin-top: 30px; +} + +.applicationCard small { + position: relative; + display: block; + max-width: 690px; + margin: 22px auto 0; + color: var(--ifm-color-emphasis-600); + font-size: 0.76rem; + line-height: 1.6; +} + +/* ========================================================= + DARK MODE +========================================================= */ + +[data-theme="dark"] .hero { + background: + radial-gradient( + circle at 80% 30%, + color-mix(in srgb, var(--career-accent) 11%, transparent), + transparent 35% + ), + var(--ifm-background-color); +} + +[data-theme="dark"] .networkCard, +[data-theme="dark"] .eventCard { + box-shadow: 0 30px 80px rgb(0 0 0 / 35%); +} + +/* ========================================================= + RESPONSIVE +========================================================= */ + +@media (max-width: 1100px) { + .heroLayout { + grid-template-columns: 1fr; + gap: 55px; + } + + .heroContent { + max-width: 800px; + } + + .communityVisual { + width: 100%; + max-width: 620px; + justify-self: center; + } + + .pillarsGrid { + grid-template-columns: repeat(2, 1fr); + } + + .workflow { + grid-template-columns: repeat(2, 1fr); + } + + .workflowArrow { + display: none; + } +} + +@media (max-width: 800px) { + .container { + width: min(100% - 30px, 700px); + } + + .section { + padding: 75px 0; + } + + .hero { + padding: 35px 0 70px; + } + + .backLink { + margin-bottom: 42px; + } + + .heroContent h1 { + font-size: clamp(3rem, 14vw, 5rem); + } + + .heroLead { + font-size: 1rem; + } + + .twoColumn, + .faqLayout, + .projectCard { + grid-template-columns: 1fr; + } + + .impactPanel { + position: static; + } + + .summaryGrid { + grid-template-columns: repeat(2, 1fr); + } + + .summaryGrid > div, + .summaryGrid > div:first-child { + padding: 20px 15px; + border-right: 1px solid var(--ifm-color-emphasis-200); + } + + .summaryGrid > div:nth-child(2n) { + border-right: 0; + } + + .summaryGrid > div:nth-child(-n + 2) { + border-bottom: 1px solid var(--ifm-color-emphasis-200); + } + + .responsibilityGrid, + .requirementGrid { + grid-template-columns: 1fr; + } + + .projectCard { + padding: 40px 30px; + } +} + +@media (max-width: 560px) { + .container { + width: min(100% - 24px, 500px); + } + + .section { + padding: 60px 0; + } + + .heroContent h1 { + font-size: 3.15rem; + } + + .meta { + display: grid; + gap: 11px; + } + + .heroActions, + .openSourceActions, + .applicationActions { + display: grid; + grid-template-columns: 1fr; + } + + .primaryButton, + .secondaryButton { + width: 100%; + } + + .communityVisual { + min-height: 350px; + } + + .networkCard { + transform: none; + } + + .networkBody { + padding: 19px; + } + + .floatingBadge { + right: 2px; + bottom: 2px; + padding: 10px; + } + + .summaryGrid { + grid-template-columns: 1fr; + } + + .summaryGrid > div, + .summaryGrid > div:first-child { + padding: 16px 0; + border-right: 0; + border-bottom: 1px solid var(--ifm-color-emphasis-200); + } + + .summaryGrid > div:last-child { + border-bottom: 0; + } + + .requirementCard { + padding: 24px; + } + + .pillarsGrid, + .workflow { + grid-template-columns: 1fr; + } + + .pillarCard { + min-height: auto; + } + + .projectCard { + padding: 32px 22px; + } + + .projectList { + grid-template-columns: 1fr; + } + + .openSourceCard { + grid-template-columns: 1fr; + padding: 32px 22px; + } + + .application { + padding-bottom: 70px; + } + + .applicationCard { + padding: 48px 20px; + border-radius: 20px; + } + + .applicationCard h2 { + font-size: 2.25rem; + } +} + +@media (prefers-reduced-motion: reduce) { + .backLink, + .primaryButton, + .secondaryButton, + .workflowItem, + .chevron { + transition: none; + } +} \ No newline at end of file diff --git a/src/pages/careers/frontend-engineer/index.tsx b/src/pages/careers/frontend-engineer/index.tsx new file mode 100644 index 000000000..c52831813 --- /dev/null +++ b/src/pages/careers/frontend-engineer/index.tsx @@ -0,0 +1,681 @@ +import React, { useMemo, useState } from "react"; +import Layout from "@theme/Layout"; +import Link from "@docusaurus/Link"; +import { + ArrowLeft, + ArrowRight, + ArrowUpRight, + BriefcaseBusiness, + Check, + ChevronDown, + Code2, + ExternalLink, + Github, + Globe2, + Heart, + Laptop, + MapPin, + Rocket, + ShieldCheck, + Sparkles, + Users, + Zap, +} from "lucide-react"; + +import styles from "./styles.module.css"; + +type FAQ = { + question: string; + answer: string; +}; + +const responsibilities = [ + "Build and maintain polished, accessible, responsive interfaces for CodeHarborHub.", + "Develop reusable React and TypeScript components that can scale across the platform.", + "Translate product requirements, designs, and ideas into production-ready experiences.", + "Work closely with backend, content, community, and product contributors.", + "Improve frontend performance, Core Web Vitals, SEO, and overall user experience.", + "Write maintainable, testable, and well-documented frontend code.", + "Review pull requests and contribute constructive technical feedback.", + "Identify technical debt and continuously improve frontend architecture.", + "Build interactive learning experiences including roadmaps, practice systems, dashboards, and developer tools.", + "Contribute to open-source projects and help establish engineering standards.", +]; + +const requirements = [ + "Strong understanding of HTML, CSS, and modern JavaScript.", + "Practical experience with React and TypeScript.", + "Understanding of responsive design and accessibility.", + "Experience working with Git and GitHub-based workflows.", + "Ability to consume REST APIs and work with asynchronous data.", + "Understanding of component-based architecture and reusable UI patterns.", + "Ability to debug frontend issues independently.", + "Good understanding of browser fundamentals and web performance.", + "Ability to communicate technical ideas clearly.", + "A strong learning mindset and willingness to contribute in an open-source environment.", +]; + +const niceToHave = [ + "Experience with Next.js or Docusaurus.", + "Experience with Tailwind CSS or CSS Modules.", + "Experience with Framer Motion or other animation libraries.", + "Experience with Supabase or PostgreSQL-backed applications.", + "Knowledge of testing with Vitest, Jest, Playwright, or Cypress.", + "Experience with CI/CD and GitHub Actions.", + "Open-source contributions or experience maintaining public repositories.", + "Understanding of SEO, structured data, and Core Web Vitals.", +]; + +const techStack = [ + { + icon: Code2, + title: "Frontend", + items: ["React", "TypeScript", "JavaScript", "HTML", "CSS"], + }, + { + icon: Sparkles, + title: "UI & UX", + items: ["CSS Modules", "Tailwind CSS", "Responsive UI", "Accessibility"], + }, + { + icon: Github, + title: "Engineering", + items: ["Git", "GitHub", "Code Review", "CI/CD"], + }, + { + icon: Globe2, + title: "Platform", + items: ["Docusaurus", "Supabase", "REST APIs", "GitHub Pages"], + }, +]; + +const interviewProcess = [ + { + number: "01", + title: "Application review", + description: + "We review your application, projects, GitHub activity, and relevant experience.", + }, + { + number: "02", + title: "Intro conversation", + description: + "A short conversation about your background, interests, expectations, and why you want to work with us.", + }, + { + number: "03", + title: "Technical discussion", + description: + "We discuss frontend fundamentals, architecture, debugging, accessibility, performance, and real-world engineering decisions.", + }, + { + number: "04", + title: "Practical challenge", + description: + "You may be asked to solve a focused frontend problem or improve a small interface. We care about your approach, not just the final output.", + }, + { + number: "05", + title: "Team conversation", + description: + "Meet contributors and discuss collaboration, ownership, communication, and how you work in an open-source environment.", + }, + { + number: "06", + title: "Decision", + description: + "We share the next steps, expectations, and role details clearly.", + }, +]; + +const faqs: FAQ[] = [ + { + question: "Is this position remote?", + answer: + "The role is designed around remote collaboration. Final working arrangements depend on the specific opportunity and team requirements.", + }, + { + question: "Do I need professional experience?", + answer: + "Professional experience is valuable, but it is not the only signal we consider. Strong personal projects, internships, open-source contributions, and demonstrated problem-solving can also be meaningful.", + }, + { + question: "Can students apply?", + answer: + "Yes. If you can demonstrate strong frontend fundamentals and the ability to build real projects, you can apply. Internship opportunities may be a better fit depending on your experience level.", + }, + { + question: "Do I need to know every technology in the stack?", + answer: + "No. You should be strong in the core frontend technologies. Familiarity with the rest of the stack is helpful, but we expect engineers to learn new tools when needed.", + }, + { + question: "Do you consider open-source contributions?", + answer: + "Absolutely. Open-source contributions can demonstrate practical engineering ability, collaboration, communication, code quality, and ownership.", + }, + { + question: "What should I include in my application?", + answer: + "Include your resume or profile, GitHub profile, portfolio if available, relevant projects, and a short explanation of why this role interests you.", + }, +]; + +function SectionHeader({ + eyebrow, + title, + description, +}: { + eyebrow: string; + title: string; + description?: string; +}) { + return ( +
+ {eyebrow} +

{title}

+ {description &&

{description}

} +
+ ); +} + +export default function FrontendEngineerPage(): JSX.Element { + const [openFaq, setOpenFaq] = useState(0); + + const applicationUrl = useMemo( + () => "https://github.com/CodeHarborHub", + [], + ); + + return ( + +
+ {/* ───────────────── HERO ───────────────── */} +
+
+ +
+ + + Back to careers + + +
+
+
+ + Engineering · Open role +
+ +

+ Frontend + Engineer +

+ +

+ Build fast, accessible, beautiful experiences that help + millions of developers learn, practice, build, and grow. +

+ +
+ + + Remote + + + + + Full-time + + + + + Engineering + +
+ +
+ + Apply for this role + + + + + Explore the role + + +
+
+ +
+
+
+ + + + + frontend.tsx +
+ +
+

+ 01 + const platform = {"{"} +

+

+ 02 +   learn: true, +

+

+ 03 +   practice: true, +

+

+ 04 +   build: true, +

+

+ 05 +   openSource: true, +

+

+ 06 +   impact: "global", +

+

+ 07 + {"}"} +

+

+ 08▌ +

+
+
+ +
+ +
+ Build at scale + Real users. Real impact. +
+
+
+
+
+
+ + {/* ───────────────── QUICK SUMMARY ───────────────── */} +
+
+
+
+ Role + Frontend Engineer +
+ +
+ Level + Mid / Senior +
+ +
+ Work model + Remote-first +
+ +
+ Focus + Developer Education +
+
+
+
+ + {/* ───────────────── ROLE ───────────────── */} +
+
+
+
+ + +

+ As a Frontend Engineer, you will help turn that vision into + fast, accessible, reliable, and enjoyable products. You will + work on user-facing experiences where frontend engineering + directly affects how people learn. +

+ +

+ This is not a role where you only implement predefined + designs. You will have opportunities to influence component + architecture, interaction patterns, performance, developer + experience, and product decisions. +

+
+ +
+
+ +
+ + Your impact + +

+ Turn complex technology into simple learning experiences. +

+ +

+ From interactive tutorials to dashboards, roadmaps, + challenges, and developer tools — your work will directly + shape the learning experience. +

+ +
+
+ 01 + Product ownership +
+ +
+ + Learning opportunities +
+
+
+
+
+
+ + {/* ───────────────── RESPONSIBILITIES ───────────────── */} +
+
+ + +
+ {responsibilities.map((item, index) => ( +
+ {String(index + 1).padStart(2, "0")} +
+ +

{item}

+
+
+ ))} +
+
+
+ + {/* ───────────────── REQUIREMENTS ───────────────── */} +
+
+
+
+
+
+ +
+ +
+ Required +

What you should bring

+
+
+ +
    + {requirements.map((item) => ( +
  • + + {item} +
  • + ))} +
+
+ +
+
+
+ +
+ +
+ Bonus +

Great if you also have

+
+
+ +
    + {niceToHave.map((item) => ( +
  • + + {item} +
  • + ))} +
+
+
+
+
+ + {/* ───────────────── TECH STACK ───────────────── */} +
+
+ + +
+ {techStack.map((group) => { + const Icon = group.icon; + + return ( +
+
+ +
+ +

{group.title}

+ +
+ {group.items.map((item) => ( + {item} + ))} +
+
+ ); + })} +
+
+
+ + {/* ───────────────── WHAT WE VALUE ───────────────── */} +
+
+ + +
+
+ +

Think in systems

+

+ Build reusable solutions instead of solving the same problem + repeatedly. +

+
+ +
+ +

Care about users

+

+ Good engineering should make difficult technology easier to + understand and use. +

+
+ +
+ +

Build in the open

+

+ Share knowledge, review code, document decisions, and help + the community grow. +

+
+ +
+ +

Own your work

+

+ Take responsibility from the first idea through production + and continuous improvement. +

+
+
+
+
+ + {/* ───────────────── INTERVIEW ───────────────── */} +
+
+ + +
+ {interviewProcess.map((step, index) => ( +
+
{step.number}
+ +
+ {index !== interviewProcess.length - 1 && } +
+ +
+

{step.title}

+

{step.description}

+
+
+ ))} +
+
+
+ + {/* ───────────────── FAQ ───────────────── */} +
+
+
+ + +
+ {faqs.map((faq, index) => { + const isOpen = openFaq === index; + + return ( +
+ + +
+

{faq.answer}

+
+
+ ); + })} +
+
+
+
+ + {/* ───────────────── APPLICATION ───────────────── */} +
+
+
+
+ +
+ +
+ + Ready to build? + +

+ Your next commit could help + thousands of developers. +

+ +

+ If this role sounds like you, we'd love to see what you've + built. Show us your projects, your thinking, and what you want + to build next. +

+ +
+ + Apply for this role + + + + + View all opportunities + + +
+ + + Don't have a traditional resume? Your GitHub, portfolio, and + open-source work can tell us a lot. + +
+
+
+
+
+ ); +} \ No newline at end of file diff --git a/src/pages/careers/frontend-engineer/styles.module.css b/src/pages/careers/frontend-engineer/styles.module.css new file mode 100644 index 000000000..40250d532 --- /dev/null +++ b/src/pages/careers/frontend-engineer/styles.module.css @@ -0,0 +1,1188 @@ +.page { + --career-accent: var(--ifm-color-primary); + --career-accent-soft: color-mix( + in srgb, + var(--career-accent) 12%, + transparent + ); + + background: var(--ifm-background-color); + color: var(--ifm-font-color-base); +} + +/* ========================================================= + COMMON +========================================================= */ + +.container { + width: min(1180px, calc(100% - 40px)); + margin: 0 auto; +} + +.section { + position: relative; + padding: 100px 0; +} + +.sectionMuted { + background: + radial-gradient( + circle at 15% 20%, + var(--career-accent-soft), + transparent 30% + ), + var(--ifm-background-surface-color); +} + +.sectionHeader { + max-width: 760px; + margin-bottom: 48px; +} + +.sectionHeader h2 { + margin: 10px 0 14px; + font-size: clamp(2rem, 4vw, 3.35rem); + line-height: 1.08; + letter-spacing: -0.04em; +} + +.sectionHeader p { + max-width: 700px; + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 1.05rem; + line-height: 1.75; +} + +.eyebrow { + display: inline-flex; + align-items: center; + gap: 7px; + color: var(--career-accent); + font-size: 0.76rem; + font-weight: 800; + letter-spacing: 0.12em; + text-transform: uppercase; +} + +/* ========================================================= + HERO +========================================================= */ + +.hero { + position: relative; + overflow: hidden; + padding: 54px 0 92px; + border-bottom: 1px solid var(--ifm-color-emphasis-200); + background: + radial-gradient( + circle at 78% 35%, + color-mix(in srgb, var(--career-accent) 15%, transparent), + transparent 30% + ), + var(--ifm-background-color); +} + +.heroGrid { + position: absolute; + inset: 0; + opacity: 0.35; + pointer-events: none; + background-image: + linear-gradient( + to right, + var(--ifm-color-emphasis-200) 1px, + transparent 1px + ), + linear-gradient( + to bottom, + var(--ifm-color-emphasis-200) 1px, + transparent 1px + ); + background-size: 52px 52px; + mask-image: linear-gradient(to bottom, black, transparent 85%); +} + +.backLink { + position: relative; + z-index: 1; + display: inline-flex; + align-items: center; + gap: 8px; + margin-bottom: 58px; + color: var(--ifm-color-emphasis-700); + font-size: 0.92rem; + font-weight: 700; + text-decoration: none; + transition: + color 180ms ease, + transform 180ms ease; +} + +.backLink:hover { + color: var(--career-accent); + text-decoration: none; + transform: translateX(-3px); +} + +.heroLayout { + position: relative; + z-index: 1; + display: grid; + grid-template-columns: minmax(0, 1.1fr) minmax(380px, 0.9fr); + gap: 80px; + align-items: center; +} + +.badge { + display: inline-flex; + align-items: center; + gap: 9px; + padding: 7px 12px; + border: 1px solid color-mix(in srgb, var(--career-accent) 28%, transparent); + border-radius: 999px; + background: var(--career-accent-soft); + color: var(--career-accent); + font-size: 0.78rem; + font-weight: 800; +} + +.badgeDot { + width: 7px; + height: 7px; + border-radius: 50%; + background: currentColor; + box-shadow: 0 0 0 4px + color-mix(in srgb, var(--career-accent) 15%, transparent); +} + +.heroContent h1 { + max-width: 780px; + margin: 24px 0 22px; + font-size: clamp(3.5rem, 7vw, 6.5rem); + line-height: 0.92; + letter-spacing: -0.065em; +} + +.heroContent h1 span { + display: block; + color: var(--career-accent); +} + +.heroLead { + max-width: 690px; + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: clamp(1.05rem, 2vw, 1.28rem); + line-height: 1.75; +} + +.meta { + display: flex; + flex-wrap: wrap; + gap: 20px; + margin-top: 28px; +} + +.meta span { + display: inline-flex; + align-items: center; + gap: 8px; + color: var(--ifm-color-emphasis-700); + font-size: 0.92rem; + font-weight: 700; +} + +.meta svg { + color: var(--career-accent); +} + +.heroActions { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: 34px; +} + +.primaryButton, +.secondaryButton { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 9px; + min-height: 48px; + padding: 0 18px; + border-radius: 12px; + font-size: 0.92rem; + font-weight: 800; + text-decoration: none; + transition: + transform 180ms ease, + box-shadow 180ms ease, + background 180ms ease, + border-color 180ms ease; +} + +.primaryButton { + border: 1px solid var(--career-accent); + background: var(--career-accent); + color: white; + box-shadow: 0 12px 28px + color-mix(in srgb, var(--career-accent) 22%, transparent); +} + +.primaryButton:hover { + color: white; + text-decoration: none; + transform: translateY(-2px); + box-shadow: 0 16px 36px + color-mix(in srgb, var(--career-accent) 30%, transparent); +} + +.secondaryButton { + border: 1px solid var(--ifm-color-emphasis-300); + background: var(--ifm-background-surface-color); + color: var(--ifm-font-color-base); +} + +.secondaryButton:hover { + color: var(--ifm-font-color-base); + text-decoration: none; + border-color: var(--career-accent); + transform: translateY(-2px); +} + +/* ========================================================= + CODE WINDOW +========================================================= */ + +.heroVisual { + position: relative; + min-height: 430px; + display: grid; + place-items: center; +} + +.codeWindow { + width: min(100%, 510px); + overflow: hidden; + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 18px; + background: color-mix( + in srgb, + var(--ifm-background-surface-color) 95%, + black + ); + box-shadow: + 0 30px 80px rgb(0 0 0 / 16%), + 0 0 0 1px rgb(255 255 255 / 2%); + transform: perspective(1000px) rotateY(-5deg) rotateX(2deg); +} + +.windowBar { + display: flex; + align-items: center; + gap: 7px; + padding: 13px 15px; + border-bottom: 1px solid var(--ifm-color-emphasis-200); + background: var(--ifm-background-surface-color); +} + +.windowBar > span { + width: 9px; + height: 9px; + border-radius: 50%; + background: var(--ifm-color-emphasis-400); +} + +.windowBar small { + margin-left: 8px; + color: var(--ifm-color-emphasis-600); + font-family: var(--ifm-font-family-monospace); +} + +.codeBody { + padding: 26px 22px 30px; + font-family: var(--ifm-font-family-monospace); + font-size: 0.88rem; + line-height: 2; +} + +.codeBody p { + margin: 0; + color: var(--ifm-color-emphasis-700); +} + +.codeBody i { + display: inline-block; + width: 30px; + margin-right: 12px; + color: var(--ifm-color-emphasis-400); + font-style: normal; + user-select: none; +} + +.codeBody b { + color: var(--career-accent); +} + +.codeBody em { + color: #e58e2f; + font-style: normal; +} + +.codeCursor { + color: var(--career-accent) !important; +} + +.floatingCard { + position: absolute; + right: -10px; + bottom: 28px; + display: flex; + align-items: center; + gap: 12px; + padding: 13px 15px; + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 14px; + background: color-mix( + in srgb, + var(--ifm-background-surface-color) 96%, + transparent + ); + box-shadow: 0 18px 45px rgb(0 0 0 / 15%); + backdrop-filter: blur(14px); +} + +.floatingCard > svg { + color: var(--career-accent); +} + +.floatingCard div { + display: grid; + gap: 2px; +} + +.floatingCard strong { + font-size: 0.85rem; +} + +.floatingCard span { + color: var(--ifm-color-emphasis-600); + font-size: 0.72rem; +} + +/* ========================================================= + SUMMARY +========================================================= */ + +.summary { + border-bottom: 1px solid var(--ifm-color-emphasis-200); + background: var(--ifm-background-surface-color); +} + +.summaryGrid { + display: grid; + grid-template-columns: repeat(4, 1fr); +} + +.summaryGrid > div { + display: grid; + gap: 6px; + padding: 24px; + border-right: 1px solid var(--ifm-color-emphasis-200); +} + +.summaryGrid > div:first-child { + padding-left: 0; +} + +.summaryGrid > div:last-child { + border-right: 0; +} + +.summaryGrid span { + color: var(--ifm-color-emphasis-600); + font-size: 0.72rem; + font-weight: 800; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.summaryGrid strong { + font-size: 0.95rem; +} + +/* ========================================================= + ROLE +========================================================= */ + +.twoColumn { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(320px, 0.7fr); + gap: 80px; + align-items: start; +} + +.bodyText { + max-width: 760px; + margin: 0 0 18px; + color: var(--ifm-color-emphasis-700); + font-size: 1rem; + line-height: 1.8; +} + +.highlightPanel { + position: sticky; + top: 110px; + padding: 32px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 22px; + background: + radial-gradient( + circle at 100% 0, + var(--career-accent-soft), + transparent 45% + ), + var(--ifm-background-surface-color); + box-shadow: 0 20px 60px rgb(0 0 0 / 7%); +} + +.panelIcon { + display: grid; + width: 48px; + height: 48px; + margin-bottom: 28px; + place-items: center; + border-radius: 14px; + background: var(--career-accent-soft); + color: var(--career-accent); +} + +.panelEyebrow { + color: var(--ifm-color-emphasis-600); + font-size: 0.72rem; + font-weight: 800; + letter-spacing: 0.1em; + text-transform: uppercase; +} + +.highlightPanel h3 { + margin: 10px 0 14px; + font-size: 1.55rem; + line-height: 1.25; + letter-spacing: -0.025em; +} + +.highlightPanel > p { + margin: 0; + color: var(--ifm-color-emphasis-700); + line-height: 1.7; +} + +.panelStats { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; + margin-top: 28px; +} + +.panelStats > div { + padding: 15px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 12px; + background: var(--ifm-background-color); +} + +.panelStats strong, +.panelStats span { + display: block; +} + +.panelStats strong { + margin-bottom: 4px; + color: var(--career-accent); + font-size: 1.35rem; +} + +.panelStats span { + color: var(--ifm-color-emphasis-600); + font-size: 0.72rem; +} + +/* ========================================================= + RESPONSIBILITIES +========================================================= */ + +.responsibilityGrid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 0 28px; + border-top: 1px solid var(--ifm-color-emphasis-200); +} + +.checkItem { + display: grid; + grid-template-columns: 38px 1fr; + gap: 14px; + padding: 22px 0; + border-bottom: 1px solid var(--ifm-color-emphasis-200); +} + +.checkItem > span { + padding-top: 2px; + color: var(--career-accent); + font-family: var(--ifm-font-family-monospace); + font-size: 0.72rem; + font-weight: 800; +} + +.checkItem > div { + display: flex; + gap: 10px; +} + +.checkItem svg { + flex: 0 0 auto; + margin-top: 3px; + color: var(--career-accent); +} + +.checkItem p { + margin: 0; + color: var(--ifm-color-emphasis-800); + font-size: 0.94rem; + line-height: 1.65; +} + +/* ========================================================= + REQUIREMENTS +========================================================= */ + +.requirementCard { + padding: 32px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 20px; + background: var(--ifm-background-surface-color); +} + +.cardHeader { + display: flex; + align-items: center; + gap: 14px; + margin-bottom: 28px; +} + +.cardIcon { + display: grid; + width: 46px; + height: 46px; + flex: 0 0 auto; + place-items: center; + border-radius: 13px; + background: var(--career-accent-soft); + color: var(--career-accent); +} + +.cardHeader span { + display: block; + margin-bottom: 3px; + color: var(--career-accent); + font-size: 0.7rem; + font-weight: 800; + letter-spacing: 0.1em; + text-transform: uppercase; +} + +.cardHeader h3 { + margin: 0; + font-size: 1.15rem; +} + +.requirementList { + display: grid; + gap: 15px; + padding: 0; + margin: 0; + list-style: none; +} + +.requirementList li { + display: flex; + gap: 10px; + color: var(--ifm-color-emphasis-700); + font-size: 0.9rem; + line-height: 1.6; +} + +.requirementList svg { + flex: 0 0 auto; + margin-top: 3px; + color: var(--career-accent); +} + +/* ========================================================= + STACK +========================================================= */ + +.stackGrid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 16px; +} + +.stackCard { + padding: 25px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 17px; + background: var(--ifm-background-color); + transition: + transform 180ms ease, + border-color 180ms ease, + box-shadow 180ms ease; +} + +.stackCard:hover { + border-color: color-mix(in srgb, var(--career-accent) 45%, transparent); + transform: translateY(-4px); + box-shadow: 0 18px 40px rgb(0 0 0 / 8%); +} + +.stackIcon { + display: grid; + width: 42px; + height: 42px; + margin-bottom: 20px; + place-items: center; + border-radius: 12px; + background: var(--career-accent-soft); + color: var(--career-accent); +} + +.stackCard h3 { + margin: 0 0 14px; + font-size: 1rem; +} + +.tagList { + display: flex; + flex-wrap: wrap; + gap: 7px; +} + +.tagList span { + padding: 5px 8px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 7px; + color: var(--ifm-color-emphasis-700); + font-family: var(--ifm-font-family-monospace); + font-size: 0.67rem; +} + +/* ========================================================= + VALUES +========================================================= */ + +.valuesGrid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 1px; + overflow: hidden; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 20px; + background: var(--ifm-color-emphasis-200); +} + +.valuesGrid article { + padding: 30px; + background: var(--ifm-background-color); +} + +.valuesGrid article > svg { + margin-bottom: 25px; + color: var(--career-accent); +} + +.valuesGrid h3 { + margin: 0 0 9px; + font-size: 1.05rem; +} + +.valuesGrid p { + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.87rem; + line-height: 1.7; +} + +/* ========================================================= + PROCESS +========================================================= */ + +.process { + max-width: 900px; +} + +.processItem { + display: grid; + grid-template-columns: 52px 30px 1fr; + min-height: 125px; +} + +.processNumber { + display: grid; + width: 42px; + height: 42px; + place-items: center; + border: 1px solid color-mix(in srgb, var(--career-accent) 35%, transparent); + border-radius: 50%; + background: var(--career-accent-soft); + color: var(--career-accent); + font-family: var(--ifm-font-family-monospace); + font-size: 0.72rem; + font-weight: 800; +} + +.processLine { + position: relative; +} + +.processLine span { + position: absolute; + top: 42px; + left: 20px; + width: 1px; + height: calc(100% - 42px); + background: var(--ifm-color-emphasis-300); +} + +.processContent { + padding: 0 0 36px; +} + +.processContent h3 { + margin: 7px 0 8px; + font-size: 1.1rem; +} + +.processContent p { + max-width: 680px; + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.9rem; + line-height: 1.7; +} + +/* ========================================================= + FAQ +========================================================= */ + +.faqLayout { + display: grid; + grid-template-columns: 0.65fr 1fr; + gap: 80px; + align-items: start; +} + +.faqList { + border-top: 1px solid var(--ifm-color-emphasis-200); +} + +.faqItem { + border-bottom: 1px solid var(--ifm-color-emphasis-200); +} + +.faqButton { + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + gap: 20px; + padding: 21px 0; + border: 0; + background: transparent; + color: var(--ifm-font-color-base); + text-align: left; + font: inherit; + font-size: 0.95rem; + font-weight: 750; + cursor: pointer; +} + +.chevron { + flex: 0 0 auto; + color: var(--ifm-color-emphasis-500); + transition: transform 180ms ease; +} + +.faqOpen .chevron { + transform: rotate(180deg); + color: var(--career-accent); +} + +.faqAnswer { + display: grid; + grid-template-rows: 0fr; + transition: grid-template-rows 220ms ease; +} + +.faqAnswer p { + overflow: hidden; + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.9rem; + line-height: 1.7; +} + +.faqOpen .faqAnswer { + grid-template-rows: 1fr; +} + +.faqOpen .faqAnswer p { + padding: 0 45px 22px 0; +} + +/* ========================================================= + APPLICATION CTA +========================================================= */ + +.application { + padding: 20px 0 110px; +} + +.applicationCard { + position: relative; + overflow: hidden; + padding: 70px 40px; + border: 1px solid + color-mix(in srgb, var(--career-accent) 30%, var(--ifm-color-emphasis-200)); + border-radius: 28px; + background: + radial-gradient( + circle at 85% 15%, + color-mix(in srgb, var(--career-accent) 18%, transparent), + transparent 35% + ), + var(--ifm-background-surface-color); + text-align: center; +} + +.applicationGlow { + position: absolute; + width: 320px; + height: 320px; + right: -160px; + bottom: -180px; + border-radius: 50%; + background: var(--career-accent); + opacity: 0.08; + filter: blur(60px); + pointer-events: none; +} + +.applicationIcon { + display: grid; + width: 58px; + height: 58px; + margin: 0 auto 24px; + place-items: center; + border: 1px solid + color-mix(in srgb, var(--career-accent) 30%, transparent); + border-radius: 17px; + background: var(--career-accent-soft); + color: var(--career-accent); +} + +.applicationCard h2 { + position: relative; + max-width: 750px; + margin: 12px auto 16px; + font-size: clamp(2.1rem, 5vw, 3.8rem); + line-height: 1.05; + letter-spacing: -0.045em; +} + +.applicationCard h2 span { + color: var(--career-accent); +} + +.applicationCard > p { + position: relative; + max-width: 650px; + margin: 0 auto; + color: var(--ifm-color-emphasis-700); + line-height: 1.75; +} + +.applicationActions { + position: relative; + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 12px; + margin-top: 30px; +} + +.applicationCard small { + position: relative; + display: block; + max-width: 650px; + margin: 22px auto 0; + color: var(--ifm-color-emphasis-600); + font-size: 0.76rem; + line-height: 1.6; +} + +/* ========================================================= + DARK MODE +========================================================= */ + +[data-theme="dark"] .hero { + background: + radial-gradient( + circle at 78% 35%, + color-mix(in srgb, var(--career-accent) 12%, transparent), + transparent 32% + ), + var(--ifm-background-color); +} + +[data-theme="dark"] .codeWindow { + background: #0b1118; + box-shadow: + 0 30px 90px rgb(0 0 0 / 40%), + 0 0 0 1px rgb(255 255 255 / 3%); +} + +[data-theme="dark"] .stackCard:hover, +[data-theme="dark"] .highlightPanel { + box-shadow: 0 22px 60px rgb(0 0 0 / 25%); +} + +/* ========================================================= + RESPONSIVE +========================================================= */ + +@media (max-width: 1100px) { + .heroLayout { + grid-template-columns: 1fr; + gap: 55px; + } + + .heroContent { + max-width: 800px; + } + + .heroVisual { + max-width: 620px; + justify-self: center; + width: 100%; + } + + .stackGrid, + .valuesGrid { + grid-template-columns: repeat(2, 1fr); + } + + .twoColumn, + .faqLayout { + gap: 45px; + } +} + +@media (max-width: 800px) { + .section { + padding: 75px 0; + } + + .container { + width: min(100% - 30px, 700px); + } + + .hero { + padding: 35px 0 70px; + } + + .backLink { + margin-bottom: 42px; + } + + .heroContent h1 { + font-size: clamp(3rem, 14vw, 5rem); + } + + .heroVisual { + min-height: 350px; + } + + .codeWindow { + transform: none; + } + + .floatingCard { + right: 0; + } + + .summaryGrid { + grid-template-columns: repeat(2, 1fr); + } + + .summaryGrid > div, + .summaryGrid > div:first-child { + padding: 20px 15px; + border-right: 1px solid var(--ifm-color-emphasis-200); + } + + .summaryGrid > div:nth-child(2n) { + border-right: 0; + } + + .summaryGrid > div:nth-child(-n + 2) { + border-bottom: 1px solid var(--ifm-color-emphasis-200); + } + + .twoColumn, + .faqLayout { + grid-template-columns: 1fr; + } + + .highlightPanel { + position: static; + } + + .responsibilityGrid { + grid-template-columns: 1fr; + } + + .stackGrid, + .valuesGrid { + grid-template-columns: 1fr 1fr; + } +} + +@media (max-width: 560px) { + .container { + width: min(100% - 24px, 500px); + } + + .section { + padding: 60px 0; + } + + .hero { + padding-bottom: 55px; + } + + .heroContent h1 { + font-size: 3.15rem; + } + + .heroLead { + font-size: 1rem; + } + + .meta { + display: grid; + gap: 11px; + } + + .heroActions, + .applicationActions { + display: grid; + grid-template-columns: 1fr; + } + + .primaryButton, + .secondaryButton { + width: 100%; + } + + .heroVisual { + min-height: 300px; + } + + .codeBody { + padding: 20px 14px; + font-size: 0.7rem; + } + + .codeBody i { + width: 24px; + margin-right: 7px; + } + + .floatingCard { + right: 4px; + bottom: 5px; + padding: 10px; + } + + .floatingCard span { + display: none; + } + + .summaryGrid { + grid-template-columns: 1fr; + } + + .summaryGrid > div, + .summaryGrid > div:first-child { + padding: 16px 0; + border-right: 0; + border-bottom: 1px solid var(--ifm-color-emphasis-200); + } + + .summaryGrid > div:last-child { + border-bottom: 0; + } + + .requirementCard, + .highlightPanel { + padding: 23px; + } + + .stackGrid, + .valuesGrid { + grid-template-columns: 1fr; + } + + .valuesGrid { + border-radius: 16px; + } + + .processItem { + grid-template-columns: 44px 20px 1fr; + } + + .processNumber { + width: 38px; + height: 38px; + } + + .processLine span { + left: 18px; + } + + .application { + padding-bottom: 70px; + } + + .applicationCard { + padding: 48px 20px; + border-radius: 20px; + } + + .applicationCard h2 { + font-size: 2.25rem; + } +} + +@media (prefers-reduced-motion: reduce) { + .primaryButton, + .secondaryButton, + .backLink, + .stackCard, + .chevron { + transition: none; + } +} \ No newline at end of file diff --git a/src/pages/careers/frontend-intern/index.tsx b/src/pages/careers/frontend-intern/index.tsx new file mode 100644 index 000000000..a0ae193b2 --- /dev/null +++ b/src/pages/careers/frontend-intern/index.tsx @@ -0,0 +1,1016 @@ +import React, { useMemo, useState } from "react"; +// @ts-ignore +import Layout from "@theme/Layout"; +// @ts-ignore +import Link from "@docusaurus/Link"; +import { + ArrowRight, + ArrowUpRight, + Award, + BookOpen, + BriefcaseBusiness, + Check, + ChevronDown, + Code2, + FileCode2, + GitBranch, + Github, + Globe, + Layers3, + Monitor, + Palette, + Rocket, + Search, + ShieldCheck, + Sparkles, + Target, + Terminal, + TestTube2, + Users, + X, + Zap, +} from "lucide-react"; +// @ts-ignore +import styles from "./styles.module.css"; + +type Skill = { + icon: React.ReactNode; + title: string; + description: string; + topics: string[]; +}; + +type Phase = { + number: string; + title: string; + description: string; + skills: string[]; + duration: string; +}; + +const SKILLS: Skill[] = [ + { + icon: , + title: "HTML & Web Foundations", + description: + "Build accessible, semantic page structures and understand how browsers render web pages.", + topics: ["HTML5", "Semantic HTML", "Forms", "SEO", "Accessibility"], + }, + { + icon: , + title: "CSS & Responsive UI", + description: + "Create responsive interfaces that work across mobile, tablet, and desktop devices.", + topics: ["CSS3", "Flexbox", "Grid", "Responsive Design", "Animations"], + }, + { + icon: , + title: "JavaScript", + description: + "Understand modern JavaScript and use it to build interactive browser experiences.", + topics: ["ES6+", "DOM", "Async JS", "APIs", "Modules"], + }, + { + icon: , + title: "React & TypeScript", + description: + "Build maintainable component-based applications using modern frontend tooling.", + topics: ["React", "TypeScript", "Hooks", "State", "Components"], + }, + { + icon: , + title: "Git & Collaboration", + description: + "Learn the workflow used to work safely with branches, pull requests, and code reviews.", + topics: ["Git", "GitHub", "Branches", "PRs", "Code Review"], + }, + { + icon: , + title: "Testing & Quality", + description: + "Develop the habit of validating frontend applications before shipping changes.", + topics: ["Testing", "Debugging", "Linting", "Performance", "QA"], + }, +]; + +const PHASES: Phase[] = [ + { + number: "01", + title: "Web Foundations", + description: + "Understand the browser, HTTP basics, HTML document structure, semantic markup, and accessibility.", + skills: ["HTML5", "HTTP", "Browser Basics", "Accessibility"], + duration: "Foundation", + }, + { + number: "02", + title: "CSS & Responsive Design", + description: + "Learn layout systems, responsive patterns, reusable styling, visual hierarchy, and modern CSS.", + skills: ["CSS", "Flexbox", "Grid", "Responsive UI"], + duration: "Foundation", + }, + { + number: "03", + title: "JavaScript Engineering", + description: + "Move from basic syntax to DOM manipulation, asynchronous programming, APIs, modules, and debugging.", + skills: ["JavaScript", "DOM", "Fetch", "Async/Await"], + duration: "Core", + }, + { + number: "04", + title: "Modern Frontend", + description: + "Build component-driven applications with React, TypeScript, state management, routing, and reusable UI.", + skills: ["React", "TypeScript", "Hooks", "Routing"], + duration: "Core", + }, + { + number: "05", + title: "Production Skills", + description: + "Learn the engineering practices required to move beyond tutorials and build maintainable applications.", + skills: ["Testing", "Performance", "Security", "Accessibility"], + duration: "Professional", + }, + { + number: "06", + title: "Portfolio & Interview", + description: + "Build projects, document technical decisions, practice frontend questions, and prepare your career portfolio.", + skills: ["Projects", "GitHub", "Portfolio", "Interviews"], + duration: "Career", + }, +]; + +const FAQS = [ + { + question: "What should I know before starting a frontend internship path?", + answer: + "You do not need to know everything. Basic computer usage, HTML, CSS, and some JavaScript are a useful starting point. The roadmap is designed to progressively develop the rest of the skills.", + }, + { + question: "Is React enough to become a frontend developer?", + answer: + "React is only one part of frontend development. A strong foundation also includes HTML, CSS, JavaScript, accessibility, browser fundamentals, Git, APIs, testing, performance, and the ability to build and maintain complete interfaces.", + }, + { + question: "How many projects should I build?", + answer: + "Focus on meaningful projects rather than a specific number. A small set of well-documented projects that demonstrate different skills can be more useful than many unfinished tutorial projects.", + }, + { + question: "Should I learn TypeScript before React?", + answer: + "You can learn React with JavaScript first and then introduce TypeScript, or use TypeScript while learning React if you already understand JavaScript fundamentals. The important part is understanding JavaScript before relying on TypeScript.", + }, + { + question: "What should my frontend portfolio contain?", + answer: + "Include selected projects, live demos where possible, source code, your role, technical decisions, challenges, screenshots, and what you learned. Keep the portfolio focused on evidence rather than a long list of technologies.", + }, + { + question: "Does completing this page guarantee an internship?", + answer: + "No. Learning resources and projects can help you develop and demonstrate skills, but internships and jobs depend on many factors including your actual ability, application quality, interview performance, company requirements, and available opportunities.", + }, +]; + +function SectionHeading({ + eyebrow, + title, + description, +}: { + eyebrow: string; + title: string; + description?: string; +}) { + return ( +
+ + + {eyebrow} + + +

{title}

+ + {description &&

{description}

} +
+ ); +} + +function SkillCard({ skill }: { skill: Skill }) { + return ( +
+
{skill.icon}
+ +

{skill.title}

+

{skill.description}

+ +
+ {skill.topics.map((topic) => ( + {topic} + ))} +
+
+ ); +} + +function PhaseCard({ phase }: { phase: Phase }) { + return ( +
+
+ {phase.number} + {phase.duration} +
+ +

{phase.title}

+

{phase.description}

+ +
+ {phase.skills.map((skill) => ( + + + {skill} + + ))} +
+
+ ); +} + +export default function FrontendInternPage(): JSX.Element { + const [search, setSearch] = useState(""); + const [openFaq, setOpenFaq] = useState(0); + + const filteredSkills = useMemo(() => { + const query = search.trim().toLowerCase(); + + if (!query) { + return SKILLS; + } + + return SKILLS.filter((skill) => + [skill.title, skill.description, ...skill.topics] + .join(" ") + .toLowerCase() + .includes(query), + ); + }, [search]); + + return ( + +
+ {/* ===================================================== + HERO + ===================================================== */} +
+
+
+ +
+
+
+ + + Frontend Developer Career Path +
+ +

+ Prepare to build + real interfaces. +

+ +

+ A practical path for aspiring frontend interns and junior + developers — from HTML and CSS fundamentals to JavaScript, + React, TypeScript, Git, testing, production UI, and portfolio + projects. +

+ +
+ + Start the Roadmap + + + + + Explore Projects + + +
+ +
+ + + Beginner friendly + + + + Project focused + + + + Interview oriented + +
+
+ +
+
+
+
+ + + +
+ +
+ + frontend-project.local +
+ + +
+ +
+
+
+ + dev +
+ +
+ + + +
+
+ +
+
+ + + +
+
+ +
+ + + +
+
+ +
+
+
+
+
+
+
+ +
+ +
+ React + TypeScript + Production UI +
+
+ +
+ +
+ Build → Test → Ship + Engineering workflow +
+
+
+
+
+ + {/* ===================================================== + WHAT COMPANIES EXPECT + ===================================================== */} +
+
+
+
+ + + What to prepare for + + +

+ Frontend is more than + writing JSX. +

+ +

+ A practical frontend developer needs to understand the + browser, create accessible interfaces, work with APIs, + collaborate through Git, debug problems, and ship reliable + software. +

+
+ +
+
+ + UI Engineering + Responsive and reusable interfaces. +
+ +
+ + Programming + Strong JavaScript fundamentals. +
+ +
+ + Collaboration + Git, GitHub, branches, and pull requests. +
+ +
+ + Quality + Accessibility, security, testing, and performance. +
+
+
+
+
+ + {/* ===================================================== + SKILLS + ===================================================== */} +
+
+ + +
+
+ + + setSearch(event.target.value)} + placeholder="Search skills..." + aria-label="Search frontend skills" + /> + + {search && ( + + )} +
+ + {filteredSkills.length} skill areas +
+ + {filteredSkills.length > 0 ? ( +
+ {filteredSkills.map((skill) => ( + + ))} +
+ ) : ( +
+ + No matching skill found + Try React, JavaScript, CSS, Git, or another keyword. +
+ )} +
+
+ + {/* ===================================================== + ROADMAP + ===================================================== */} +
+
+ + +
+ {PHASES.map((phase) => ( + + ))} +
+
+
+ + {/* ===================================================== + PROJECTS + ===================================================== */} +
+
+
+
+
+
+ + + +
+ + portfolio-project + + +
+ +
+
+ 01 + const{" "} + project = {"{"} +
+ +
+ 02 +   name:{" "} + + "Analytics Dashboard" + +
+ +
+ 03 +   stack:{" "} + + "React + TypeScript" + +
+ +
+ 04 +   responsive:{" "} + true +
+ +
+ 05 +   tested:{" "} + true +
+ +
+ 06 +   deployed:{" "} + true +
+ +
+ 07 + {"}"}; +
+
+
+ +
+ + + Project-first learning + + +

+ Build projects that + demonstrate your skills. +

+ +

+ Avoid building only tutorial clones. Create projects where + you have to make decisions about component architecture, + responsive behavior, state, APIs, error handling, + accessibility, performance, and deployment. +

+ +
+
+ + Responsive UI +
+ +
+ + Reusable components +
+ +
+ + API integration +
+ +
+ + Loading & error states +
+ +
+ + Accessibility +
+ +
+ + Deployment +
+
+ + + Explore frontend projects + + +
+
+
+
+ + {/* ===================================================== + WORKFLOW + ===================================================== */} +
+
+ + +
+
+ + Understand + Read the requirement. +
+ + + +
+ + Plan + Break down the work. +
+ + + +
+ + Build + Implement the solution. +
+ + + +
+ + Test + Validate behavior. +
+ + + +
+ + Review + Get feedback. +
+ + + +
+ + Ship + Deploy & document. +
+
+
+
+ + {/* ===================================================== + INTERNSHIP READINESS + ===================================================== */} +
+
+
+
+ + + Internship readiness + + +

+ Know what evidence + you can show. +

+ +

+ Before applying, review whether you can demonstrate these + skills through actual work rather than only certificates. +

+ +
+
+ + Build a responsive application from scratch. +
+ +
+ + Consume and handle data from an API. +
+ +
+ + Use Git branches and create pull requests. +
+ +
+ + Debug a frontend issue systematically. +
+ +
+ + Explain your component and state architecture. +
+ +
+ + Deploy a project and document it clearly. +
+
+
+ +
+
+ Frontend readiness + CHECKLIST +
+ +
+
+ HTML / CSS + Core +
+
+ +
+
+ +
+
+ JavaScript + Core +
+
+ +
+
+ +
+
+ React + Core +
+
+ +
+
+ +
+
+ Git / GitHub + Required +
+
+ +
+
+ +
+
+ Testing / Quality + Professional +
+
+ +
+
+ +
+ + + Use this as a learning checklist, not as an employment + score. + +
+
+
+
+
+ + {/* ===================================================== + PORTFOLIO + ===================================================== */} +
+
+
+
+
+
FE
+ +
+ Frontend Developer + Portfolio snapshot +
+ + +
+ +
+ FEATURED PROJECT + Developer Analytics Dashboard + +
+ React + TypeScript + API +
+
+ +
+
+ Live + Demo +
+ +
+ Public + Source +
+ +
+ Clean + README +
+
+
+ +
+ + + Career evidence + + +

+ Make your portfolio tell a + technical story. +

+ +

+ A strong project description should make it easy to + understand the problem, your role, architecture, technology + choices, challenges, testing approach, and final result. +

+ + + Build portfolio projects + + +
+
+
+
+ + {/* ===================================================== + FAQ + ===================================================== */} +
+
+ + +
+ {FAQS.map((faq, index) => { + const isOpen = openFaq === index; + + return ( +
+ + +
+

{faq.answer}

+
+
+ ); + })} +
+
+
+ + {/* ===================================================== + FINAL CTA + ===================================================== */} +
+
+ +
+
+
+ +
+ + + + Start building + + +

+ Your frontend journey + starts with one project. +

+ +

+ Learn the fundamentals, build real interfaces, practice + engineering workflows, and keep improving through meaningful + projects. +

+ +
+ + Start with HTML + + + + + Explore Projects + + +
+ +
+ + Learn → Practice → Build → Review → Showcase +
+
+
+
+
+
+ ); +} \ No newline at end of file diff --git a/src/pages/careers/frontend-intern/styles.module.css b/src/pages/careers/frontend-intern/styles.module.css new file mode 100644 index 000000000..6c698d551 --- /dev/null +++ b/src/pages/careers/frontend-intern/styles.module.css @@ -0,0 +1,1489 @@ +.page { + --career-border: var(--ifm-color-emphasis-200); + --career-border-strong: var(--ifm-color-emphasis-300); + --career-muted: var(--ifm-color-emphasis-700); + --career-soft: var(--ifm-color-emphasis-100); + --career-card: var(--ifm-background-surface-color); + --career-primary: var(--ifm-color-primary); + --career-primary-dark: var(--ifm-color-primary-dark); + overflow: hidden; +} + +.container { + width: min(1180px, calc(100% - 40px)); + margin: 0 auto; +} + +.containerNarrow { + width: min(850px, calc(100% - 40px)); + margin: 0 auto; +} + +/* ========================================================= + SHARED + ========================================================= */ + +.section { + position: relative; + padding: 110px 0; +} + +.sectionHeading { + max-width: 780px; + margin: 0 auto 55px; + text-align: center; +} + +.sectionHeading h2, +.expectIntro h2, +.projectContent h2, +.readinessContent h2, +.portfolioContent h2 { + margin: 16px 0; + color: var(--ifm-heading-color); + font-size: clamp(2rem, 4vw, 3.25rem); + line-height: 1.08; + letter-spacing: -0.045em; +} + +.sectionHeading p, +.expectIntro p, +.projectContent > p, +.readinessContent > p, +.portfolioContent > p { + margin: 0; + color: var(--career-muted); + font-size: 1rem; + line-height: 1.8; +} + +.eyebrow { + display: inline-flex; + align-items: center; + gap: 7px; + color: var(--career-primary); + font-size: 0.75rem; + font-weight: 850; + letter-spacing: 0.11em; + text-transform: uppercase; +} + +.sectionHeading h2 span, +.expectIntro h2 span, +.projectContent h2 span, +.readinessContent h2 span, +.portfolioContent h2 span { + color: var(--career-primary); +} + +/* ========================================================= + HERO + ========================================================= */ + +.hero { + position: relative; + display: flex; + align-items: center; + padding: 3rem 0 2rem; + isolation: isolate; + background: + radial-gradient( + circle at 15% 30%, + color-mix(in srgb, var(--career-primary) 14%, transparent), + transparent 36% + ), + radial-gradient( + circle at 90% 65%, + color-mix(in srgb, var(--career-primary) 10%, transparent), + transparent 32% + ), + var(--ifm-background-color); +} + +.heroGrid, +.ctaGrid { + position: absolute; + inset: 0; + pointer-events: none; + opacity: 0.4; + background-image: + linear-gradient(var(--career-border) 1px, transparent 1px), + linear-gradient(90deg, var(--career-border) 1px, transparent 1px); + background-size: 52px 52px; + mask-image: linear-gradient(to bottom, black, transparent 82%); +} + +.heroGlow { + position: absolute; + width: 500px; + height: 500px; + right: -170px; + top: 50%; + border-radius: 50%; + transform: translateY(-50%); + background: var(--career-primary); + opacity: 0.07; + filter: blur(90px); +} + +.hero .container { + position: relative; + z-index: 2; + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(420px, 0.9fr); + align-items: center; + gap: 80px; +} + +.heroContent { + max-width: 690px; +} + +.heroBadge { + display: inline-flex; + align-items: center; + gap: 9px; + padding: 8px 12px; + border: 1px solid var(--career-border-strong); + border-radius: 999px; + color: var(--career-muted); + background: var(--career-card); + font-size: 0.77rem; + font-weight: 750; +} + +.badgeDot { + width: 7px; + height: 7px; + border-radius: 50%; + background: var(--career-primary); + box-shadow: 0 0 0 5px + color-mix(in srgb, var(--career-primary) 13%, transparent); +} + +.hero h1 { + margin: 26px 0 23px; + color: var(--ifm-heading-color); + font-size: clamp(3.2rem, 6vw, 5.5rem); + line-height: 0.98; + letter-spacing: -0.065em; +} + +.hero h1 span { + display: block; + color: var(--career-primary); +} + +.heroDescription { + max-width: 650px; + margin: 0; + color: var(--career-muted); + font-size: 1.08rem; + line-height: 1.85; +} + +.heroActions { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: 32px; +} + +.button { + min-height: 48px; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 9px; + padding: 0 18px; + border: 1px solid transparent; + border-radius: 12px; + font-size: 0.9rem; + font-weight: 800; + text-decoration: none !important; + transition: + transform 180ms ease, + border-color 180ms ease, + background 180ms ease; +} + +.button:hover { + transform: translateY(-2px); +} + +.buttonPrimary { + color: #fff !important; + background: var(--career-primary); + box-shadow: 0 12px 30px + color-mix(in srgb, var(--career-primary) 25%, transparent); +} + +.buttonPrimary:hover { + color: #fff !important; + background: var(--career-primary-dark); +} + +.buttonSecondary, +.buttonGhost { + color: var(--ifm-font-color-base) !important; + border-color: var(--career-border-strong); + background: var(--career-card); +} + +.buttonSecondary:hover, +.buttonGhost:hover { + border-color: var(--career-primary); +} + +.heroTrust { + display: flex; + flex-wrap: wrap; + gap: 18px; + margin-top: 25px; +} + +.heroTrust span { + display: inline-flex; + align-items: center; + gap: 6px; + color: var(--career-muted); + font-size: 0.77rem; + font-weight: 700; +} + +.heroTrust svg { + color: var(--career-primary); +} + +/* ========================================================= + BROWSER MOCKUP + ========================================================= */ + +.heroVisual { + position: relative; + min-height: 430px; + display: grid; + place-items: center; +} + +.browserWindow { + width: min(100%, 560px); + overflow: hidden; + border: 1px solid var(--career-border-strong); + border-radius: 18px; + background: var(--career-card); + box-shadow: 0 30px 80px rgb(0 0 0 / 14%); + transform: perspective(1000px) rotateY(-5deg) rotateX(2deg); +} + +.browserBar { + height: 45px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 15px; + padding: 0 14px; + border-bottom: 1px solid var(--career-border); + color: var(--career-muted); + font-size: 0.68rem; +} + +.browserDots { + display: flex; + gap: 6px; +} + +.browserDots i { + width: 8px; + height: 8px; + border-radius: 50%; + background: var(--career-border-strong); +} + +.addressBar { + flex: 1; + display: flex; + align-items: center; + gap: 7px; + max-width: 270px; + padding: 7px 10px; + border: 1px solid var(--career-border); + border-radius: 7px; + background: var(--career-soft); + font-family: var(--ifm-font-family-monospace); +} + +.browserContent { + min-height: 320px; + padding: 22px; + background: + radial-gradient( + circle at 80% 10%, + color-mix(in srgb, var(--career-primary) 9%, transparent), + transparent 30% + ), + var(--career-card); +} + +.mockNav { + display: flex; + align-items: center; + justify-content: space-between; +} + +.mockLogo { + display: flex; + align-items: center; + gap: 6px; + color: var(--career-primary); + font-size: 0.78rem; + font-weight: 900; +} + +.mockLinks { + display: flex; + gap: 7px; +} + +.mockLinks span { + width: 28px; + height: 5px; + border-radius: 5px; + background: var(--career-border-strong); +} + +.mockHero { + display: grid; + grid-template-columns: 1fr 0.75fr; + gap: 25px; + align-items: center; + min-height: 180px; +} + +.mockText { + display: flex; + flex-direction: column; + gap: 9px; +} + +.mockText span { + width: 90%; + height: 9px; + border-radius: 8px; + background: var(--career-border-strong); +} + +.mockText span:nth-child(2) { + width: 72%; +} + +.mockText span:nth-child(3) { + width: 60%; +} + +.mockText div { + width: 80px; + height: 28px; + margin-top: 8px; + border-radius: 7px; + background: var(--career-primary); +} + +.mockCard { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 10px; + min-height: 145px; + border: 1px solid var(--career-border); + border-radius: 14px; + color: var(--career-primary); + background: var(--career-soft); +} + +.mockCard span { + width: 65%; + height: 6px; + border-radius: 5px; + background: var(--career-border-strong); +} + +.mockCard span:last-child { + width: 45%; +} + +.mockGrid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 10px; +} + +.mockGrid div { + height: 65px; + border: 1px solid var(--career-border); + border-radius: 10px; + background: var(--career-soft); +} + +.floatingSkill, +.floatingStatus { + position: absolute; + display: flex; + align-items: center; + gap: 10px; + padding: 12px 14px; + border: 1px solid var(--career-border-strong); + border-radius: 13px; + background: var(--career-card); + box-shadow: 0 18px 45px rgb(0 0 0 / 10%); +} + +.floatingSkill { + top: 25px; + right: -10px; +} + +.floatingStatus { + bottom: 25px; + left: -20px; +} + +.floatingSkill svg, +.floatingStatus svg { + color: var(--career-primary); +} + +.floatingSkill div, +.floatingStatus div { + display: flex; + flex-direction: column; +} + +.floatingSkill strong, +.floatingStatus strong { + font-size: 0.72rem; +} + +.floatingSkill span, +.floatingStatus span { + color: var(--career-muted); + font-size: 0.64rem; +} + +/* ========================================================= + EXPECTATIONS + ========================================================= */ + +.expectSection { + padding: 90px 0; + border-block: 1px solid var(--career-border); + background: var(--career-soft); +} + +.expectGrid { + display: grid; + grid-template-columns: 0.8fr 1.2fr; + gap: 80px; + align-items: center; +} + +.expectIntro h2 { + max-width: 470px; +} + +.expectIntro p { + max-width: 500px; +} + +.expectCards { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 14px; +} + +.expectCards article { + display: flex; + flex-direction: column; + gap: 8px; + padding: 23px; + border: 1px solid var(--career-border); + border-radius: 15px; + background: var(--career-card); +} + +.expectCards svg { + color: var(--career-primary); +} + +.expectCards strong { + font-size: 0.88rem; +} + +.expectCards span { + color: var(--career-muted); + font-size: 0.76rem; + line-height: 1.55; +} + +/* ========================================================= + SEARCH + ========================================================= */ + +.searchRow { + display: flex; + align-items: center; + justify-content: space-between; + gap: 15px; + margin-bottom: 25px; +} + +.searchRow > span { + color: var(--career-muted); + font-size: 0.76rem; + font-weight: 700; +} + +.searchBox { + width: min(470px, 100%); + height: 48px; + display: flex; + align-items: center; + gap: 10px; + padding: 0 13px; + border: 1px solid var(--career-border-strong); + border-radius: 11px; + background: var(--career-card); +} + +.searchBox > svg { + color: var(--career-muted); +} + +.searchBox input { + width: 100%; + min-width: 0; + border: 0; + outline: 0; + color: var(--ifm-font-color-base); + background: transparent; + font: inherit; +} + +.searchBox button { + display: grid; + width: 28px; + height: 28px; + place-items: center; + padding: 0; + border: 0; + border-radius: 7px; + color: var(--career-muted); + background: transparent; + cursor: pointer; +} + +.skillGrid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 16px; +} + +.skillCard { + min-height: 260px; + padding: 24px; + border: 1px solid var(--career-border); + border-radius: 17px; + background: var(--career-card); + transition: + transform 180ms ease, + border-color 180ms ease, + box-shadow 180ms ease; +} + +.skillCard:hover { + transform: translateY(-4px); + border-color: var(--career-primary); + box-shadow: 0 20px 45px rgb(0 0 0 / 7%); +} + +.skillIcon { + display: grid; + width: 43px; + height: 43px; + place-items: center; + border-radius: 11px; + color: var(--career-primary); + background: color-mix(in srgb, var(--career-primary) 9%, transparent); +} + +.skillCard h3 { + margin: 20px 0 8px; + font-size: 1rem; +} + +.skillCard p { + margin: 0; + color: var(--career-muted); + font-size: 0.8rem; + line-height: 1.7; +} + +.topicList { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-top: 17px; +} + +.topicList span, +.phaseSkills span { + padding: 5px 8px; + border: 1px solid var(--career-border); + border-radius: 6px; + color: var(--career-muted); + background: var(--career-soft); + font-size: 0.64rem; + font-weight: 700; +} + +.emptyState { + display: flex; + min-height: 200px; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 7px; + border: 1px dashed var(--career-border-strong); + border-radius: 16px; + color: var(--career-muted); + text-align: center; +} + +.emptyState svg { + color: var(--career-primary); +} + +/* ========================================================= + ROADMAP + ========================================================= */ + +.roadmapSection, +.workflowSection { + border-block: 1px solid var(--career-border); + background: var(--career-soft); +} + +.phaseGrid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 16px; +} + +.phaseCard { + padding: 25px; + border: 1px solid var(--career-border); + border-radius: 17px; + background: var(--career-card); +} + +.phaseTop { + display: flex; + align-items: center; + justify-content: space-between; +} + +.phaseNumber { + color: var(--career-primary); + font-family: var(--ifm-font-family-monospace); + font-size: 0.72rem; + font-weight: 900; +} + +.phaseDuration { + padding: 5px 8px; + border-radius: 6px; + color: var(--career-muted); + background: var(--career-soft); + font-size: 0.61rem; + font-weight: 800; + text-transform: uppercase; +} + +.phaseCard h3 { + margin: 24px 0 8px; + font-size: 1rem; +} + +.phaseCard > p { + margin: 0; + color: var(--career-muted); + font-size: 0.8rem; + line-height: 1.7; +} + +.phaseSkills { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-top: 18px; +} + +.phaseSkills span { + display: inline-flex; + align-items: center; + gap: 4px; +} + +.phaseSkills svg { + color: var(--career-primary); +} + +/* ========================================================= + PROJECTS + ========================================================= */ + +.projectGrid { + display: grid; + grid-template-columns: 0.95fr 1.05fr; + gap: 80px; + align-items: center; +} + +.projectVisual { + overflow: hidden; + border: 1px solid var(--career-border-strong); + border-radius: 18px; + background: var(--career-card); + box-shadow: 0 25px 70px rgb(0 0 0 / 8%); +} + +.projectHeader { + height: 44px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 15px; + padding: 0 14px; + border-bottom: 1px solid var(--career-border); + color: var(--career-muted); + font-family: var(--ifm-font-family-monospace); + font-size: 0.66rem; +} + +.projectDots { + display: flex; + gap: 5px; +} + +.projectDots i { + width: 7px; + height: 7px; + border-radius: 50%; + background: var(--career-border-strong); +} + +.codeLines { + padding: 25px 20px; + color: var(--ifm-font-color-base); + font-family: var(--ifm-font-family-monospace); + font-size: 0.72rem; + line-height: 2.35; + overflow-x: auto; +} + +.codeLines div { + white-space: nowrap; +} + +.codeLines b { + display: inline-block; + width: 30px; + color: var(--career-muted); + font-weight: 500; +} + +.codeBlue { + color: var(--career-primary); +} + +.codeGreen { + color: var(--ifm-color-success); +} + +.codePurple { + color: var(--ifm-color-info); +} + +.projectContent > p { + max-width: 600px; +} + +.projectChecklist { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 10px; + margin-top: 26px; +} + +.projectChecklist div, +.readinessList div { + display: flex; + align-items: center; + gap: 8px; + color: var(--career-muted); + font-size: 0.78rem; +} + +.projectChecklist svg, +.readinessList svg { + flex: 0 0 auto; + color: var(--career-primary); +} + +.textLink { + display: inline-flex; + align-items: center; + gap: 7px; + margin-top: 26px; + color: var(--career-primary) !important; + font-size: 0.82rem; + font-weight: 800; + text-decoration: none !important; +} + +/* ========================================================= + WORKFLOW + ========================================================= */ + +.workflowSection { + padding: 100px 0; +} + +.workflow { + display: flex; + align-items: center; + justify-content: center; + gap: 12px; +} + +.workflowStep { + min-width: 130px; + padding: 19px 13px; + border: 1px solid var(--career-border); + border-radius: 13px; + background: var(--career-card); + text-align: center; +} + +.workflowStep svg { + margin-bottom: 6px; + color: var(--career-primary); +} + +.workflowStep strong, +.workflowStep span { + display: block; +} + +.workflowStep strong { + font-size: 0.78rem; +} + +.workflowStep span { + margin-top: 3px; + color: var(--career-muted); + font-size: 0.63rem; +} + +.workflowArrow { + flex: 0 0 auto; + color: var(--career-primary); +} + +/* ========================================================= + READINESS + ========================================================= */ + +.readinessGrid { + display: grid; + grid-template-columns: 1fr 0.9fr; + align-items: center; + gap: 80px; +} + +.readinessContent > p { + max-width: 570px; +} + +.readinessList { + display: flex; + flex-direction: column; + gap: 12px; + margin-top: 27px; +} + +.readinessCard { + padding: 27px; + border: 1px solid var(--career-border-strong); + border-radius: 19px; + background: var(--career-card); + box-shadow: 0 20px 55px rgb(0 0 0 / 7%); +} + +.readinessCardHeader { + display: flex; + justify-content: space-between; + padding-bottom: 17px; + border-bottom: 1px solid var(--career-border); +} + +.readinessCardHeader span:first-child { + font-size: 0.84rem; + font-weight: 800; +} + +.readinessCardHeader span:last-child { + color: var(--career-primary); + font-size: 0.62rem; + font-weight: 900; + letter-spacing: 0.1em; +} + +.progressRow { + margin-top: 19px; +} + +.progressRow > div:first-child { + display: flex; + justify-content: space-between; + gap: 10px; + margin-bottom: 7px; +} + +.progressRow span { + color: var(--career-muted); + font-size: 0.68rem; +} + +.progressRow strong { + color: var(--career-primary); + font-size: 0.62rem; +} + +.progressTrack { + height: 6px; + overflow: hidden; + border-radius: 99px; + background: var(--career-soft); +} + +.progressTrack span { + display: block; + height: 100%; + border-radius: inherit; + background: var(--career-primary); +} + +.readinessNote { + display: flex; + gap: 8px; + margin-top: 23px; + padding: 12px; + border: 1px solid var(--career-border); + border-radius: 9px; + color: var(--career-muted); + background: var(--career-soft); + font-size: 0.67rem; + line-height: 1.55; +} + +.readinessNote svg { + flex: 0 0 auto; + color: var(--career-primary); +} + +/* ========================================================= + PORTFOLIO + ========================================================= */ + +.portfolioSection { + background: var(--career-soft); + border-block: 1px solid var(--career-border); +} + +.portfolioGrid { + display: grid; + grid-template-columns: 0.95fr 1.05fr; + align-items: center; + gap: 80px; +} + +.portfolioCard { + padding: 21px; + border: 1px solid var(--career-border-strong); + border-radius: 19px; + background: var(--career-card); + box-shadow: 0 25px 65px rgb(0 0 0 / 8%); +} + +.portfolioTop { + display: flex; + align-items: center; + gap: 11px; + padding-bottom: 18px; + border-bottom: 1px solid var(--career-border); +} + +.portfolioAvatar { + display: grid; + width: 43px; + height: 43px; + place-items: center; + border-radius: 11px; + color: #fff; + background: var(--career-primary); + font-size: 0.72rem; + font-weight: 900; +} + +.portfolioTop > div:nth-child(2) { + flex: 1; + display: flex; + flex-direction: column; +} + +.portfolioTop strong { + font-size: 0.82rem; +} + +.portfolioTop span { + color: var(--career-muted); + font-size: 0.67rem; +} + +.portfolioTop > svg { + color: var(--career-primary); +} + +.portfolioProject { + display: flex; + flex-direction: column; + gap: 7px; + padding: 22px 0; +} + +.portfolioProject > span { + color: var(--career-primary); + font-size: 0.61rem; + font-weight: 900; + letter-spacing: 0.1em; +} + +.portfolioProject strong { + font-size: 0.95rem; +} + +.portfolioProject div { + display: flex; + flex-wrap: wrap; + gap: 6px; +} + +.portfolioProject div span { + padding: 5px 7px; + border: 1px solid var(--career-border); + border-radius: 6px; + color: var(--career-muted); + background: var(--career-soft); + font-size: 0.61rem; +} + +.portfolioStats { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 8px; +} + +.portfolioStats div { + padding: 12px; + border: 1px solid var(--career-border); + border-radius: 9px; + background: var(--career-soft); +} + +.portfolioStats strong, +.portfolioStats span { + display: block; +} + +.portfolioStats strong { + font-size: 0.75rem; +} + +.portfolioStats span { + margin-top: 3px; + color: var(--career-muted); + font-size: 0.61rem; +} + +.portfolioContent > p { + max-width: 600px; +} + +/* ========================================================= + FAQ + ========================================================= */ + +.faqList { + display: flex; + flex-direction: column; + gap: 10px; +} + +.faqItem { + overflow: hidden; + border: 1px solid var(--career-border); + border-radius: 13px; + background: var(--career-card); +} + +.faqButton { + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + gap: 20px; + padding: 19px; + border: 0; + color: var(--ifm-font-color-base); + background: transparent; + font: inherit; + font-weight: 750; + text-align: left; + cursor: pointer; +} + +.faqButton svg { + flex: 0 0 auto; + color: var(--career-muted); + transition: transform 180ms ease; +} + +.faqOpen .faqButton svg { + transform: rotate(180deg); + color: var(--career-primary); +} + +.faqAnswer { + display: grid; + grid-template-rows: 0fr; + transition: grid-template-rows 220ms ease; +} + +.faqAnswer p { + min-height: 0; + overflow: hidden; + margin: 0; + padding: 0 19px; + color: var(--career-muted); + font-size: 0.82rem; + line-height: 1.75; +} + +.faqOpen .faqAnswer { + grid-template-rows: 1fr; +} + +.faqOpen .faqAnswer p { + padding-bottom: 19px; +} + +/* ========================================================= + FINAL CTA + ========================================================= */ + +.finalCta { + position: relative; + padding: 125px 0; + overflow: hidden; + border-top: 1px solid var(--career-border); + background: + radial-gradient( + circle at 50% 20%, + color-mix(in srgb, var(--career-primary) 14%, transparent), + transparent 45% + ), + var(--ifm-background-color); +} + +.finalCta .container { + position: relative; + z-index: 2; +} + +.ctaContent { + max-width: 800px; + margin: 0 auto; + text-align: center; +} + +.ctaIcon { + display: grid; + width: 52px; + height: 52px; + margin: 0 auto 22px; + place-items: center; + border: 1px solid + color-mix(in srgb, var(--career-primary) 35%, var(--career-border)); + border-radius: 15px; + color: var(--career-primary); + background: color-mix(in srgb, var(--career-primary) 8%, transparent); +} + +.ctaContent h2 { + margin: 17px 0; + color: var(--ifm-heading-color); + font-size: clamp(2.4rem, 5vw, 4.5rem); + line-height: 1; + letter-spacing: -0.06em; +} + +.ctaContent h2 span { + color: var(--career-primary); +} + +.ctaContent > p { + max-width: 650px; + margin: 0 auto; + color: var(--career-muted); + line-height: 1.8; +} + +.ctaActions { + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 12px; + margin-top: 32px; +} + +.ctaNote { + display: inline-flex; + align-items: center; + gap: 7px; + margin-top: 23px; + color: var(--career-muted); + font-size: 0.74rem; +} + +.ctaNote svg { + color: var(--career-primary); +} + +/* ========================================================= + RESPONSIVE + ========================================================= */ + +@media (max-width: 1100px) { + .hero .container { + grid-template-columns: 1fr; + gap: 60px; + } + + .heroContent { + max-width: 780px; + margin: 0 auto; + text-align: center; + } + + .heroDescription { + margin-inline: auto; + } + + .heroActions, + .heroTrust { + justify-content: center; + } + + .heroVisual { + min-height: 390px; + } + + .browserWindow { + transform: none; + } + + .expectGrid, + .projectGrid, + .readinessGrid, + .portfolioGrid { + grid-template-columns: 1fr; + } + + .expectIntro { + max-width: 700px; + } + + .projectVisual, + .portfolioCard { + max-width: 680px; + } +} + +@media (max-width: 850px) { + .section { + padding: 85px 0; + } + + .skillGrid, + .phaseGrid { + grid-template-columns: repeat(2, 1fr); + } + + .workflow { + flex-wrap: wrap; + } + + .workflowArrow { + display: none; + } + + .workflowStep { + min-width: 145px; + } +} + +@media (max-width: 640px) { + .container, + .containerNarrow { + width: calc(100% - 28px); + } + + .hero { + min-height: auto; + padding: 85px 0 70px; + } + + .hero h1 { + font-size: clamp(2.7rem, 13vw, 4rem); + } + + .heroDescription { + font-size: 0.96rem; + } + + .heroActions { + flex-direction: column; + } + + .button { + width: 100%; + } + + .heroTrust { + /* flex-direction: column; */ + align-items: center; + gap: 9px; + } + + .heroVisual { + min-height: 320px; + } + + .floatingSkill, + .floatingStatus { + display: none; + } + + .browserContent { + min-height: 270px; + padding: 15px; + } + + .mockHero { + min-height: 145px; + gap: 12px; + } + + .mockGrid div { + height: 48px; + } + + .sectionHeading h2, + .expectIntro h2, + .projectContent h2, + .readinessContent h2, + .portfolioContent h2 { + font-size: 2rem; + } + + .expectCards, + .skillGrid, + .phaseGrid { + grid-template-columns: 1fr; + } + + .searchRow { + align-items: stretch; + flex-direction: column; + } + + .searchBox { + width: 100%; + } + + .searchRow > span { + align-self: flex-end; + } + + .projectChecklist { + grid-template-columns: 1fr; + } + + .workflow { + display: grid; + grid-template-columns: repeat(2, 1fr); + } + + .workflowStep { + min-width: 0; + } + + .readinessCard { + padding: 19px; + } + + .portfolioStats { + gap: 5px; + } + + .portfolioStats div { + padding: 9px; + } + + .finalCta { + padding: 90px 0; + } + + .ctaContent h2 { + font-size: 2.6rem; + } + + .ctaActions { + flex-direction: column; + } +} + +@media (prefers-reduced-motion: reduce) { + .button, + .skillCard, + .faqButton svg { + transition: none; + } + + .button:hover, + .skillCard:hover { + transform: none; + } +} \ No newline at end of file diff --git a/src/pages/careers/full-stack-engineer/index.tsx b/src/pages/careers/full-stack-engineer/index.tsx new file mode 100644 index 000000000..d2e1d3621 --- /dev/null +++ b/src/pages/careers/full-stack-engineer/index.tsx @@ -0,0 +1,834 @@ +import React, { useState } from "react"; +import Layout from "@theme/Layout"; +import Link from "@docusaurus/Link"; +import { + ArrowLeft, + ArrowRight, + ArrowUpRight, + BriefcaseBusiness, + Check, + ChevronDown, + Cloud, + Code2, + Database, + ExternalLink, + Github, + Globe2, + Heart, + Layers3, + LockKeyhole, + Network, + Rocket, + Server, + Sparkles, + Terminal, + Users, + Zap, +} from "lucide-react"; + +import styles from "./styles.module.css"; + +type FAQ = { + question: string; + answer: string; +}; + +const responsibilities = [ + "Design and build end-to-end product features across the frontend, backend, database, and API layers.", + "Develop scalable React and TypeScript interfaces for learning, practice, projects, dashboards, and community experiences.", + "Build reliable backend services, REST APIs, authentication flows, and data-driven application features.", + "Design clean database schemas and efficient queries for application data and user workflows.", + "Integrate third-party services and APIs while keeping security, reliability, and maintainability in mind.", + "Collaborate with frontend engineers, designers, technical writers, community contributors, and product stakeholders.", + "Own features from technical design and implementation through testing, deployment, monitoring, and iteration.", + "Review pull requests, improve engineering standards, and contribute to architectural decisions.", + "Investigate production issues, debug across the stack, and improve application performance.", + "Contribute to the open-source ecosystem and help make CodeHarborHub easier for other developers to build on.", +]; + +const requirements = [ + "Strong fundamentals in JavaScript or TypeScript.", + "Practical experience building applications with React.", + "Experience developing backend applications and APIs.", + "Good understanding of HTTP, REST APIs, authentication, and asynchronous programming.", + "Working knowledge of relational databases and SQL.", + "Comfortable with Git and GitHub-based development workflows.", + "Understanding of application security fundamentals.", + "Ability to debug problems across frontend and backend layers.", + "Understanding of responsive UI development and browser fundamentals.", + "Ability to independently break large product requirements into smaller technical tasks.", +]; + +const niceToHave = [ + "Experience with Node.js, Express, NestJS, or similar backend frameworks.", + "Experience with Supabase, PostgreSQL, or other managed databases.", + "Experience with Next.js or Docusaurus.", + "Experience with TypeScript across the full stack.", + "Knowledge of Docker and containerized development.", + "Experience with GitHub Actions or other CI/CD systems.", + "Experience with automated testing and end-to-end testing.", + "Understanding of caching, queues, background jobs, or event-driven systems.", + "Open-source contributions or experience maintaining public repositories.", + "Experience building developer tools, EdTech products, or community platforms.", +]; + +const architecture = [ + { + icon: Globe2, + title: "Experience layer", + description: + "Build intuitive learning, practice, project, dashboard, and community experiences.", + tags: ["React", "TypeScript", "Docusaurus"], + }, + { + icon: Network, + title: "Application layer", + description: + "Connect product experiences through clean APIs, authentication, business logic, and integrations.", + tags: ["REST APIs", "Auth", "Services"], + }, + { + icon: Database, + title: "Data layer", + description: + "Design reliable data models for users, learning progress, projects, contributions, and platform activity.", + tags: ["PostgreSQL", "SQL", "Supabase"], + }, + { + icon: Cloud, + title: "Infrastructure", + description: + "Keep the platform deployable, observable, secure, and reliable as usage grows.", + tags: ["GitHub", "CI/CD", "Cloud"], + }, +]; + +const stack = [ + { + icon: Code2, + title: "Frontend", + technologies: ["React", "TypeScript", "JavaScript", "HTML", "CSS"], + }, + { + icon: Server, + title: "Backend", + technologies: ["Node.js", "REST APIs", "Authentication", "Services"], + }, + { + icon: Database, + title: "Data", + technologies: ["PostgreSQL", "Supabase", "SQL", "Data Modeling"], + }, + { + icon: Terminal, + title: "Engineering", + technologies: ["Git", "GitHub", "CI/CD", "Testing"], + }, +]; + +const engineeringPrinciples = [ + { + icon: Layers3, + title: "Think end-to-end", + description: + "Understand how a feature moves from interface to API, database, infrastructure, and back to the user.", + }, + { + icon: LockKeyhole, + title: "Security by default", + description: + "Treat authentication, authorization, validation, secrets, and user data as core engineering concerns.", + }, + { + icon: Zap, + title: "Optimize for impact", + description: + "Choose practical architecture that solves the real problem without unnecessary complexity.", + }, + { + icon: Users, + title: "Build with others", + description: + "Communicate decisions, review code thoughtfully, document important context, and make contributors successful.", + }, +]; + +const process = [ + { + number: "01", + title: "Application review", + description: + "We review your experience, GitHub activity, portfolio, projects, and relevant technical work.", + }, + { + number: "02", + title: "Intro conversation", + description: + "A short discussion about your background, interests, engineering experience, and what you want to build.", + }, + { + number: "03", + title: "Full-stack technical discussion", + description: + "We explore frontend, backend, APIs, databases, security, architecture, debugging, and engineering trade-offs.", + }, + { + number: "04", + title: "Practical engineering task", + description: + "You may work through a realistic feature or debugging problem covering multiple parts of the stack.", + }, + { + number: "05", + title: "Architecture conversation", + description: + "We discuss how you would design, scale, secure, test, and evolve a real product feature.", + }, + { + number: "06", + title: "Team conversation", + description: + "We talk about collaboration, ownership, communication, open source, and how you work with other engineers.", + }, + { + number: "07", + title: "Final decision", + description: + "We share the outcome and next steps clearly, including expectations for the role.", + }, +]; + +const faqs: FAQ[] = [ + { + question: "Is this role remote?", + answer: + "The role is designed around remote-first collaboration. Specific working arrangements can depend on the opportunity and team requirements.", + }, + { + question: "Do I need to be equally strong in frontend and backend?", + answer: + "You should be comfortable working across the stack, but we do not expect every engineer to have identical depth everywhere. Strong fundamentals, practical experience, and the ability to learn are important.", + }, + { + question: "Which backend technology do you use?", + answer: + "The platform can use Node.js-based services, REST APIs, and Supabase/PostgreSQL depending on the product area. The exact stack can evolve as the platform grows.", + }, + { + question: "Is database knowledge required?", + answer: + "Yes. You should understand relational data modeling, SQL fundamentals, relationships, indexes at a conceptual level, and how application code interacts with persistent data.", + }, + { + question: "Can junior developers apply?", + answer: + "This particular position is intended for engineers who already have meaningful full-stack project experience. If you are earlier in your journey, internships and contributor opportunities may be a better starting point.", + }, + { + question: "Do open-source contributions matter?", + answer: + "Yes. Open-source work is especially relevant because our engineering culture values public collaboration, code review, documentation, ownership, and community contribution.", + }, +]; + +export default function FullStackEngineerPage(): JSX.Element { + const [openFaq, setOpenFaq] = useState(0); + + const applicationUrl = "https://github.com/CodeHarborHub"; + + return ( + +
+ {/* HERO */} +
+
+
+ +
+ + + Back to careers + + +
+
+
+ + Engineering · Full-time · Remote +
+ +

+ Full Stack + Engineer +

+ +

+ Build the systems behind a developer learning platform — + from beautiful interfaces and APIs to databases, + authentication, infrastructure, and everything in between. +

+ +
+ + + Remote-first + + + + + Full-time + + + + + Product Engineering + +
+ +
+ + Apply for this role + + + + + Explore the role + + +
+ +
+ + + Real product ownership · Open source · Developer impact + +
+
+ + {/* Architecture visual */} +
+
+
+
+ CODEHARBORHUB + Application Architecture +
+ +
+ + SYSTEM ONLINE +
+
+ +
+
+ +
+ Web Experience + React · TypeScript +
+
+ +
+ +
+ +
+ +
+ API & Services + Auth · Business Logic +
+
+ +
+ +
+ +
+ +
+ Data Layer + PostgreSQL · Supabase +
+
+ +
+
+ LATENCY + LOW +
+ +
+ SECURITY + FIRST +
+ +
+ QUALITY + HIGH +
+
+
+
+ +
+ +
+ Ship end-to-end + Idea → Production +
+
+
+
+
+
+ + {/* ROLE SNAPSHOT */} +
+
+
+
+ Role + Full Stack Engineer +
+ +
+ Level + Mid / Senior +
+ +
+ Environment + Remote-first +
+ +
+ Domain + Developer Education +
+ +
+ Ownership + End-to-end +
+
+
+
+ + {/* OVERVIEW */} +
+
+
+
+ + +

+ As a Full Stack Engineer, you will work across the entire + product surface. One day you might build a React learning + experience. Another day you could design an API, improve a + database query, implement authentication, or troubleshoot a + production issue. +

+ +

+ The goal is not simply to add more features. The goal is to + build a platform that is fast, reliable, maintainable, + secure, and genuinely useful to developers at different + stages of their careers. +

+ +

+ You will have meaningful influence over technical decisions + and the opportunity to work on systems that connect + education, open source, community, and developer tooling. +

+
+ + +
+
+
+ + {/* ARCHITECTURE */} +
+
+ + +
+ {architecture.map((item) => { + const Icon = item.icon; + + return ( +
+
+ +
+ + + 0{architecture.indexOf(item) + 1} + + +

{item.title}

+ +

{item.description}

+ +
+ {item.tags.map((tag) => ( + {tag} + ))} +
+
+ ); + })} +
+
+
+ + {/* RESPONSIBILITIES */} +
+
+ + +
+ {responsibilities.map((item, index) => ( +
+ {String(index + 1).padStart(2, "0")} + + + +

{item}

+
+ ))} +
+
+
+ + {/* REQUIREMENTS */} +
+
+
+ + + +
+
+
+ + {/* STACK */} +
+
+ + +
+ {stack.map((item) => { + const Icon = item.icon; + + return ( +
+
+
+ +
+ + +
+ +

{item.title}

+ +
+ {item.technologies.map((technology) => ( + {technology} + ))} +
+
+ ); + })} +
+
+
+ + {/* PRINCIPLES */} +
+
+ + +
+ {engineeringPrinciples.map((item) => { + const Icon = item.icon; + + return ( +
+ + +

{item.title}

+ +

{item.description}

+
+ ); + })} +
+
+
+ + {/* INTERVIEW PROCESS */} +
+
+ + +
+ {process.map((step, index) => ( +
+
{step.number}
+ +
+ {index !== process.length - 1 && } +
+ +
+

{step.title}

+

{step.description}

+
+
+ ))} +
+
+
+ + {/* FAQ */} +
+
+
+ + +
+ {faqs.map((faq, index) => { + const open = openFaq === index; + + return ( +
+ + +
+

{faq.answer}

+
+
+ ); + })} +
+
+
+
+ + {/* CTA */} +
+
+
+
+ +
+ +
+ + YOUR NEXT BUILD + +

+ Build something that + developers remember. +

+ +

+ If you enjoy moving between interfaces, APIs, databases, and + architecture — and want your work to have a real impact on + developers — we'd love to hear from you. +

+ +
+ + Apply for this role + + + + + Explore other roles + + +
+ +
+ + + Your GitHub, projects, and technical work can tell us more + than a traditional resume. + +
+
+
+
+
+
+ ); +} + +/* ───────────────────────────────────────────── + Reusable components +───────────────────────────────────────────── */ + +function SectionHeader({ + eyebrow, + title, + description, +}: { + eyebrow: string; + title: string; + description: string; +}) { + return ( +
+ {eyebrow} +

{title}

+

{description}

+
+ ); +} + +function RequirementCard({ + icon: Icon, + eyebrow, + title, + items, +}: { + icon: React.ComponentType<{ size?: number }>; + eyebrow: string; + title: string; + items: string[]; +}) { + return ( +
+
+
+ +
+ +
+ {eyebrow} +

{title}

+
+
+ +
    + {items.map((item) => ( +
  • + + {item} +
  • + ))} +
+
+ ); +} + +function MapPinIcon() { + return ; +} + +function ShieldIcon({ size = 21 }: { size?: number }) { + return ; +} \ No newline at end of file diff --git a/src/pages/careers/full-stack-engineer/styles.module.css b/src/pages/careers/full-stack-engineer/styles.module.css new file mode 100644 index 000000000..716825059 --- /dev/null +++ b/src/pages/careers/full-stack-engineer/styles.module.css @@ -0,0 +1,1342 @@ +.page { + --career-accent: var(--ifm-color-primary); + --career-accent-soft: color-mix( + in srgb, + var(--career-accent) 12%, + transparent + ); + + color: var(--ifm-font-color-base); + background: var(--ifm-background-color); +} + +/* ========================================================= + BASE +========================================================= */ + +.container { + width: min(1180px, calc(100% - 40px)); + margin: 0 auto; +} + +.section { + position: relative; + padding: 105px 0; +} + +.muted { + background: + radial-gradient( + circle at 10% 20%, + var(--career-accent-soft), + transparent 28% + ), + var(--ifm-background-surface-color); +} + +.sectionHeader { + max-width: 780px; + margin-bottom: 50px; +} + +.sectionHeader > span, +.eyebrow { + display: inline-flex; + color: var(--career-accent); + font-size: 0.72rem; + font-weight: 850; + letter-spacing: 0.13em; + text-transform: uppercase; +} + +.sectionHeader h2 { + margin: 11px 0 15px; + font-size: clamp(2.15rem, 4.5vw, 3.65rem); + line-height: 1.04; + letter-spacing: -0.045em; +} + +.sectionHeader p { + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 1.02rem; + line-height: 1.78; +} + +/* ========================================================= + HERO +========================================================= */ + +.hero { + position: relative; + overflow: hidden; + padding: 52px 0 95px; + border-bottom: 1px solid var(--ifm-color-emphasis-200); + background: var(--ifm-background-color); +} + +.heroGrid { + position: absolute; + inset: 0; + opacity: 0.28; + background-image: + linear-gradient( + to right, + var(--ifm-color-emphasis-200) 1px, + transparent 1px + ), + linear-gradient( + to bottom, + var(--ifm-color-emphasis-200) 1px, + transparent 1px + ); + background-size: 52px 52px; + mask-image: linear-gradient(to bottom, black, transparent 85%); + pointer-events: none; +} + +.heroGlow { + position: absolute; + top: 10%; + right: 5%; + width: 500px; + height: 500px; + border-radius: 50%; + background: var(--career-accent); + opacity: 0.08; + filter: blur(100px); + pointer-events: none; +} + +.backLink { + position: relative; + z-index: 1; + display: inline-flex; + align-items: center; + gap: 8px; + margin-bottom: 60px; + color: var(--ifm-color-emphasis-700); + font-size: 0.9rem; + font-weight: 750; + text-decoration: none; + transition: + color 180ms ease, + transform 180ms ease; +} + +.backLink:hover { + color: var(--career-accent); + text-decoration: none; + transform: translateX(-3px); +} + +.heroLayout { + position: relative; + z-index: 1; + display: grid; + grid-template-columns: minmax(0, 1.05fr) minmax(400px, 0.95fr); + gap: 80px; + align-items: center; +} + +.badge { + display: inline-flex; + align-items: center; + gap: 9px; + padding: 8px 13px; + border: 1px solid color-mix(in srgb, var(--career-accent) 30%, transparent); + border-radius: 999px; + background: var(--career-accent-soft); + color: var(--career-accent); + font-size: 0.73rem; + font-weight: 800; +} + +.badge span { + width: 7px; + height: 7px; + border-radius: 50%; + background: currentColor; + box-shadow: 0 0 0 4px + color-mix(in srgb, var(--career-accent) 13%, transparent); +} + +.heroContent h1 { + max-width: 780px; + margin: 24px 0 22px; + font-size: clamp(3.5rem, 7vw, 6.4rem); + line-height: 0.91; + letter-spacing: -0.065em; +} + +.heroContent h1 strong { + display: block; + color: var(--career-accent); + font-weight: inherit; +} + +.heroLead { + max-width: 720px; + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: clamp(1.04rem, 2vw, 1.25rem); + line-height: 1.75; +} + +.meta { + display: flex; + flex-wrap: wrap; + gap: 20px; + margin-top: 28px; +} + +.meta span { + display: inline-flex; + align-items: center; + gap: 8px; + color: var(--ifm-color-emphasis-700); + font-size: 0.88rem; + font-weight: 750; +} + +.meta svg { + color: var(--career-accent); +} + +.mapPin { + color: var(--career-accent); + font-size: 12px; +} + +.actions { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: 34px; +} + +.primaryButton, +.secondaryButton { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 9px; + min-height: 49px; + padding: 0 19px; + border-radius: 12px; + font-size: 0.9rem; + font-weight: 800; + text-decoration: none; + transition: + transform 180ms ease, + box-shadow 180ms ease, + border-color 180ms ease; +} + +.primaryButton { + border: 1px solid var(--career-accent); + background: var(--career-accent); + color: white; + box-shadow: 0 14px 30px + color-mix(in srgb, var(--career-accent) 23%, transparent); +} + +.primaryButton:hover { + color: white; + text-decoration: none; + transform: translateY(-2px); + box-shadow: 0 18px 38px + color-mix(in srgb, var(--career-accent) 30%, transparent); +} + +.secondaryButton { + border: 1px solid var(--ifm-color-emphasis-300); + background: var(--ifm-background-surface-color); + color: var(--ifm-font-color-base); +} + +.secondaryButton:hover { + color: var(--ifm-font-color-base); + text-decoration: none; + border-color: var(--career-accent); + transform: translateY(-2px); +} + +.heroTrust { + display: flex; + align-items: center; + gap: 7px; + margin-top: 19px; + color: var(--ifm-color-emphasis-600); + font-size: 0.74rem; +} + +.heroTrust svg { + color: var(--career-accent); +} + +/* ========================================================= + ARCHITECTURE VISUAL +========================================================= */ + +.architectureVisual { + position: relative; + min-height: 470px; + display: grid; + place-items: center; +} + +.architectureCard { + width: min(100%, 530px); + overflow: hidden; + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 21px; + background: var(--ifm-background-surface-color); + box-shadow: 0 35px 90px rgb(0 0 0 / 12%); + transform: perspective(1100px) rotateY(-4deg) rotateX(2deg); +} + +.archHeader { + display: flex; + align-items: center; + justify-content: space-between; + gap: 15px; + padding: 17px 18px; + border-bottom: 1px solid var(--ifm-color-emphasis-200); +} + +.archHeader > div:first-child { + display: grid; + gap: 3px; +} + +.archHeader span { + color: var(--ifm-color-emphasis-500); + font-family: var(--ifm-font-family-monospace); + font-size: 0.59rem; + letter-spacing: 0.12em; +} + +.archHeader strong { + font-size: 0.82rem; +} + +.status { + display: inline-flex; + align-items: center; + gap: 6px; + color: var(--career-accent); + font-family: var(--ifm-font-family-monospace); + font-size: 0.55rem; + font-weight: 800; +} + +.status span { + width: 6px; + height: 6px; + border-radius: 50%; + background: currentColor; +} + +.archDiagram { + padding: 30px 25px 24px; +} + +.archNode { + display: flex; + align-items: center; + gap: 13px; + padding: 17px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 13px; + background: var(--ifm-background-color); +} + +.archNode > svg { + color: var(--career-accent); +} + +.archNode div { + display: grid; + gap: 3px; +} + +.archNode strong { + font-size: 0.83rem; +} + +.archNode small { + color: var(--ifm-color-emphasis-600); + font-family: var(--ifm-font-family-monospace); + font-size: 0.63rem; +} + +.connector { + position: relative; + height: 32px; +} + +.connector::before { + position: absolute; + top: 0; + left: 50%; + width: 1px; + height: 100%; + background: var(--ifm-color-emphasis-300); + content: ""; +} + +.connector span { + position: absolute; + bottom: 0; + left: calc(50% - 3px); + width: 7px; + height: 7px; + border-right: 1px solid var(--ifm-color-emphasis-500); + border-bottom: 1px solid var(--ifm-color-emphasis-500); + transform: rotate(45deg); +} + +.archFooter { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 8px; + margin-top: 25px; +} + +.archFooter div { + padding: 11px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 10px; +} + +.archFooter span, +.archFooter strong { + display: block; +} + +.archFooter span { + color: var(--ifm-color-emphasis-500); + font-size: 0.55rem; +} + +.archFooter strong { + margin-top: 3px; + color: var(--career-accent); + font-family: var(--ifm-font-family-monospace); + font-size: 0.72rem; +} + +.floatingCard { + position: absolute; + right: -10px; + bottom: 15px; + display: flex; + align-items: center; + gap: 11px; + padding: 13px 15px; + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 14px; + background: color-mix( + in srgb, + var(--ifm-background-surface-color) 94%, + transparent + ); + box-shadow: 0 20px 50px rgb(0 0 0 / 15%); + backdrop-filter: blur(15px); +} + +.floatingCard > svg { + color: var(--career-accent); +} + +.floatingCard div { + display: grid; + gap: 2px; +} + +.floatingCard strong { + font-size: 0.8rem; +} + +.floatingCard span { + color: var(--ifm-color-emphasis-600); + font-size: 0.69rem; +} + +/* ========================================================= + SNAPSHOT +========================================================= */ + +.snapshot { + border-bottom: 1px solid var(--ifm-color-emphasis-200); + background: var(--ifm-background-surface-color); +} + +.snapshotGrid { + display: grid; + grid-template-columns: repeat(5, 1fr); +} + +.snapshotGrid > div { + display: grid; + gap: 5px; + padding: 23px 20px; + border-right: 1px solid var(--ifm-color-emphasis-200); +} + +.snapshotGrid > div:first-child { + padding-left: 0; +} + +.snapshotGrid > div:last-child { + border-right: 0; +} + +.snapshotGrid span { + color: var(--ifm-color-emphasis-600); + font-size: 0.66rem; + font-weight: 800; + letter-spacing: 0.09em; + text-transform: uppercase; +} + +.snapshotGrid strong { + font-size: 0.88rem; +} + +/* ========================================================= + TWO COLUMN +========================================================= */ + +.twoColumn { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(330px, 0.68fr); + gap: 80px; + align-items: start; +} + +.bodyText { + max-width: 770px; + margin: 0 0 18px; + color: var(--ifm-color-emphasis-700); + font-size: 0.98rem; + line-height: 1.82; +} + +.impactCard { + position: sticky; + top: 100px; + padding: 32px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 22px; + background: + radial-gradient( + circle at 100% 0, + var(--career-accent-soft), + transparent 45% + ), + var(--ifm-background-surface-color); +} + +.impactIcon { + display: grid; + width: 48px; + height: 48px; + margin-bottom: 25px; + place-items: center; + border-radius: 14px; + background: var(--career-accent-soft); + color: var(--career-accent); +} + +.impactCard > span { + color: var(--ifm-color-emphasis-600); + font-size: 0.67rem; + font-weight: 850; + letter-spacing: 0.12em; +} + +.impactCard h3 { + margin: 10px 0 13px; + font-size: 1.5rem; + line-height: 1.25; + letter-spacing: -0.025em; +} + +.impactCard > p { + margin: 0; + color: var(--ifm-color-emphasis-700); + line-height: 1.7; + font-size: 0.88rem; +} + +.impactMetrics { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 7px; + margin-top: 26px; +} + +.impactMetrics div { + padding: 13px 10px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 10px; + background: var(--ifm-background-color); + text-align: center; +} + +.impactMetrics strong, +.impactMetrics span { + display: block; +} + +.impactMetrics strong { + color: var(--career-accent); + font-family: var(--ifm-font-family-monospace); + font-size: 0.9rem; +} + +.impactMetrics span { + margin-top: 3px; + color: var(--ifm-color-emphasis-600); + font-size: 0.6rem; +} + +/* ========================================================= + ARCHITECTURE GRID +========================================================= */ + +.archGrid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 14px; +} + +.archItem { + position: relative; + padding: 27px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 18px; + background: var(--ifm-background-color); + transition: + transform 180ms ease, + border-color 180ms ease, + box-shadow 180ms ease; +} + +.archItem:hover { + border-color: color-mix(in srgb, var(--career-accent) 45%, transparent); + transform: translateY(-4px); + box-shadow: 0 20px 45px rgb(0 0 0 / 7%); +} + +.archIcon { + display: grid; + width: 43px; + height: 43px; + margin-bottom: 28px; + place-items: center; + border-radius: 12px; + background: var(--career-accent-soft); + color: var(--career-accent); +} + +.archNumber { + position: absolute; + top: 28px; + right: 25px; + color: var(--ifm-color-emphasis-400); + font-family: var(--ifm-font-family-monospace); + font-size: 0.67rem; +} + +.archItem h3 { + margin: 0 0 9px; + font-size: 1rem; +} + +.archItem p { + min-height: 88px; + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.84rem; + line-height: 1.7; +} + +.tags, +.stackTags { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-top: 18px; +} + +.tags span, +.stackTags span { + padding: 5px 7px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 6px; + color: var(--ifm-color-emphasis-600); + font-family: var(--ifm-font-family-monospace); + font-size: 0.61rem; +} + +/* ========================================================= + RESPONSIBILITIES +========================================================= */ + +.responsibilityGrid { + display: grid; + grid-template-columns: repeat(2, 1fr); + column-gap: 35px; + border-top: 1px solid var(--ifm-color-emphasis-200); +} + +.responsibility { + display: grid; + grid-template-columns: 35px 19px 1fr; + gap: 11px; + align-items: start; + padding: 21px 0; + border-bottom: 1px solid var(--ifm-color-emphasis-200); +} + +.responsibility > span { + color: var(--career-accent); + font-family: var(--ifm-font-family-monospace); + font-size: 0.68rem; + font-weight: 800; +} + +.responsibility > svg { + margin-top: 2px; + color: var(--career-accent); +} + +.responsibility p { + margin: 0; + color: var(--ifm-color-emphasis-800); + font-size: 0.88rem; + line-height: 1.65; +} + +/* ========================================================= + REQUIREMENTS +========================================================= */ + +.requirementCard { + padding: 32px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 20px; + background: var(--ifm-background-color); +} + +.requirementHeader { + display: flex; + gap: 14px; + align-items: center; + margin-bottom: 27px; +} + +.requirementIcon { + display: grid; + width: 46px; + height: 46px; + flex: 0 0 auto; + place-items: center; + border-radius: 13px; + background: var(--career-accent-soft); + color: var(--career-accent); +} + +.requirementHeader span { + display: block; + color: var(--career-accent); + font-size: 0.65rem; + font-weight: 850; + letter-spacing: 0.1em; + text-transform: uppercase; +} + +.requirementHeader h3 { + margin: 3px 0 0; + font-size: 1.1rem; +} + +.requirementCard ul { + display: grid; + gap: 14px; + padding: 0; + margin: 0; + list-style: none; +} + +.requirementCard li { + display: flex; + gap: 9px; + color: var(--ifm-color-emphasis-700); + font-size: 0.86rem; + line-height: 1.65; +} + +.requirementCard li svg { + flex: 0 0 auto; + margin-top: 3px; + color: var(--career-accent); +} + +/* ========================================================= + STACK +========================================================= */ + +.stackGrid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 15px; +} + +.stackCard { + padding: 24px; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 17px; + background: var(--ifm-background-surface-color); + transition: + transform 180ms ease, + border-color 180ms ease; +} + +.stackCard:hover { + border-color: color-mix(in srgb, var(--career-accent) 45%, transparent); + transform: translateY(-4px); +} + +.stackTop { + display: flex; + align-items: center; + justify-content: space-between; +} + +.stackTop > svg { + color: var(--ifm-color-emphasis-400); +} + +.stackIcon { + display: grid; + width: 43px; + height: 43px; + place-items: center; + border-radius: 12px; + background: var(--career-accent-soft); + color: var(--career-accent); +} + +.stackCard h3 { + margin: 20px 0 0; + font-size: 1rem; +} + +.stackTags { + margin-top: 13px; +} + +/* ========================================================= + PRINCIPLES +========================================================= */ + +.principlesGrid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 1px; + overflow: hidden; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 20px; + background: var(--ifm-color-emphasis-200); +} + +.principle { + padding: 30px; + background: var(--ifm-background-color); +} + +.principle > svg { + margin-bottom: 25px; + color: var(--career-accent); +} + +.principle h3 { + margin: 0 0 9px; + font-size: 1rem; +} + +.principle p { + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.84rem; + line-height: 1.7; +} + +/* ========================================================= + PROCESS +========================================================= */ + +.process { + max-width: 900px; +} + +.processItem { + display: grid; + grid-template-columns: 48px 30px 1fr; + min-height: 120px; +} + +.processNumber { + display: grid; + width: 42px; + height: 42px; + place-items: center; + border: 1px solid color-mix(in srgb, var(--career-accent) 30%, transparent); + border-radius: 50%; + background: var(--career-accent-soft); + color: var(--career-accent); + font-family: var(--ifm-font-family-monospace); + font-size: 0.69rem; + font-weight: 850; +} + +.processRail { + position: relative; +} + +.processRail span { + position: absolute; + top: 42px; + left: 20px; + width: 1px; + height: calc(100% - 42px); + background: var(--ifm-color-emphasis-300); +} + +.processContent { + padding-bottom: 34px; +} + +.processContent h3 { + margin: 8px 0 8px; + font-size: 1.08rem; +} + +.processContent p { + max-width: 690px; + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.87rem; + line-height: 1.7; +} + +/* ========================================================= + FAQ +========================================================= */ + +.faqLayout { + display: grid; + grid-template-columns: 0.65fr 1fr; + gap: 80px; + align-items: start; +} + +.faqList { + border-top: 1px solid var(--ifm-color-emphasis-200); +} + +.faqItem { + border-bottom: 1px solid var(--ifm-color-emphasis-200); +} + +.faqButton { + display: flex; + width: 100%; + align-items: center; + justify-content: space-between; + gap: 20px; + padding: 21px 0; + border: 0; + background: transparent; + color: var(--ifm-font-color-base); + text-align: left; + font: inherit; + font-size: 0.91rem; + font-weight: 750; + cursor: pointer; +} + +.faqButton svg { + flex: 0 0 auto; + color: var(--ifm-color-emphasis-500); + transition: transform 180ms ease; +} + +.open .faqButton svg { + color: var(--career-accent); + transform: rotate(180deg); +} + +.answer { + display: grid; + grid-template-rows: 0fr; + transition: grid-template-rows 220ms ease; +} + +.answer p { + overflow: hidden; + margin: 0; + color: var(--ifm-color-emphasis-700); + font-size: 0.86rem; + line-height: 1.7; +} + +.open .answer { + grid-template-rows: 1fr; +} + +.open .answer p { + padding: 0 35px 22px 0; +} + +/* ========================================================= + CTA +========================================================= */ + +.cta { + padding: 15px 0 110px; +} + +.ctaCard { + position: relative; + overflow: hidden; + padding: 75px 40px; + border: 1px solid color-mix( + in srgb, + var(--career-accent) 28%, + var(--ifm-color-emphasis-200) + ); + border-radius: 28px; + background: + radial-gradient( + circle at 85% 15%, + color-mix(in srgb, var(--career-accent) 18%, transparent), + transparent 35% + ), + var(--ifm-background-surface-color); + text-align: center; +} + +.ctaGlow { + position: absolute; + right: -150px; + bottom: -180px; + width: 350px; + height: 350px; + border-radius: 50%; + background: var(--career-accent); + opacity: 0.08; + filter: blur(70px); + pointer-events: none; +} + +.ctaIcon { + position: relative; + display: grid; + width: 58px; + height: 58px; + margin: 0 auto 24px; + place-items: center; + border: 1px solid color-mix(in srgb, var(--career-accent) 30%, transparent); + border-radius: 17px; + background: var(--career-accent-soft); + color: var(--career-accent); +} + +.ctaCard h2 { + position: relative; + max-width: 780px; + margin: 11px auto 17px; + font-size: clamp(2.2rem, 5vw, 4rem); + line-height: 1.04; + letter-spacing: -0.05em; +} + +.ctaCard h2 strong { + color: var(--career-accent); + font-weight: inherit; +} + +.ctaCard > p { + position: relative; + max-width: 680px; + margin: 0 auto; + color: var(--ifm-color-emphasis-700); + line-height: 1.75; +} + +.ctaActions { + position: relative; + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 12px; + margin-top: 31px; +} + +.ctaNote { + position: relative; + display: flex; + justify-content: center; + align-items: center; + gap: 7px; + max-width: 700px; + margin: 22px auto 0; + color: var(--ifm-color-emphasis-600); + font-size: 0.73rem; + line-height: 1.6; +} + +.ctaNote svg { + flex: 0 0 auto; +} + +/* ========================================================= + DARK MODE +========================================================= */ + +[data-theme="dark"] .architectureCard { + background: #0c1219; + box-shadow: 0 35px 100px rgb(0 0 0 / 40%); +} + +[data-theme="dark"] .archNode { + background: #0f1720; +} + +[data-theme="dark"] .impactCard, +[data-theme="dark"] .requirementCard, +[data-theme="dark"] .stackCard { + box-shadow: 0 18px 50px rgb(0 0 0 / 15%); +} + +/* ========================================================= + RESPONSIVE +========================================================= */ + +@media (max-width: 1100px) { + .heroLayout { + grid-template-columns: 1fr; + gap: 65px; + } + + .heroContent { + max-width: 800px; + } + + .architectureVisual { + width: min(100%, 650px); + justify-self: center; + } + + .archGrid, + .stackGrid, + .principlesGrid { + grid-template-columns: repeat(2, 1fr); + } + + .twoColumn, + .faqLayout { + gap: 45px; + } +} + +@media (max-width: 800px) { + .container { + width: min(100% - 30px, 700px); + } + + .section { + padding: 75px 0; + } + + .hero { + padding: 35px 0 70px; + } + + .backLink { + margin-bottom: 42px; + } + + .heroContent h1 { + font-size: clamp(3.1rem, 13vw, 5rem); + } + + .architectureVisual { + min-height: 400px; + } + + .architectureCard { + transform: none; + } + + .snapshotGrid { + grid-template-columns: repeat(2, 1fr); + } + + .snapshotGrid > div, + .snapshotGrid > div:first-child { + padding: 18px 15px; + border-bottom: 1px solid var(--ifm-color-emphasis-200); + } + + .snapshotGrid > div:nth-child(2n) { + border-right: 0; + } + + .snapshotGrid > div:last-child { + border-bottom: 0; + } + + .twoColumn, + .faqLayout { + grid-template-columns: 1fr; + } + + .impactCard { + position: static; + } + + .responsibilityGrid { + grid-template-columns: 1fr; + } +} + +@media (max-width: 560px) { + .container { + width: min(100% - 24px, 500px); + } + + .section { + padding: 60px 0; + } + + .heroContent h1 { + font-size: 3.15rem; + } + + .heroLead { + font-size: 1rem; + } + + .meta { + display: grid; + gap: 11px; + } + + .actions, + .ctaActions { + display: grid; + grid-template-columns: 1fr; + } + + .primaryButton, + .secondaryButton { + width: 100%; + } + + .architectureVisual { + min-height: 340px; + } + + .architectureCard { + width: 100%; + } + + .archHeader { + align-items: flex-start; + flex-direction: column; + } + + .archDiagram { + padding: 20px 15px; + } + + .floatingCard { + right: 0; + bottom: 0; + } + + .floatingCard span { + display: none; + } + + .snapshotGrid { + grid-template-columns: 1fr; + } + + .snapshotGrid > div, + .snapshotGrid > div:first-child { + padding: 15px 0; + border-right: 0; + } + + .snapshotGrid > div:last-child { + border-bottom: 0; + } + + .archGrid, + .stackGrid, + .principlesGrid { + grid-template-columns: 1fr; + } + + .archItem p { + min-height: auto; + } + + .requirementCard { + padding: 23px; + } + + .processItem { + grid-template-columns: 43px 20px 1fr; + } + + .processNumber { + width: 38px; + height: 38px; + } + + .processRail span { + left: 18px; + } + + .cta { + padding-bottom: 70px; + } + + .ctaCard { + padding: 50px 20px; + border-radius: 20px; + } + + .ctaCard h2 { + font-size: 2.25rem; + } +} + +@media (prefers-reduced-motion: reduce) { + .primaryButton, + .secondaryButton, + .backLink, + .archItem, + .stackCard, + .faqButton svg { + transition: none; + } +} \ No newline at end of file diff --git a/src/pages/careers/index.tsx b/src/pages/careers/index.tsx index 2a477bd4b..97ed19368 100644 --- a/src/pages/careers/index.tsx +++ b/src/pages/careers/index.tsx @@ -1,31 +1,1098 @@ -import React from "react"; -import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; +import React, { useMemo, useState } from "react"; +// @ts-ignore import Layout from "@theme/Layout"; -import CareerPage from "../../components/CareerPage"; -import Head from "@docusaurus/Head"; +// @ts-ignore +import Link from "@docusaurus/Link"; -export default function Careers() { - const { siteConfig } = useDocusaurusContext(); +import { + ArrowRight, + ArrowUpRight, + BriefcaseBusiness, + Building2, + CheckCircle2, + ChevronDown, + Code2, + ExternalLink, + Github, + Globe2, + HeartHandshake, + Laptop, + MapPin, + Rocket, + Search, + ShieldCheck, + Sparkles, + Users, + X, + Zap, +} from "lucide-react"; + +// @ts-ignore +import styles from "./styles.module.css"; + +type JobType = "Full-time" | "Internship" | "Contract" | "Volunteer"; + +type Job = { + id: string; + title: string; + department: string; + location: string; + type: JobType; + remote: boolean; + description: string; + skills: string[]; + featured?: boolean; +}; + +const JOBS: Job[] = [ + { + id: "frontend-engineer", + title: "Frontend Engineer", + department: "Engineering", + location: "Remote — India", + type: "Full-time", + remote: true, + featured: true, + description: + "Build fast, accessible and delightful learning experiences for developers around the world.", + skills: ["React", "TypeScript", "Docusaurus", "CSS"], + }, + { + id: "full-stack-engineer", + title: "Full Stack Engineer", + department: "Engineering", + location: "Remote — India", + type: "Full-time", + remote: true, + featured: true, + description: + "Build scalable learning, practice, community and developer-platform features end to end.", + skills: ["React", "Node.js", "TypeScript", "Supabase"], + }, + { + id: "technical-writer", + title: "Technical Writer", + department: "Content", + location: "Remote", + type: "Contract", + remote: true, + description: + "Create accurate, practical and beginner-friendly technical documentation and tutorials.", + skills: ["MDX", "Git", "JavaScript", "Technical Writing"], + }, + { + id: "open-source-contributor", + title: "Open Source Contributor", + department: "Community", + location: "Global", + type: "Volunteer", + remote: true, + description: + "Help improve CodeHarborHub through documentation, code, design, issues and community contributions.", + skills: ["GitHub", "Open Source", "Communication"], + }, + { + id: "frontend-intern", + title: "Frontend Developer Intern", + department: "Engineering", + location: "Remote — India", + type: "Internship", + remote: true, + description: + "Learn by shipping real product improvements while working with modern frontend technologies.", + skills: ["HTML", "CSS", "JavaScript", "React"], + }, + { + id: "community-intern", + title: "Developer Community Intern", + department: "Community", + location: "Remote", + type: "Internship", + remote: true, + description: + "Help grow a welcoming developer community through events, content and contributor programs.", + skills: ["Community", "GitHub", "Content", "Communication"], + }, +]; + +const DEPARTMENTS = [ + { + title: "Engineering", + description: + "Build the infrastructure, learning tools and developer experiences powering CodeHarborHub.", + icon: , + count: "4 roles", + }, + { + title: "Content", + description: + "Turn complex technical concepts into clear, practical and useful learning experiences.", + icon: , + count: "2 roles", + }, + { + title: "Community", + description: + "Build an inclusive open-source community where developers learn and contribute together.", + icon: , + count: "3 roles", + }, + { + title: "Product & Design", + description: + "Design experiences that make learning, practicing and building easier for developers.", + icon: , + count: "Coming soon", + }, +]; + +const VALUES = [ + { + number: "01", + title: "Learners first", + description: + "We make decisions around what creates the most value for people learning and building with technology.", + icon: , + }, + { + number: "02", + title: "Build in the open", + description: + "We believe transparency, collaboration and open source can create better technology and stronger communities.", + icon: , + }, + { + number: "03", + title: "Own the outcome", + description: + "Take responsibility, communicate clearly and focus on meaningful results rather than simply completing tasks.", + icon: , + }, + { + number: "04", + title: "Keep learning", + description: + "Technology changes quickly. We continuously experiment, learn from mistakes and improve our craft.", + icon: , + }, +]; + +const BENEFITS = [ + { + title: "Remote-first", + description: + "Work from where you do your best work, with communication designed for distributed teams.", + icon: , + }, + { + title: "Real ownership", + description: + "Work on meaningful product areas instead of isolated practice assignments.", + icon: , + }, + { + title: "Open source", + description: + "Build publicly, collaborate with contributors and create work you can be proud of.", + icon: , + }, + { + title: "Continuous learning", + description: + "Grow through technical challenges, documentation, reviews and collaboration.", + icon: , + }, + { + title: "Developer community", + description: + "Work alongside learners, contributors and developers from different backgrounds.", + icon: , + }, + { + title: "Impact at scale", + description: + "Help create accessible technology education for developers around the world.", + icon: , + }, +]; + +const FAQS = [ + { + question: "Is CodeHarborHub hiring right now?", + answer: + "This page is designed to show currently published opportunities. If no role matches your profile, you can still contribute to the open-source project and build a public track record with the community.", + }, + { + question: "Can I apply for more than one role?", + answer: + "Yes. Apply to roles where your experience genuinely matches the requirements. Tailor your application to the specific role rather than sending the same application everywhere.", + }, + { + question: "Are opportunities remote?", + answer: + "Many CodeHarborHub opportunities are designed to support remote collaboration. The exact location requirements should always be checked on the individual opportunity.", + }, + { + question: "Can beginners contribute?", + answer: + "Yes. Open-source contribution is a good starting point for developers who are still building professional experience. Documentation, testing, design, issue triage and beginner-friendly engineering tasks can all create meaningful contribution paths.", + }, + { + question: "Do you offer internships?", + answer: + "Internship opportunities can be published when there is an active opening. Candidates should apply only through the official opportunity page and follow the requirements listed there.", + }, + { + question: "How can I contribute if there are no jobs?", + answer: + "You can contribute through GitHub, documentation, tutorials, design, issue discussions, community programs and other open-source initiatives.", + }, +]; + +function getTypeClass(type: JobType) { + switch (type) { + case "Full-time": + return styles.fullTime; + + case "Internship": + return styles.internship; + + case "Contract": + return styles.contract; + + default: + return styles.volunteer; + } +} + +export default function CareersPage(): React.JSX.Element { + const [search, setSearch] = useState(""); + const [jobType, setJobType] = useState<"All" | JobType>("All"); + const [department, setDepartment] = useState("All"); + const [openFaq, setOpenFaq] = useState(0); + + const filteredJobs = useMemo(() => { + const query = search.trim().toLowerCase(); + + return JOBS.filter((job) => { + const matchesType = jobType === "All" || job.type === jobType; + + const matchesDepartment = + department === "All" || job.department === department; + + const searchableText = [ + job.title, + job.department, + job.location, + job.description, + ...job.skills, + ] + .join(" ") + .toLowerCase(); + + const matchesSearch = !query || searchableText.includes(query); + + return matchesType && matchesDepartment && matchesSearch; + }); + }, [search, jobType, department]); return ( - -