Repository: Avdhesh-Varshney/pjt-blog
Pull request #1154: Dark mode
Author: login: Avdhesh-Varshney
Labels: name: enhancement
description: New feature or request
Created: 2025-05-05T19:12:00Z | Merged: 2025-05-06T16:29:59Z

<!-- #issue_number  -->
Closes: #985 

### Describe the add-ons or changes you've made 📃
- [x] implementing theme changing functionality
- [x] 3 different modes: system, light & dark



### Type of change ☑️
What sort of change have you made:

- [x] New feature 



Diff:
diff --git a/frontend/src/components/AboutUser.jsx b/frontend/src/components/AboutUser.jsx
index 6bffc5916..752dec7f7 100644
--- a/frontend/src/components/AboutUser.jsx
+++ b/frontend/src/components/AboutUser.jsx
@@ -12,7 +12,13 @@ const AboutUser = ({ className, bio, social_links, joinedAt }) => {
                         let link = social_links[key];
                         return link ?
                             <Link to={link} key={key} target="_blank">
-                                <i className={"fi " + (key !== 'website' ? "fi-brands-" + key : "fi-rr-globe") + " text-2xl hover:text-black"} ></i>
+                                <i
+                                    className={
+                                        "fi " +
+                                        (key !== 'website' ? "fi-brands-" + key : "fi-rr-globe") +
+                                        " text-2xl text-gray-700 dark:text-gray-300 hover:text-black dark:hover:text-white transition-colors"
+                                    }
+                                ></i>
                             </Link> :
                             ""
                     })
