diff --git a/package-lock.json b/package-lock.json
index 2d90f7af..2d925f2d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,8 +16,10 @@
"dompurify": "^3.2.6",
"framer-motion": "^12.17.3",
"lucide-react": "^0.476.0",
+ "next-themes": "^0.4.6",
"react": "^19.1.0",
"react-dom": "^19.1.0",
+ "react-icons": "^5.5.0",
"react-markdown": "^10.1.0",
"react-responsive-carousel": "^3.2.23",
"react-router-dom": "^7.6.2",
@@ -28,6 +30,7 @@
"remark-frontmatter": "^5.0.0",
"remark-gfm": "^4.0.1",
"remark-supersub": "^1.0.0",
+ "sonner": "^2.0.5",
"tailwind-merge": "^3.3.1",
"tailwindcss": "^4.0.4",
"tailwindcss-animate": "^1.0.7",
@@ -6802,6 +6805,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/next-themes": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz",
+ "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc"
+ }
+ },
"node_modules/node-releases": {
"version": "2.0.19",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
@@ -7384,6 +7397,15 @@
"node": ">= 6"
}
},
+ "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",
+ "peerDependencies": {
+ "react": "*"
+ }
+ },
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -8105,6 +8127,16 @@
"url": "https://github.com/sponsors/cyyynthia"
}
},
+ "node_modules/sonner": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.5.tgz",
+ "integrity": "sha512-YwbHQO6cSso3HBXlbCkgrgzDNIhws14r4MO87Ofy+cV2X7ES4pOoAK3+veSmVTvqNx1BWUxlhPmZzP00Crk2aQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc",
+ "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ }
+ },
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
diff --git a/package.json b/package.json
index 53d65df9..e92885d3 100644
--- a/package.json
+++ b/package.json
@@ -26,8 +26,10 @@
"dompurify": "^3.2.6",
"framer-motion": "^12.17.3",
"lucide-react": "^0.476.0",
+ "next-themes": "^0.4.6",
"react": "^19.1.0",
"react-dom": "^19.1.0",
+ "react-icons": "^5.5.0",
"react-markdown": "^10.1.0",
"react-responsive-carousel": "^3.2.23",
"react-router-dom": "^7.6.2",
@@ -38,6 +40,7 @@
"remark-frontmatter": "^5.0.0",
"remark-gfm": "^4.0.1",
"remark-supersub": "^1.0.0",
+ "sonner": "^2.0.5",
"tailwind-merge": "^3.3.1",
"tailwindcss": "^4.0.4",
"tailwindcss-animate": "^1.0.7",
diff --git a/src/components/ui/sonner.tsx b/src/components/ui/sonner.tsx
new file mode 100644
index 00000000..5b102940
--- /dev/null
+++ b/src/components/ui/sonner.tsx
@@ -0,0 +1,23 @@
+import { useTheme } from 'next-themes';
+import { Toaster as Sonner, ToasterProps } from 'sonner';
+
+const Toaster = ({ ...props }: ToasterProps) => {
+ const { theme = 'system' } = useTheme();
+
+ return (
+