diff --git a/frontend/src/components/CommentCard.jsx b/frontend/src/components/CommentCard.jsx
index 534baead4..97920f841 100644
--- a/frontend/src/components/CommentCard.jsx
+++ b/frontend/src/components/CommentCard.jsx
@@ -122,7 +122,8 @@ const CommentCard = ({ index, leftVal, commentData }) => {
         let btn = (
             <button
                 onClick={() => loadReplies({ skip: index - parentIndex, currentIndex: getParentIndex() })}
-                className="text-gray-500 p-2 px-3 hover:bg-gray-50 rounded-md flex items-center gap-2">
+                className="text-[#555] dark:text-gray-300 p-2 px-3 hover:bg-[#f3f3f3] dark:hover:bg-[#1e1e1e] rounded-md flex items-center gap-2"
+            >
                 Load More Replies
             </button>
         );
@@ -159,13 +160,13 @@ const CommentCard = ({ index, leftVal, commentData }) => {
                         commentData.isReplyLoaded ?
                             <button
                                 onClick={hideReplies}
-                                className="text-gray-500 p-2 px-3 hover:bg-gray-50 rounded-md flex items-center gap-2"
+                                className="text-[#555] dark:text-gray-300 p-2 px-3 hover:bg-[#f3f3f3] dark:hover:bg-[#1e1e1e] rounded-md flex items-center gap-2"
                             >
                                 <i className="fi fi-rs-comment-dots"></i> Hide Reply
                             </button> :
                             <button
                                 onClick={loadReplies}
-                                className="text-gray-500 p-2 px-3 hover:bg-gray-50 rounded-md flex items-center gap-2"
+                                className="text-[#555] dark:text-gray-300 p-2 px-3 hover:bg-[#f3f3f3] dark:hover:bg-[#1e1e1e] rounded-md flex items-center gap-2"
                             >
                                 <i className="fi fi-rs-comment-dots"></i> {children.length} Reply
                             </button>
diff --git a/frontend/src/components/CommentField.jsx b/frontend/src/components/CommentField.jsx
index 3350528ba..3becd7034 100644
--- a/frontend/src/components/CommentField.jsx
+++ b/frontend/src/components/CommentField.jsx
@@ -70,7 +70,7 @@ const CommentField = ({ action, index = undefined, replyingTo = undefined, setRe
             >
             </textarea>
             <button
-                className="btn-dark mt-5 px-10"
+                className="btn-dark dark:btn-light mt-5 px-10"
                 onClick={handleComment}
             >
                 {action}
diff --git a/frontend/src/components/Comments.jsx b/frontend/src/components/Comments.jsx
index 8b2832fc3..65680923e 100644
--- a/frontend/src/components/Comments.jsx
+++ b/frontend/src/components/Comments.jsx
@@ -41,7 +41,14 @@ const CommentsContainer = () => {
     }
 
     return (
-        <div className={"max-sm:w-full fixed " + (commentsWrapper ? "top-0 sm:right-0" : "top-[100%] sm:right-[-100%]") + " duration-700 max-sm:right-0 sm:top-0 w-[30%] min-w-[350px] h-full z-50 bg-white shadow-2xl p-8 px-16 overflow-y-auto overflow-x-hidden"}>
+        <div
+            className={
+                "max-sm:w-full fixed " +
+                (commentsWrapper ? "top-0 sm:right-0" : "top-[100%] sm:right-[-100%]") +
+                " duration-700 max-sm:right-0 sm:top-0 w-[30%] min-w-[350px] h-full z-50 " +
+                "bg-white dark:bg-[#121212] shadow-2xl dark:shadow-lg text-black dark:text-gray-200 p-8 px-16 overflow-y-auto overflow-x-hidden"
+            }
+        >
 
             <div className="relative">
                 <h1 className="font-medium text-xl">Comments</h1>
@@ -49,7 +56,7 @@ const CommentsContainer = () => {
 
                 <button
                     onClick={() => setCommentsWrapper(preVal => !preVal)}
-                    className="absolute top-0 right-0 flex justify-center items-center w-12 h-12 rounded-full bg-gray-100"
+                    className="absolute top-0 right-0 flex justify-center items-center w-12 h-12 rounded-full bg-gray-100 dark:bg-[#09090b]"
                 >
                     <i className="fi fi-br-cross text-2xl mt-1"></i>
                 </button>
diff --git a/frontend/src/components/InPageNavigation.jsx b/frontend/src/components/InPageNavigation.jsx
index cebf651a7..0c9119562 100644
--- a/frontend/src/components/InPageNavigation.jsx
+++ b/frontend/src/components/InPageNavigation.jsx
@@ -39,14 +39,14 @@ const InPageNavigation = ({ routes, defaultHidden = [], defaultActiveIndex = 0,
 
     return (
         <>
-            <div className="relative mb-8 bg-white border-b border-gray-200 flex flex-nowrap overflow-x-auto">
+            <div className="relative mb-8 bg-[#fafafa] dark:bg-[#09090b] border-b border-gray-200 flex flex-nowrap overflow-x-auto">
                 {
                     routes.map((route, i) => {
                         return (
                             <button
                                 ref={i === defaultActiveIndex ? activeTabRef : null}
                                 key={i}
-                                className={"p-4 px-5 capitalize " + (inPageNavIndex === i ? "text-black " : "text-dark-grey " + (defaultHidden.includes(route) ? "md:hidden" : ""))}
+                                className={"p-4 px-5 capitalize " + (inPageNavIndex === i ? "text-black dark:text-[#ededed] " : "text-dark-grey dark:text-[#a3a3a3] " + (defaultHidden.includes(route) ? "md:hidden" : ""))}
                                 onClick={(e) => { changePageState(e.target, i) }}
                             >
                                 {route}
diff --git a/frontend/src/components/LoadMoreData.jsx b/frontend/src/components/LoadMoreData.jsx
index dfaa2c108..7fe5246d0 100644
--- a/frontend/src/components/LoadMoreData.jsx
+++ b/frontend/src/components/LoadMoreData.jsx
@@ -4,7 +4,7 @@ const LoadMoreDataBtn = ({ state, fetchDataFun, additionalParam }) => {
         return (
             <button
                 onClick={() => fetchDataFun({ ...additionalParam, page: state.page + 1 })}
-                className="text-gray-800 p-2 px-3 hover:bg-gray-50 rounded-md flex items-center gap-2"
+                className="text-gray-800 dark:text-gray-200 p-2 px-3 rounded-md hover:bg-gray-100 dark:hover:bg-gray-800 flex items-center gap-2 transition-colors"
             >
                 Load More
             </button>
diff --git a/frontend/src/components/Navbar.jsx b/frontend/src/components/Navbar.jsx
index 5ac4407b9..df86b2176 100644
--- a/frontend/src/components/Navbar.jsx
+++ b/frontend/src/components/Navbar.jsx
@@ -3,6 +3,7 @@ import { Link, Outlet, useNavigate } from "react-router-dom";
 import { UserContext } from "../App";
 import UserNavigationPanel from "./UserNavigationPanel";
 import SubscribeModal from "./SubscribeModal";
+import ThemeToggle from "./ThemeToggle";
 import axios from "axios";
 
 const Navbar = () => {
@@ -58,26 +59,30 @@ const Navbar = () => {
         <>
             <nav className="navbar z-50">
                 <Link to="/" className="flex-none w-10">
-                    <img src="/logo.png" alt="" className="w-full" />
+                    <img src="/logo.png" alt="" className="w-full dark:invert" />
                 </Link>
 
-                <div className={"absolute bg-white w-full left-0 top-full mt-0.5 border-b border-gray-200 py-4 px-[5vw] md:border-0 md:relative md:inset-0 md:p-0 md:w-auto " + (searchBoxVisibility ? "show" : "hidden md:block")}
+                <div
+                    className={"absolute bg-[#fafafa] dark:bg-[#09090b] w-full left-0 top-full mt-0.5 border-b border-gray-200 dark:border-[#27272a] py-4 px-[5vw] md:border-0 md:relative md:inset-0 md:p-0 md:w-auto " +
+                        (searchBoxVisibility ? "show" : "hidden md:block")}
                 >
                     <input
                         type="text"
                         placeholder="Search"
-                        className="w-full md:w-auto bg-gray-100 p-4 pl-6 pr-[12%] md:pr-6 rounded-full placeholder:text-dark-grey md:pl-12"
+                        className="w-full md:w-auto bg-[#ffffff] dark:bg-[#18181b] p-4 pl-6 pr-[12%] md:pr-6 rounded-full placeholder:text-dark-grey dark:placeholder:text-gray-400 md:pl-12"
                         onKeyDown={handleSearch}
                     />
-                    <i className="fi fi-rr-search absolute right-[10%] md:pointer-events-none md:left-5 top-1/2 -translate-y-1/2 text-xl text-dark-grey"></i>
+                    <i className="fi fi-rr-search absolute right-[10%] md:pointer-events-none md:left-5 top-1/2 -translate-y-1/2 text-xl text-dark-grey dark:text-gray-400"></i>
                 </div>
 
                 <div className="flex items-center gap-3 md:gap-6 ml-auto">
-                    <button className="md:hidden bg-gray-100 w-12 h-12 rounded-full flex items-center justify-center" onClick={() => setSearchBoxVisibility(!searchBoxVisibility)}>
-                        <i className="fi fi-rr-search text-xl"></i>
+                    <button className="md:hidden bg-[#ffffff] dark:bg-[#18181b] w-12 h-12 rounded-full flex items-center justify-center" onClick={() => setSearchBoxVisibility(!searchBoxVisibility)}>
+                        <i className="fi fi-rr-search text-xl text-dark-grey dark:text-gray-400"></i>
                     </button>
 
-                    <Link to="/editor" className="hidden md:flex items-center gap-2 text-gray-700 hover:text-black hover:bg-gray-200 p-3 px-4 rounded-lg transition">
+                    <ThemeToggle />
+
+                    <Link to="/editor" className="hidden md:flex items-center gap-2 text-gray-700 dark:text-gray-300 hover:text-black dark:hover:text-white hover:bg-gray-200 dark:hover:bg-[#27272a] p-3 px-4 rounded-lg transition">
                         <i className="fi fi-rr-file-edit"></i>
                         <p>Write</p>
                     </Link>
@@ -86,7 +91,7 @@ const Navbar = () => {
                         access_token ?
                             <>
                                 <Link to="/dashboard/notifications">
-                                    <button className="w-12 h-12 rounded-full bg-gray-200 relative hover:bg-black/10">
+                                    <button className="w-12 h-12 rounded-full relative text-gray-700 dark:text-gray-300 hover:text-black dark:hover:text-white hover:bg-gray-200 dark:hover:bg-[#27272a]">
                                         <i className="fi fi-rr-bell text-2xl block mt-1"></i>
                                         {
                                             new_notification_available ?
@@ -112,15 +117,15 @@ const Navbar = () => {
                             <>
                                 <button
                                     onClick={toggleSubscribeModal}
-                                    className="text-gray-700 bg-gray-200 py-2 px-4 rounded-full transition cursor-pointer"
+                                    className="text-gray-700 dark:text-gray-300 hover:text-black dark:hover:text-white hover:bg-gray-200 dark:hover:bg-[#27272a] py-2 px-4 rounded-full transition cursor-pointer"
                                 >
                                     <i className="fi fi-rr-envelope-plus text-xl"></i>
                                 </button>
 
-                                <Link className="bg-black text-white py-2 px-5 rounded-full hover:bg-gray-800 transition" to="/login">
+                                <Link className="bg-black dark:bg-gray-200 text-white dark:text-gray-800 py-2 px-5 rounded-full hover:bg-gray-800 dark:hover:bg-[#ffffff] transition" to="/login">
                                     Login
                                 </Link>
-                                <Link className="bg-gray-200 text-gray-800 py-2 px-5 rounded-full hidden md:block hover:bg-gray-300 transition" to="/signup">
+                                <Link className="bg-gray-200 dark:bg-black text-gray-800 dark:text-white py-2 px-5 rounded-full hidden md:block hover:bg-gray-300 dark:hover:bg-[#27272a] transition" to="/signup">
                                     Sign Up
                                 </Link>
                             </>
diff --git a/frontend/src/components/NoData.jsx b/frontend/src/components/NoData.jsx
index 5c810903d..a9aac7609 100644
--- a/frontend/src/components/NoData.jsx
+++ b/frontend/src/components/NoData.jsx
@@ -1,6 +1,6 @@
 const NoDataMessage = ({ message }) => {
     return (
-        <div className="text-center w-full p-4 rounded-full bg-gray-50 mt-4">
+        <div className="text-center w-full p-4 rounded-full bg-gray-50 dark:bg-[#1a1a1a] text-gray-800 dark:text-gray-200 mt-4">
             <p>{message}</p>
         </div>
     )
diff --git a/frontend/src/components/NotificationCard.jsx b/frontend/src/components/NotificationCard.jsx
index 5bccb7a0f..5ecd454b1 100644
--- a/frontend/src/components/NotificationCard.jsx
+++ b/frontend/src/components/NotificationCard.jsx
@@ -50,7 +50,12 @@ const NotificationCard = ({ data, index, notificationState }) => {
                 <div className="w-full">
                     <h1 className="font-medium text-xl text-gray-500">
                         <span className="lg:inline-block hidden capitalize">{fullname}</span>
-                        <Link to={`/user/${username}`} className="mx-1 text-black underline">@{username}</Link>
+                        <Link
+                            to={`/user/${username}`}
+                            className="mx-1 text-black underline hover:text-blue-600 dark:text-white dark:hover:text-blue-400"
+                        >
+                            @{username}
+                        </Link>
                         <span className="font-normal">
                             {
                                 type === 'like' ? "liked your project" :
@@ -62,10 +67,13 @@ const NotificationCard = ({ data, index, notificationState }) => {
 
                     {
                         type === 'reply' ?
-                            <div className="p-4 mt-4 rounded-md bg-gray-100">
+                            <div className="p-4 mt-4 rounded-md bg-gray-100 dark:bg-gray-700">
                                 <p>{replied_on_comment.comment}</p>
                             </div> :
-                            <Link to={`/project/${project_id}`} className="font-medium text-gray-500 hover:underline line-clamp-1">
+                            <Link
+                                to={`/project/${project_id}`}
+                                className="font-medium text-gray-500 hover:underline line-clamp-1 dark:text-gray-300 dark:hover:text-blue-400"
+                            >
                                 {`"${title}"`}
                             </Link>
                     }
@@ -87,7 +95,7 @@ const NotificationCard = ({ data, index, notificationState }) => {
                             {
                                 !reply ?
                                     <button
-                                        className="underline hover:text-black"
+                                        className="underline hover:text-black dark:hover:text-white"
                                         onClick={handleReplyClick}
                                     >
                                         Reply
@@ -96,7 +104,7 @@ const NotificationCard = ({ data, index, notificationState }) => {
                             }
 
                             <button
-                                className="underline hover:text-black"
+                                className="underline hover:text-black dark:hover:text-white"
                                 onClick={(e) => handleDelete(comment._id, "comment", e.target)}
                             >
                                 Delete
@@ -116,17 +124,17 @@ const NotificationCard = ({ data, index, notificationState }) => {
 
             {
                 reply ?
-                    <div className="ml-20 p-5 bg-gray-100 mt-5 rounded-md">
+                    <div className="ml-20 p-5 bg-gray-100 dark:bg-gray-700 mt-5 rounded-md">
                         <div className="flex gap-3 mb-3">
                             <img src={author_profile_img} className="w-8 h-8 rounded-full" alt="" />
 
                             <div>
                                 <h1 className="font-medium text-xl text-gray-500">
-                                    <Link to={`/user/${author_username}`} className="mx-1 text-black underline">@{author_username}</Link>
+                                    <Link to={`/user/${author_username}`} className="mx-1 text-black dark:text-white underline">@{author_username}</Link>
 
                                     <span className="font-normal">replied to</span>
 
-                                    <Link to={`/user/${username}`} className="mx-1 text-black underline">@{username}</Link>
+                                    <Link to={`/user/${username}`} className="mx-1 text-black dark:text-white underline">@{username}</Link>
                                 </h1>
                             </div>
                         </div>
@@ -134,7 +142,7 @@ const NotificationCard = ({ data, index, notificationState }) => {
                         <p className="ml-14 font-gelasio text-xl my-2">{reply.comment}</p>
 
                         <button
-                            className="underline hover:text-black ml-14 mt-2"
+                            className="underline hover:text-black hover:dark:text-white ml-14 mt-2"
                             onClick={(e) => handleDelete(reply._id, "reply", e.target)}
                         >
                             Delete
diff --git a/frontend/src/components/ProjectEditor.jsx b/frontend/src/components/ProjectEditor.jsx
index e93f77c91..c3fd3802d 100644
--- a/frontend/src/components/ProjectEditor.jsx
+++ b/frontend/src/components/ProjectEditor.jsx
@@ -158,9 +158,9 @@ const ProjectEditor = () => {
         <>
             <nav className="navbar">
                 <Link to="/" className="flex-none w-10">
-                    <img src="logo.png" />
+                    <img src="logo.png" alt="" className="dark:invert" />
                 </Link>
-                <p className="max-md:hidden text-black line-clamp-1 w-full">
+                <p className="max-md:hidden text-black dark:text-white line-clamp-1 w-full">
                     {title.length ? title : "New Project"}
                 </p>
 
diff --git a/frontend/src/components/ProjectInteraction.jsx b/frontend/src/components/ProjectInteraction.jsx
index b29e65866..f6440c94e 100644
--- a/frontend/src/components/ProjectInteraction.jsx
+++ b/frontend/src/components/ProjectInteraction.jsx
@@ -59,19 +59,24 @@ const ProjectInteraction = () => {
                 <div className="flex gap-3 items-center">
                     <button
                         onClick={handleLike}
-                        className={"w-10 h-10 rounded-full flex items-center justify-center " + (islikedByUser ? "bg-red-100 text-red-500" : "bg-gray-100")}
+                        className={
+                            "w-10 h-10 rounded-full flex items-center justify-center transition-colors duration-200 " +
+                            (islikedByUser
+                                ? "bg-red-100 text-red-500 dark:bg-red-200 dark:text-red-600"
+                                : "bg-gray-100 text-gray-600 dark:bg-[#27272a] dark:text-gray-300")
+                        }
                     >
                         <i className={"fi " + (islikedByUser ? "fi-sr-heart" : "fi-rr-heart")}></i>
                     </button>
-                    <p className="text-xl text-gray-700">{total_likes}</p>
+                    <p className="text-xl text-gray-700 dark:text-gray-300">{total_likes}</p>
 
                     <button
                         onClick={() => setCommentsWrapper(preVal => !preVal)}
-                        className="w-10 h-10 rounded-full flex items-center justify-center bg-gray-100"
+                        className="w-10 h-10 rounded-full flex items-center justify-center transition-colors duration-200 bg-gray-100 text-gray-600 dark:bg-[#27272a] dark:text-gray-300"
                     >
                         <i className="fi fi-rr-comment-dots"></i>
                     </button>
-                    <p className="text-xl text-gray-700">{total_comments}</p>
+                    <p className="text-xl text-gray-700 dark:text-gray-300">{total_comments}</p>
                 </div>
 
                 <div className="flex gap-6 items-center">
diff --git a/frontend/src/components/PublishForm.jsx b/frontend/src/components/PublishForm.jsx
index 53740b9ef..917126e85 100644
--- a/frontend/src/components/PublishForm.jsx
+++ b/frontend/src/components/PublishForm.jsx
@@ -56,7 +56,7 @@ const PublishForm = () => {
         }
     }
 
-    const publichProject = (e) => {
+    const publishProject = (e) => {
 
         if (e.target.className.includes("disable")) {
             return;
@@ -129,7 +129,7 @@ const PublishForm = () => {
                     <p className="font-gelasio line-clamp-2 text-xl leading-7 mt-4">{des}</p>
                 </div>
 
-                <div className="border-gray-200 lg:border-1 lg:pl-8">
+                <div>
                     <p className="text-dark-grey mb-2 mt-9">Project Title</p>
                     <input type="text" placeholder="Project Title" defaultValue={title} className="input-box pl-4" onChange={handleProjectTitleChange} />
 
@@ -149,7 +149,12 @@ const PublishForm = () => {
                     <p className="text-dark-grey mb-2 mt-9">Topics - (Helps in searching and ranking your project post)</p>
 
                     <div className="relative input-box pl-2 py-2 pb-4">
-                        <input type="text" placeholder="Add topics" className="sticky input-box bg-white top-0 left-0 pl-4 mb-3 focus:bg-white" onKeyDown={handleKeyDown} />
+                        <input
+                            type="text"
+                            placeholder="Add topics"
+                            className="sticky input-box top-0 left-0 pl-4 mb-3 bg-white dark:bg-black"
+                            onKeyDown={handleKeyDown}
+                        />
                         {
                             tags.map((tag, i) => {
                                 return <Tag tag={tag} tagIndex={i} key={i} />
@@ -158,9 +163,12 @@ const PublishForm = () => {
                     </div>
                     <p className="mt-1 mb-4 text-dark-grey text-right">{tagLimit - tags.length} Tags left</p>
 
-                    <button className="btn-dark px-8"
-                        onClick={publichProject}
-                    >Publish</button>
+                    <button
+                        className="btn-dark px-8"
+                        onClick={publishProject}
+                    >
+                        Publish
+                    </button>
                 </div>
             </section>
         </AnimationWrapper>
diff --git a/frontend/src/components/SideNavBar.jsx b/frontend/src/components/SideNavBar.jsx
index 951bd3890..e9188dc7b 100644
--- a/frontend/src/components/SideNavBar.jsx
+++ b/frontend/src/components/SideNavBar.jsx
@@ -60,10 +60,13 @@ const SideNav = () => {
                         </div>
 
                         <div
-                            className={"min-w-[200px] h-[calc(100vh-80px-60px)] md:h-cover md:sticky top-24 overflow-y-auto p-6 md:pr-0 md:border-gray-100 md:border-r absolute max-md:top-[64px] bg-white max-md:w-[calc(100%+80px)] max-md:px-16 max-md:-ml-7 duration-500 " + (!showSideNav ? "max-md:opacity-0 max-md:pointer-events-none" : "opacity-100 pointer-events-auto")}
+                            className={
+                                "min-w-[200px] h-[calc(100vh-80px-60px)] md:h-cover md:sticky top-24 overflow-y-auto p-6 md:pr-0 md:border-r md:border-gray-100 dark:md:border-gray-800 absolute max-md:top-[64px] bg-[#fafafa] dark:bg-[#09090b] max-md:w-[calc(100%+80px)] max-md:px-16 max-md:-ml-7 duration-500 " + 
+                                (!showSideNav ? "max-md:opacity-0 max-md:pointer-events-none" : "opacity-100 pointer-events-auto")
+                            }
                         >
-                            <h1 className="text-xl text-gray-500 mb-3">Dashboard</h1>
-                            <hr className="border-gray-100 -ml-6 mb-8 mr-6" />
+                            <h1 className="text-xl text-gray-500 dark:text-gray-400 mb-3">Dashboard</h1>
+                            <hr className="border-gray-100 dark:border-gray-800 -ml-6 mb-8 mr-6" />
 
                             <NavLink
                                 to="/dashboard/projects"
@@ -97,8 +100,8 @@ const SideNav = () => {
                                 Write
                             </NavLink>
 
-                            <h1 className="text-xl text-gray-500 mt-20 mb-3">Settings</h1>
-                            <hr className="border-gray-100 -ml-6 mb-8 mr-6" />
+                            <h1 className="text-xl text-gray-500 dark:text-gray-400 mt-20 mb-3">Settings</h1>
+                            <hr className="border-gray-100 dark:border-gray-800 -ml-6 mb-8 mr-6" />
 
                             <NavLink
                                 to="/settings/edit-profile"
diff --git a/frontend/src/components/SubscribeModal.jsx b/frontend/src/components/SubscribeModal.jsx
index 82c43ec59..7d732ad33 100644
--- a/frontend/src/components/SubscribeModal.jsx
+++ b/frontend/src/components/SubscribeModal.jsx
@@ -43,16 +43,16 @@ const SubscribeModal = ({ onClose }) => {
         <div className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-100 p-4">
             <Toaster />
 
-            <form id="subscribeFormEle" className="bg-white rounded-lg max-w-md w-full p-6 relative">
+            <form id="subscribeFormEle" className="bg-white dark:bg-black rounded-lg max-w-md w-full p-6 relative">
                 <button
                     onClick={onClose}
-                    className="absolute top-4 right-4 text-black py-3 px-4 rounded-full hover:bg-gray-100 transition"
+                    className="absolute top-4 right-4 text-black dark:text-white py-3 px-4 rounded-full hover:bg-gray-100 hover:dark:bg-[#1f1f23] transition"
                 >
                     <i className="fi fi-rr-cross text-xl"></i>
                 </button>
 
                 <h2 className="text-2xl font-bold mb-2">Subscribe to Newsletter</h2>
-                <p className="text-gray-600 mb-6">
+                <p className="text-gray-700 dark:text-gray-300 mb-6">
                     Stay updated with our latest articles, projects, and announcements.
                 </p>
 
diff --git a/frontend/src/components/Tags.jsx b/frontend/src/components/Tags.jsx
index d8649828a..fc207e60d 100644
--- a/frontend/src/components/Tags.jsx
+++ b/frontend/src/components/Tags.jsx
@@ -27,13 +27,20 @@ const Tag = ({ tag, tagIndex }) => {
     }
 
     return (
-        <div className="relative p-2 mt-2 mr-2 px-5 bg-white rounded-full inline-block hover:bg-opacity-50 pr-10">
-            <p className="outline-none" onKeyDown={handleTagEdit} onClick={addEditable}>{tag}</p>
+        <div className="relative p-2 mt-2 mr-2 px-5 bg-white dark:bg-black rounded-full inline-block hover:bg-opacity-50 pr-10">
+            <p
+                className="outline-none cursor-pointer"
+                onKeyDown={handleTagEdit}
+                onClick={addEditable}
+            >
+                {tag}
+            </p>
             <button
-                className="mt-[2px] rounded-full absolute right-3 top-1/2 -translate-y-1/2"
+                className="mt-[2px] rounded-full absolute right-3 top-1/2 transform -translate-y-1/2 bg-transparent border-0 p-0"
                 onClick={handleTagDelete}
+                aria-label="Delete tag"
             >
-                <i className="fi fi-br-cross text-xl pointer-events-none"></i>
+                <i className="fi fi-br-cross text-xl text-gray-600 hover:text-red-500"></i>
             </button>
         </div>
     );
diff --git a/frontend/src/components/ThemeToggle.jsx b/frontend/src/components/ThemeToggle.jsx
new file mode 100644
index 000000000..f3f8cb563
--- /dev/null
+++ b/frontend/src/components/ThemeToggle.jsx
@@ -0,0 +1,68 @@
+import { useTheme } from '../context/ThemeContext';
+import { useState, useEffect, useRef } from 'react';
+
+const ThemeToggle = () => {
+    const { theme, setThemeMode } = useTheme();
+    const [isOpen, setIsOpen] = useState(false);
+    const dropdownRef = useRef();
+
+    const themes = [
+        { name: 'Light', value: 'light', icon: 'fi fi-rr-sun' },
+        { name: 'Dark', value: 'dark', icon: 'fi fi-rr-moon' },
+        { name: 'System', value: 'system', icon: 'fi fi-rr-laptop' },
+    ];
+
+    useEffect(() => {
+        const handleClickOutside = (e) => {
+            if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
+                setIsOpen(false);
+            }
+        };
+        document.addEventListener('mousedown', handleClickOutside);
+        return () => document.removeEventListener('mousedown', handleClickOutside);
+    }, []);
+
+    return (
+        <div className="relative" ref={dropdownRef}>
+            <button
+                onClick={() => setIsOpen((prev) => !prev)}
+                className="p-2 rounded-full hover:bg-gray-200 dark:hover:bg-[#27272a] transition-colors"
+                aria-label="Theme settings"
+            >
+                <i
+                    className={`text-xl ${theme === 'system'
+                        ? 'fi fi-rr-laptop'
+                        : theme === 'dark'
+                            ? 'fi fi-rr-moon inline-block rotate-[-45deg]'
+                            : 'fi fi-rr-sun'
+                        }`}
+                ></i>
+            </button>
+
+            {isOpen && (
+                <div className="absolute right-0 mt-2 w-48 rounded-md shadow-lg bg-white dark:bg-[#27272a] z-50">
+                    <div className="py-1">
+                        {themes.map(({ name, value, icon }) => (
+                            <button
+                                key={value}
+                                onClick={() => {
+                                    setThemeMode(value);
+                                    setIsOpen(false);
+                                }}
+                                className={`flex items-center w-full px-4 py-2 text-sm transition-colors ${theme === value
+                                    ? 'bg-gray-100 dark:bg-gray-700 text-black dark:text-white'
+                                    : 'text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700'
+                                    }`}
+                            >
+                                <i className={`${icon} mr-3 ${icon == "fi fi-rr-moon" ? "transform -rotate-45" : ""}`}></i>
+                                {name}
+                            </button>
+                        ))}
+                    </div>
+                </div>
+            )}
+        </div>
+    );
+};
+
+export default ThemeToggle;
diff --git a/frontend/src/components/UserNavigationPanel.jsx b/frontend/src/components/UserNavigationPanel.jsx
index a87eec0a6..dca2c27ab 100644
--- a/frontend/src/components/UserNavigationPanel.jsx
+++ b/frontend/src/components/UserNavigationPanel.jsx
@@ -17,7 +17,7 @@ const UserNavigationPanel = () => {
             className="absolute right-0 z-50"
             transition={{ duration: 0.2 }}
         >
-            <div className="bg-white absolute right-0 border border-gray-200 w-60 duration-200">
+            <div className="bg-[#fafafa] dark:bg-[#09090b] absolute right-0 border border-[#e5e7eb] dark:border-[#27272a] w-60 duration-200">
                 <Link to={"/editor"} className="flex gap-2 link md:hidden pl-8 py-4">
                     <i className="fi fi-rr-file-edit"></i>
                     <p>Write</p>
@@ -38,7 +38,7 @@ const UserNavigationPanel = () => {
                 <span className="absolute border-t border-gray-200 w-[100%]"></span>
 
                 <button
-                    className="text-left p-4 hover:bg-gray-200 w-full pl-8 py-4 cursor-pointer"
+                    className="text-left w-full pl-8 py-4 cursor-pointer hover:bg-gray-200 dark:hover:bg-[#27272a] text-gray-800 dark:text-gray-100"
                     onClick={signOutUser}
                 >
                     <h1 className="font-bold text-xl mg-1">Sign Out</h1>
diff --git a/frontend/src/context/ThemeContext.jsx b/frontend/src/context/ThemeContext.jsx
new file mode 100644
index 000000000..8eb44bf8b
--- /dev/null
+++ b/frontend/src/context/ThemeContext.jsx
@@ -0,0 +1,60 @@
+import { createContext, useContext, useEffect, useState } from 'react';
+
+const ThemeContext = createContext();
+export const useTheme = () => useContext(ThemeContext);
+
+export const ThemeProvider = ({ children }) => {
+    const [theme, setTheme] = useState(() => localStorage.getItem('theme') || 'system');
+
+    useEffect(() => {
+        localStorage.setItem('theme', theme);
+
+        const root = document.documentElement;
+
+        const applyTheme = () => {
+            const isSystemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
+            const darkMode = theme === 'dark' || (theme === 'system' && isSystemDark);
+
+            if (darkMode) {
+                root.classList.add('dark');
+            } else {
+                root.classList.remove('dark');
+            }
+        };
+
+        applyTheme();
+
+        // If using system theme, listen for changes
+        let mediaQuery;
+        const handleChange = (e) => {
+            if (theme === 'system') {
+                applyTheme();
+            }
+        };
+
+        if (theme === 'system') {
+            mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
+            mediaQuery.addEventListener('change', handleChange);
+        }
+
+        return () => {
+            if (mediaQuery) {
+                mediaQuery.removeEventListener('change', handleChange);
+            }
+        };
+    }, [theme]);
+
+    const setThemeMode = (newTheme) => {
+        setTheme(newTheme);
+    };
+
+    const isDarkMode =
+        theme === 'dark' ||
+        (theme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);
+
+    return (
+        <ThemeContext.Provider value={{ theme, setThemeMode, isDarkMode }}>
+            {children}
+        </ThemeContext.Provider>
+    );
+};
diff --git a/frontend/src/index.css b/frontend/src/index.css
index cd78f15d5..3e4977fb3 100644
--- a/frontend/src/index.css
+++ b/frontend/src/index.css
@@ -1,11 +1,35 @@
 @import url('https://fonts.googleapis.com/css2?family=Gelasio&family=Inter:wght@400;500&display=swap');
 @import "@flaticon/flaticon-uicons/css/all/all";
 @import "tailwindcss";
+@custom-variant dark (&:where(.dark, .dark *));
 
 .font-gelasio {
     font-family: 'Gelasio', serif;
 }
 
+:root {
+    /* Light Theme */
+    --bg-color: #FAFAFA;
+    --bg-secondary-color: #F0F0F0;
+    --text-color: #111111;
+    --text-secondary-color: #444444;
+    --accent-color: #3B82F6;
+    --border-color: #E5E7EB;
+    --card-bg-color: #FFFFFF;
+    --link-color: #2563EB;
+}
+
+[data-theme="dark"] {
+    --bg-color: #09090B;
+    --bg-secondary-color: #1F1F23;
+    --text-color: #EDEDED;
+    --text-secondary-color: #A3A3A3;
+    --accent-color: #60A5FA;
+    --border-color: #27272A;
+    --card-bg-color: #18181B;
+    --link-color: #3B82F6;
+}
+
 @layer components {
     * {
         @apply m-0 p-0 box-border text-base duration-100;
@@ -16,7 +40,7 @@
     }
 
     body {
-        @apply font-normal text-black;
+        @apply font-normal text-[#111111] dark:text-[#ededed] bg-[#fafafa] dark:bg-[#09090b] transition-colors duration-300;
     }
 
     i {
@@ -32,7 +56,7 @@
     }
 
     .navbar {
-        @apply z-10 sticky top-0 flex items-center gap-12 w-full px-[5vw] py-5 h-[80px] border-b border-gray-200 bg-white;
+        @apply z-10 sticky top-0 flex items-center gap-12 w-full px-[5vw] py-5 h-[80px] border-b border-[#e5e7eb] dark:border-[#27272a] bg-[#fafafa] dark:bg-[#09090b];
     }
 
     .h-cover {
@@ -44,20 +68,20 @@
     }
 
     .btn-dark {
-        @apply whitespace-nowrap bg-black text-white rounded-full py-3 px-6 text-xl capitalize hover:opacity-80;
+        @apply whitespace-nowrap rounded-full bg-[#1f1f1f] dark:bg-[#e4e4e7] text-[#f1f1f1] dark:text-[#1a1a1a] hover:opacity-80 py-3 px-6 text-xl capitalize;
     }
 
     .btn-light {
-        @apply whitespace-nowrap rounded-full py-3 px-6 text-xl capitalize hover:opacity-80 bg-gray-200 text-black;
+        @apply whitespace-nowrap rounded-full bg-[#f4f4f5] dark:bg-[#1a1a1d] text-[#1a1a1a] dark:text-[#f4f4f5] hover:opacity-80 py-3 px-6 text-xl capitalize;
     }
 
     .input-box {
-        @apply w-[100%] rounded-md p-4 bg-gray-200 pl-12 border border-gray-200 focus:bg-transparent placeholder:text-black;
+        @apply w-[100%] rounded-md p-4 bg-[#fafafa] dark:bg-[#09090b] pl-12 border border-[#e5e7eb] dark:border-[#27272a] focus:bg-transparent placeholder:text-black dark:placeholder:text-white;
     }
 
     input:disabled,
     input:disabled~.input-icon {
-        @apply opacity-50;
+        @apply opacity-50 dark:opacity-100;
     }
 
     .input-icon {
@@ -65,7 +89,7 @@
     }
 
     .link {
-        @apply text-gray-600 hover:text-black hover:bg-gray-200 p-3 px-4 block opacity-75;
+        @apply text-[#444444] dark:text-[#a3a3a3] hover:text-[#111111] hover:bg-[#ededed] p-3 px-4 block opacity-75;
     }
 
     .hide {
@@ -77,11 +101,11 @@
     }
 
     .sidebar-link {
-        @apply flex gap-4 items-center py-5 text-gray-600 hover:text-black;
+        @apply flex gap-4 items-center py-5 text-[#444444] dark:text-[#a3a3a3] hover:text-[#111111] hover:dark:text-[#ededed];
     }
 
     .sidebar-link.active {
-        @apply text-black border-r-2 border-black pl-6 bg-gray-50 -ml-6 md:rounded-tl-lg md:rounded-bl-lg max-md:border-none;
+        @apply text-[#111111] dark:text-[#ededed] border-r-2 border-[#e5e7eb] dark:border-[#27272a] pl-6 bg-[#f0f0f0] dark:bg-[#1f1f23] -ml-6 md:rounded-tl-lg md:rounded-bl-lg max-md:border-none;
     }
 
     #textEditor h2,
@@ -101,11 +125,11 @@
 
     #textEditor a,
     .project-page-content a {
-        @apply text-purple-600 underline hover:opacity-50;
+        @apply text-[#111111] dark:text-[#ededed] underline hover:opacity-50;
     }
 
     .tag {
-        @apply p-2 bg-gray-200 rounded-full px-4 capitalize;
+        @apply p-2 bg-[#09090b] dark:bg-[#fafafa] text-[#ededed] dark:text-[#111111] rounded-full px-4 capitalize;
     }
 
     .project-title {
@@ -113,7 +137,7 @@
     }
 
     .project-index {
-        @apply text-4xl sm:text-3xl lg:text-5xl font-bold text-gray-300 leading-none;
+        @apply text-4xl sm:text-3xl lg:text-5xl font-bold text-[#111111] dark:text-[#ededed] leading-none;
     }
 }
 
diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx
index 2898346ee..5fc3b9e19 100644
--- a/frontend/src/main.jsx
+++ b/frontend/src/main.jsx
@@ -3,11 +3,14 @@ import { createRoot } from 'react-dom/client'
 import { BrowserRouter } from 'react-router-dom'
 import './index.css'
 import App from './App.jsx'
+import { ThemeProvider } from './context/ThemeContext.jsx'
 
 createRoot(document.getElementById('root')).render(
   <StrictMode>
     <BrowserRouter>
-      <App />
+      <ThemeProvider>
+        <App />
+      </ThemeProvider>
     </BrowserRouter>
   </StrictMode>,
 )
diff --git a/frontend/src/pages/404.jsx b/frontend/src/pages/404.jsx
index c5f433eb8..8c9bd2b38 100644
--- a/frontend/src/pages/404.jsx
+++ b/frontend/src/pages/404.jsx
@@ -4,12 +4,15 @@ const PageNotFound = () => {
     return (
         <section className="h-cover relative p-10 flex flex-col items-center gap-20 text-center">
             <img src="/404.png" alt="" className="select-none border-2 border-gray-200 w-144 aspect-video object-cover rounded" />
-            <h1 className="text-4xl font-gelasio leading-7">Page not found</h1>
-            <p className="text-gray-600 text-xl leading-7 -mt-8">The page you are looking for does not exists. Head back to the <Link to="/" className="text-black underline">home page</Link>.</p>
+            <h1 className="text-4xl font-gelasio leading-7 text-black dark:text-white">Page not found</h1>
+            <p className="text-gray-600 dark:text-gray-400 text-xl leading-7 -mt-8">
+                The page you are looking for does not exist. Head back to the{' '}
+                <Link to="/" className="text-black dark:text-white underline">home page</Link>.
+            </p>
 
-            <div className="mt-auto">
-                <img src="/full-logo.svg" alt="" className="h-8 object-contain block mx-auto select-none" />
-                <p className="mt-5 text-gray-600">Read millions of projects script around the world.</p>
+            <div className="mt-auto text-center">
+                <img src="/full-logo.svg" alt="Logo" className="h-8 object-contain mx-auto select-none dark:invert" />
+                <p className="mt-5 text-gray-600 dark:text-gray-400">Read millions of project scripts around the world.</p>
             </div>
         </section>
     )
diff --git a/frontend/src/pages/Home.jsx b/frontend/src/pages/Home.jsx
index 86d4c802f..f7394436d 100644
--- a/frontend/src/pages/Home.jsx
+++ b/frontend/src/pages/Home.jsx
@@ -139,7 +139,7 @@ const Home = () => {
                                 {
                                     categories.map((category, i) => {
                                         return (
-                                            <button key={i} className={"tag " + (pageState === category ? "bg-black text-white " : "")} onClick={loadProjectsByCategory}>
+                                            <button key={i} className={"tag " + (pageState === category ? "bg-[#f0f0f0] dark:bg-[#18181b] text-[#444444] dark:text-[#a3a3a3] " : "")} onClick={loadProjectsByCategory}>
                                                 {category}
                                             </button>
                                         )
diff --git a/frontend/src/pages/ManageProjects.jsx b/frontend/src/pages/ManageProjects.jsx
index a21a1f773..0cba0327a 100644
--- a/frontend/src/pages/ManageProjects.jsx
+++ b/frontend/src/pages/ManageProjects.jsx
@@ -92,7 +92,7 @@ const ManageProjects = () => {
             <div className="relative max-md:mt-5 md:mt-8 mb-10">
                 <input
                     type="search"
-                    className="w-full bg-gray-100 p-4 pl-12 pr-6 rounded-full placeholder:text-gray-500"
+                    className="w-full bg-gray-100 dark:bg-[#1f1f1f] text-black dark:text-white p-4 pl-12 pr-6 rounded-full placeholder:text-gray-500 dark:placeholder:text-gray-400"
                     placeholder="Search Projects"
                     onChange={handleChange}
                     onKeyDown={handleSearch}
diff --git a/frontend/src/pages/Project.jsx b/frontend/src/pages/Project.jsx
index 8a384b7d6..27bd1e041 100644
--- a/frontend/src/pages/Project.jsx
+++ b/frontend/src/pages/Project.jsx
@@ -84,11 +84,15 @@ const ProjectPage = () => {
 
                         <div className="max-w-[900px] center py-10 max-lg:px-[5vw]">
                             <div className="my-8 flex max-sm:flex-col justify-between">
-                                <h2>{title}</h2>
+                                <h2 className={`${projectUrl && repository ? "max-w-[60%]" : "max-w-[80%]"
+                                    } truncate whitespace-nowrap overflow-hidden`}
+                                >
+                                    {title}
+                                </h2>
                                 <div className="flex gap-4">
                                     {
                                         projectUrl ?
-                                            <Link to={projectUrl} className="btn-light rounded flex gap-2 items-center">
+                                            <Link to={projectUrl} className="btn-dark dark:btn-light rounded flex gap-2 items-center">
                                                 <i className="fi fi-rr-link"></i>
                                                 Live URL
                                             </Link>
@@ -96,7 +100,7 @@ const ProjectPage = () => {
                                     }
                                     {
                                         repository ?
-                                            <Link to={repository} className="btn-light rounded flex gap-2 items-center">
+                                            <Link to={repository} className="btn-dark dark:btn-light rounded flex gap-2 items-center">
                                                 <i className="fi fi-brands-github"></i>
                                                 GitHub
                                             </Link>
@@ -116,7 +120,7 @@ const ProjectPage = () => {
                                     </p>
                                 </div>
 
-                                <p className="text-gray-700 opacity-75 max-sm:mt-6 max-sm:ml-12 max-sm:pl-5">Published on {getDay(publishedAt)}</p>
+                                <p className="text-gray-700 dark:text-gray-200 opacity-75 max-sm:mt-6 max-sm:ml-12 max-sm:pl-5">Published on {getDay(publishedAt)}</p>
                             </div>
 
                             <ProjectInteraction />
diff --git a/frontend/src/pages/UserAuthForm.jsx b/frontend/src/pages/UserAuthForm.jsx
index 40df3fb21..ac208c426 100644
--- a/frontend/src/pages/UserAuthForm.jsx
+++ b/frontend/src/pages/UserAuthForm.jsx
@@ -112,22 +112,15 @@ const UserAuthForm = ({ type }) => {
                             {type === "login" ? "Login" : "Sign Up"}
                         </button>
 
-                        {
-                            type === "login" ?
-                                <p className="mt-6 text-gray-700 text-xl text-center">
-                                    Don't have an account ?
-                                    <Link to="/signup" className="text-black text-xl ml-1 underline">
-                                        Join us today
-                                    </Link>
-                                </p>
-                                :
-                                <p className="mt-6 text-gray-700 text-xl text-center">
-                                    Already a member ?
-                                    <Link to="/login" className="text-black text-xl ml-1 underline">
-                                        Sign in here
-                                    </Link>
-                                </p>
-                        }
+                        <p className="mt-10 text-[#a3a3a3] text-xl text-center">
+                            {type === "login" ? "Don't have an account ?" : "Already a member ?"}
+                            <Link
+                                to={type === "login" ? "/signup" : "/login"}
+                                className="text-black dark:text-[#ededed] text-xl ml-1 underline"
+                            >
+                                {type === "login" ? "Join us today" : "Sign in here"}
+                            </Link>
+                        </p>
                     </form>
                 </section>
             </AnimationWrapper>


Reviews:
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR implements dark mode support throughout the frontend by introducing a ThemeContext and a ThemeToggle component, as well as updating various UI components to adapt to light and dark themes. Key changes include:
- Integration of a ThemeProvider in main.jsx and creation of ThemeContext for handling theme state.
- Updates to UI components (UserAuthForm, Navbar, InPageNavigation) to include dark mode compatible CSS classes.
- Addition of a new ThemeToggle component for user-controlled theme switching.

### Reviewed Changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.

<details>
<summary>Show a summary per file</summary>

| File                                  | Description                                                  |
| ------------------------------------- | ------------------------------------------------------------ |
| frontend/src/pages/UserAuthForm.jsx   | Updated sign-in/up elements to adjust for dark mode styling. |
| frontend/src/main.jsx                  | Wrapped the App with ThemeProvider.                          |
| frontend/src/context/ThemeContext.jsx  | Created a theme context to persist and manage theme state.    |
| frontend/src/components/ThemeToggle.jsx| New component implemented to toggle between themes.          |
| frontend/src/components/Navbar.jsx     | Modified Navbar UI to support dark mode elements and themes.   |
| frontend/src/components/InPageNavigation.jsx | Updated navigation styling with dark mode conditional classes.  |
</details>


<details>
<summary>Files not reviewed (1)</summary>

* **frontend/src/index.css**: Language not supported
</details>

<details>
<summary>Comments suppressed due to low confidence (1)</summary>

**frontend/src/context/ThemeContext.jsx:16**
* [nitpick] To improve clarity, consider consolidating the theme and isDarkMode state updates into a single effect, as the relationship between them is interdependent.
```
const [isDarkMode, setIsDarkMode] = useState(() => { if (theme === 'system') { return window.matchMedia('(prefers-color-scheme: dark)').matches } return theme === 'dark'; });
```
</details>


state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-05T19:12:39Z
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR introduces dark mode support across the frontend by updating styling and adding a theme toggle along with a ThemeProvider context. Key changes include:
- Wrapping the main app component with a ThemeProvider for theme management.
- Updating component styles (navbar, buttons, modals, etc.) to support light, dark, and system modes.
- Adding a new ThemeToggle component to allow users to switch themes.

### Reviewed Changes

Copilot reviewed 24 out of 25 changed files in this pull request and generated no comments.

<details>
<summary>Show a summary per file</summary>

| File | Description |
| ---- | ----------- |
| frontend/src/main.jsx | Wrapped App with ThemeProvider for theme switching. |
| frontend/src/context/ThemeContext.jsx | Added ThemeContext to manage theme state and update dark mode classes. |
| frontend/src/components/UserNavigationPanel.jsx | Updated dark mode styles and button hover effects. |
| frontend/src/components/ThemeToggle.jsx | New component for toggling between light, dark, and system themes. |
| frontend/src/components/Tags.jsx | Adjusted styles to support dark mode for tag elements. |
| frontend/src/components/SubscribeModal.jsx | Revised styles for dark mode in modal and button transitions. |
| frontend/src/components/SideNavBar.jsx | Updated sidebar styling for consistent dark mode appearance. |
| frontend/src/components/PublishForm.jsx | Modified form styles and button structure with dark mode support. |
| frontend/src/components/ProjectInteraction.jsx | Updated styles for interaction buttons in dark mode. |
| frontend/src/components/ProjectEditor.jsx | Added dark mode support in header elements. |
| frontend/src/components/NotificationCard.jsx | Revised link and background styling for dark mode. |
| frontend/src/components/NoData.jsx | Adjusted no-data message colors for dark theme. |
| frontend/src/components/Navbar.jsx | Integrated ThemeToggle and updated navbar styling for dark mode. |
| frontend/src/components/LoadMoreData.jsx | Updated loading button styles to include dark mode colors. |
| frontend/src/components/InPageNavigation.jsx | Updated navigation styling for dark background consistency. |
| frontend/src/components/Comments.jsx | Tweaked comments container classes for dark mode. |
| frontend/src/components/CommentField.jsx | Updated button classes to support dark mode variations. |
| frontend/src/components/CommentCard.jsx | Revised reply and delete button styles for dark mode. |
| frontend/src/components/AboutUser.jsx | Updated icon and text colors to improve dark mode appearance. |
</details>


<details>
<summary>Files not reviewed (1)</summary>

* **frontend/src/index.css**: Language not supported
</details>

<details>
<summary>Comments suppressed due to low confidence (2)</summary>

**frontend/src/components/PublishForm.jsx:165**
* It appears 'publichProject' is misspelled; consider renaming it to 'publishProject' for clarity and consistency.
```
onClick={publichProject}
```
**frontend/src/components/UserNavigationPanel.jsx:44**
* [nitpick] The class 'mg-1' might be a typo; consider using a valid margin utility class such as 'm-1'.
```
<h1 className="font-bold text-xl mg-1">Sign Out</h1>
```
</details>


state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T16:26:24Z
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR introduces dark mode theme support across the frontend along with some UI style updates and minor bug fixes.  
- Implements a theme toggle using a new ThemeContext provider.  
- Applies dark mode class variants throughout multiple components.  
- Fixes a naming typo in the PublishForm component.

### Reviewed Changes

Copilot reviewed 24 out of 25 changed files in this pull request and generated 1 comment.

<details>
<summary>Show a summary per file</summary>

| File                                    | Description                                                     |
| --------------------------------------- | --------------------------------------------------------------- |
| frontend/src/main.jsx                    | Wraps the app with ThemeProvider                                |
| frontend/src/context/ThemeContext.jsx    | Provides dark mode functionality with system and manual modes     |
| frontend/src/components/UserNavigationPanel.jsx | Updates UI with dark mode styles; contains a potential class typo   |
| frontend/src/components/ThemeToggle.jsx  | Introduces a theme toggle button with dark mode icons and transitions |
| frontend/src/components/Tags.jsx         | Adds dark mode variants and accessibility improvements            |
| frontend/src/components/SubscribeModal.jsx  | Updates modal styles to support dark mode                        |
| frontend/src/components/SideNavBar.jsx   | Applies dark mode class tweaks for improved styling               |
| frontend/src/components/PublishForm.jsx  | Renames a function for clarity and updates dark mode styling        |
| frontend/src/components/ProjectInteraction.jsx | Updates like and comment button styles for dark mode support        |
| frontend/src/components/ProjectEditor.jsx     | Adds dark mode adjustments to logo and title styles               |
| frontend/src/components/NotificationCard.jsx  | Enhances dark mode styles in notification links and cards           |
| frontend/src/components/NoData.jsx       | Adds dark mode styling to the no-data message                      |
| frontend/src/components/Navbar.jsx       | Integrates ThemeToggle and updates search and logo elements for dark mode |
| frontend/src/components/LoadMoreData.jsx | Tweaks button styles to adapt to dark mode                          |
| frontend/src/components/InPageNavigation.jsx | Updates tab navigation with dark mode color variants                |
| frontend/src/components/Comments.jsx     | Adds dark mode backdrop and text color adjustments for comments       |
| frontend/src/components/CommentField.jsx | Updates button styling for dark mode                              |
| frontend/src/components/CommentCard.jsx  | Adjusts dark mode styles for reply and delete actions               |
| frontend/src/components/AboutUser.jsx    | Improves icon styling with dark mode variants                        |
</details>


<details>
<summary>Files not reviewed (1)</summary>

* **frontend/src/index.css**: Language not supported
</details>

<details>
<summary>Comments suppressed due to low confidence (1)</summary>

**frontend/src/components/UserNavigationPanel.jsx:41**
* [nitpick] The utility class 'mg-1' does not appear to be a standard Tailwind CSS class. Consider verifying if it is intentional or if it should be replaced with a standard margin class such as 'm-1'.
```
<h1 className="font-bold text-xl mg-1">Sign Out</h1>
```
</details>


state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T16:29:29Z

Review comments:
diff_hunk: @@ -39,14 +39,14 @@ const InPageNavigation = ({ routes, defaultHidden = [], defaultActiveIndex = 0,
 
     return (
         <>
-            <div className="relative mb-8 bg-white border-b border-gray-200 flex flex-nowrap overflow-x-auto">
+            <div className="relative mb-8 bg-white dark:bg-[#09090b] border-b border-gray-200 flex flex-nowrap overflow-x-auto">
                 {
                     routes.map((route, i) => {
                         return (
                             <button
                                 ref={i === defaultActiveIndex ? activeTabRef : null}
                                 key={i}
-                                className={"p-4 px-5 capitalize " + (inPageNavIndex === i ? "text-black " : "text-dark-grey " + (defaultHidden.includes(route) ? "md:hidden" : ""))}
+                                className={"p-4 px-5 capitalize " + (inPageNavIndex === i ? "text-black dark:text-[#ededed] " : "text-dark-grey dark:text-[#a3a3a3] " + (defaultHidden.includes(route) ? "md:hidden" : ""))}
path: frontend/src/components/InPageNavigation.jsx
user: login: Copilot
body: [nitpick] Consider using a utility such as 'classnames' to improve conditional CSS class concatenation readability in this line.
created_at: 2025-05-05T19:12:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -58,26 +59,30 @@ const Navbar = () => {
         <>
             <nav className="navbar z-50">
                 <Link to="/" className="flex-none w-10">
-                    <img src="/logo.png" alt="" className="w-full" />
+                    <img src="/logo.png" alt="" className="w-full dark:invert" />
path: frontend/src/components/Navbar.jsx
user: login: Copilot
body: [nitpick] Consider adding a descriptive alt text for the logo image to improve accessibility, unless the image is intended to be purely decorative.
```suggestion
                    <img src="/logo.png" alt="Website Logo" className="w-full dark:invert" />
```
created_at: 2025-05-05T19:12:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -58,26 +59,30 @@ const Navbar = () => {
         <>
             <nav className="navbar z-50">
                 <Link to="/" className="flex-none w-10">
-                    <img src="/logo.png" alt="" className="w-full" />
+                    <img src="/logo.png" alt="" className="w-full dark:invert" />
path: frontend/src/components/Navbar.jsx
user: login: Copilot
body: The logo image has an empty alt attribute; consider providing a descriptive alt text for better accessibility.
```suggestion
                    <img src="/logo.png" alt="Website Logo" className="w-full dark:invert" />
```
created_at: 2025-05-06T16:29:29Z
author_association: CONTRIBUTOR

PR comments:
user: login: vercel[bot]
created_at: 2025-05-05T19:12:04Z
body: [vc]: #id1BHZ8VGaD5HTJCEMXdjuoCoVTBHpdQEDQniYEiJYw=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJwanQtYmxvZyIsImxpdmVGZWVkYmFjayI6eyJyZXNvbHZlZCI6MCwidW5yZXNvbHZlZCI6MCwidG90YWwiOjAsImxpbmsiOiJwanQtYmxvZy1naXQtZmVhdC1kYXJrLW1vZGUtYXZkaGVzaHZhcnNobmV5cy1wcm9qZWN0cy52ZXJjZWwuYXBwIn0sImluc3BlY3RvclVybCI6Imh0dHBzOi8vdmVyY2VsLmNvbS9hdmRoZXNodmFyc2huZXlzLXByb2plY3RzL3BqdC1ibG9nLzl2UHF6Wlh6clNlSE16UFR6aGtCTlJBRm44R1EiLCJwcmV2aWV3VXJsIjoicGp0LWJsb2ctZ2l0LWZlYXQtZGFyay1tb2RlLWF2ZGhlc2h2YXJzaG5leXMtcHJvamVjdHMudmVyY2VsLmFwcCIsIm5leHRDb21taXRTdGF0dXMiOiJERVBMT1lFRCIsInJvb3REaXJlY3RvcnkiOiJmcm9udGVuZCJ9XX0=
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **pjt-blog** | ✅ Ready ([Inspect](https://vercel.com/avdheshvarshneys-projects/pjt-blog/9vPqzZXzrSeHMzPTzhkBNRAFn8GQ)) | [Visit Preview](https://pjt-blog-git-feat-dark-mode-avdheshvarshneys-projects.vercel.app) | 💬 [**Add feedback**](https://vercel.live/open-feedback/pjt-blog-git-feat-dark-mode-avdheshvarshneys-projects.vercel.app?via=pr-comment-feedback-link) | May 6, 2025 4:29pm |


author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-05T19:12:11Z
body: Thank you for submitting your pull request! We'll review it as soon as possible. For further communication, join our discord server https://discord.gg/tSqtvHUJzE.
author_association: NONE