Skip to content
Open

hi #28

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
:root {
--background: #ffffff;
--foreground: #171717;
--primary-purple: #7c3aed;
--primary-purple-dark: #581c87;
--secondary-purple: #a855f7;
--accent-purple: #c084fc;
--dark-bg: #0f0f0f;
--dark-surface: #1a1a1a;
--dark-text: #f5f5f5;
--dark-text-secondary: #a3a3a3;
}

@theme inline {
Expand All @@ -15,11 +23,30 @@

@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
--background: var(--dark-bg);
--foreground: var(--dark-text);
}
}

/* Dark mode class for manual toggle */
.dark {
--background: var(--dark-bg);
--foreground: var(--dark-text);
}

/* Custom dark mode utilities */
.dark .bg-surface {
background-color: var(--dark-surface);
}

.dark .text-dark-secondary {
color: var(--dark-text-secondary);
}

.dark .border-dark {
border-color: rgba(255, 255, 255, 0.1);
}

body {
background: var(--background);
color: var(--foreground);
Expand Down
7 changes: 6 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Instrument_Serif } from "next/font/google";
import "./globals.css";
import { DarkModeProvider } from "../contexts/DarkModeContext";

const instrumentSerif = Instrument_Serif({
subsets: ["latin"],
Expand All @@ -22,7 +23,11 @@ export default function RootLayout({
}) {
return (
<html lang="en">
<body className={`${instrumentSerif.variable}`}>{children}</body>
<body className={`${instrumentSerif.variable}`}>
<DarkModeProvider>
{children}
</DarkModeProvider>
</body>
</html>
);
}
18 changes: 9 additions & 9 deletions src/components/ConceptInputForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,20 @@ const ConceptInputForm: React.FC<ConceptInputFormProps> = ({
transition={{ duration: 0.6, ease: "easeOut" }}
>
<motion.div
className="text-3xl md:text-5xl lg:text-6xl font-serif font-medium text-gray-900 tracking-tight text-center w-full mb-8"
className="text-3xl md:text-5xl lg:text-6xl font-serif font-medium text-gray-900 dark:text-white tracking-tight text-center w-full mb-8"
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.2, ease: "easeOut" }}
>
{mode === "lessons"
{mode === "lessons"
? "Write the concept for lesson breakdown"
: "Write the concept you want to understand"
}
</motion.div>

{mode === "lessons" && (
<motion.div
className="text-lg md:text-xl text-gray-600 text-center w-full mb-6"
className="text-lg md:text-xl text-gray-600 dark:text-purple-200 text-center w-full mb-6"
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.3, ease: "easeOut" }}
Expand All @@ -66,8 +66,8 @@ const ConceptInputForm: React.FC<ConceptInputFormProps> = ({
onSubmit();
}
}}
className="text-3xl md:text-5xl lg:text-6xl font-serif font-medium text-gray-900 tracking-tight bg-transparent border-none outline-none text-center w-full relative z-10"
style={{ caretColor: "rgb(17 24 39)" }}
className="text-3xl md:text-5xl lg:text-6xl font-serif font-medium text-gray-900 dark:text-white tracking-tight bg-transparent border-none outline-none text-center w-full relative z-10"
style={{ caretColor: "rgb(17 24 39) var(--tw-dark-caret, rgb(229 231 235))" }}
placeholder={placeholder}
/>
{inputValue === "" && !isFocused && (
Expand All @@ -79,9 +79,9 @@ const ConceptInputForm: React.FC<ConceptInputFormProps> = ({
<div className="flex justify-center mt-8">
<motion.button
onClick={() => isValid && onSubmit()}
className={`w-14 h-14 backdrop-blur-sm text-gray-700 rounded-full flex items-center justify-center transition-all duration-300 disabled:cursor-not-allowed ${
isFocused ? "bg-gray-500/30" : "bg-gray-500/10"
} ${isValid ? "hover:bg-gray-500/40" : ""}`}
className={`w-14 h-14 backdrop-blur-sm text-gray-700 dark:text-purple-200 rounded-full flex items-center justify-center transition-all duration-300 disabled:cursor-not-allowed ${
isFocused ? "bg-gray-500/30 dark:bg-purple-500/30" : "bg-gray-500/10 dark:bg-purple-500/20"
} ${isValid ? "hover:bg-gray-500/40 dark:hover:bg-purple-500/40" : ""}`}
disabled={!isValid}
whileHover={{ scale: isValid ? 1.05 : 1 }}
whileTap={{ scale: isValid ? 0.95 : 1 }}
Expand Down
117 changes: 117 additions & 0 deletions src/components/DarkModeToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
"use client";

import React from "react";
import { useDarkMode } from "../contexts/DarkModeContext";
import { motion } from "motion/react";

interface DarkModeToggleProps {
className?: string;
}

const DarkModeToggle: React.FC<DarkModeToggleProps> = ({ className = "" }) => {
const { isDarkMode, toggleDarkMode } = useDarkMode();

return (
<motion.button
onClick={toggleDarkMode}
className={`relative flex items-center justify-center w-12 h-12 rounded-full transition-all duration-300 ${
isDarkMode
? "bg-purple-800/50 hover:bg-purple-700/50 border border-purple-600/30"
: "bg-white/80 hover:bg-white/90 border border-gray-200/50 backdrop-blur-sm"
} ${className}`}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
aria-label={isDarkMode ? "Switch to light mode" : "Switch to dark mode"}
>
{/* Sun Icon */}
<motion.svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
className={`absolute transition-all duration-300 ${
isDarkMode ? "opacity-0 rotate-90 scale-0" : "opacity-100 rotate-0 scale-100"
}`}
>
<circle
cx="12"
cy="12"
r="5"
stroke={isDarkMode ? "#a855f7" : "#7c3aed"}
strokeWidth="2"
fill={isDarkMode ? "#a855f7" : "#7c3aed"}
/>
<path
d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"
stroke={isDarkMode ? "#a855f7" : "#7c3aed"}
strokeWidth="2"
/>
</motion.svg>

{/* Moon Icon */}
<motion.svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
className={`absolute transition-all duration-300 ${
isDarkMode ? "opacity-100 rotate-0 scale-100" : "opacity-0 -rotate-90 scale-0"
}`}
>
<path
d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"
stroke="#e879f9"
strokeWidth="2"
fill="#e879f9"
/>
</motion.svg>

{/* Animated stars for dark mode */}
{isDarkMode && (
<>
<motion.div
className="absolute w-1 h-1 bg-purple-300 rounded-full"
style={{ top: "4px", right: "6px" }}
animate={{
opacity: [0.3, 1, 0.3],
scale: [0.8, 1.2, 0.8],
}}
transition={{
duration: 2,
repeat: Infinity,
delay: 0,
}}
/>
<motion.div
className="absolute w-0.5 h-0.5 bg-purple-200 rounded-full"
style={{ top: "6px", left: "5px" }}
animate={{
opacity: [0.5, 1, 0.5],
scale: [1, 1.3, 1],
}}
transition={{
duration: 1.5,
repeat: Infinity,
delay: 0.5,
}}
/>
<motion.div
className="absolute w-0.5 h-0.5 bg-purple-400 rounded-full"
style={{ bottom: "5px", right: "4px" }}
animate={{
opacity: [0.4, 1, 0.4],
scale: [0.9, 1.1, 0.9],
}}
transition={{
duration: 2.5,
repeat: Infinity,
delay: 1,
}}
/>
</>
)}
</motion.button>
);
};

export default DarkModeToggle;
14 changes: 8 additions & 6 deletions src/components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
import DarkModeToggle from "./DarkModeToggle";

interface NavbarProps {
showBackButton?: boolean;
Expand All @@ -22,7 +23,7 @@ const Navbar: React.FC<NavbarProps> = ({
{showBackButton && (
<button
onClick={() => router.push(backPath)}
className="w-8 h-8 bg-black text-white rounded-full flex items-center justify-center transition-colors hover:bg-gray-800 cursor-pointer"
className="w-8 h-8 bg-black dark:bg-purple-800 text-white rounded-full flex items-center justify-center transition-colors hover:bg-gray-800 dark:hover:bg-purple-700 cursor-pointer"
aria-label="Go back"
>
<svg
Expand All @@ -43,14 +44,14 @@ const Navbar: React.FC<NavbarProps> = ({
{!showBackButton && <div className="w-8"></div>}

<div className="flex items-center">
<h1 className="text-2xl md:text-3xl font-serif font-medium text-gray-900 tracking-tight">
<h1 className="text-2xl md:text-3xl font-serif font-medium text-gray-900 dark:text-white tracking-tight">
<span className="inline-flex items-center gap-2">
Mona
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
className="w-5 h-5 text-pink-500 inline-block align-middle"
className="w-5 h-5 text-pink-500 dark:text-purple-400 inline-block align-middle"
aria-label="heart"
>
<path
Expand All @@ -64,11 +65,12 @@ const Navbar: React.FC<NavbarProps> = ({
</div>

<div className="flex items-center gap-3">
<DarkModeToggle />
{!hideCreateButtons && (
<>
<Link
href="/explain"
className="w-8 h-8 bg-black text-white rounded-full flex items-center justify-center transition-colors hover:bg-gray-800 cursor-pointer shadow-lg"
className="w-8 h-8 bg-black dark:bg-purple-800 text-white rounded-full flex items-center justify-center transition-colors hover:bg-gray-800 dark:hover:bg-purple-700 cursor-pointer shadow-lg"
title="Create Video"
aria-label="Create video explanation"
>
Expand All @@ -84,7 +86,7 @@ const Navbar: React.FC<NavbarProps> = ({
</Link>
<Link
href="/article"
className="w-8 h-8 bg-white/60 backdrop-blur-sm text-gray-700 rounded-full flex items-center justify-center transition-colors hover:bg-white/80 cursor-pointer shadow-lg border border-white/50"
className="w-8 h-8 bg-white/60 dark:bg-purple-900/50 backdrop-blur-sm text-gray-700 dark:text-purple-200 rounded-full flex items-center justify-center transition-colors hover:bg-white/80 dark:hover:bg-purple-800/50 cursor-pointer shadow-lg border border-white/50 dark:border-purple-600/30"
title="Create Article"
aria-label="Create article explanation"
>
Expand All @@ -110,7 +112,7 @@ const Navbar: React.FC<NavbarProps> = ({
)}
<Link
href="/library"
className="w-8 h-8 bg-black text-white rounded-full flex items-center justify-center transition-colors hover:bg-gray-800 cursor-pointer shadow-lg"
className="w-8 h-8 bg-black dark:bg-purple-800 text-white rounded-full flex items-center justify-center transition-colors hover:bg-gray-800 dark:hover:bg-purple-700 cursor-pointer shadow-lg"
title="View Library"
aria-label="Go to library"
>
Expand Down
45 changes: 33 additions & 12 deletions src/components/ShaderBackground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type React from "react";

import { useEffect, useRef, useState } from "react";
import { MeshGradient } from "@paper-design/shaders-react";
import { useDarkMode } from "../contexts/DarkModeContext";

interface ShaderBackgroundProps {
children?: React.ReactNode;
Expand All @@ -12,18 +13,21 @@ interface ShaderBackgroundProps {
export default function ShaderBackground({ children }: ShaderBackgroundProps) {
const containerRef = useRef<HTMLDivElement>(null);
const [grainSeed, setGrainSeed] = useState<number>(0);
const { isDarkMode } = useDarkMode();

useEffect(() => {
// Generate random seed for grain effect on client side only
setGrainSeed(Math.random() * 1000);
}, []);



return (
<div
ref={containerRef}
className="min-h-screen bg-gradient-to-br from-pink-50 via-purple-50 to-blue-50 relative overflow-hidden"
className={`min-h-screen relative overflow-hidden ${
isDarkMode
? "bg-gradient-to-br from-purple-900 via-gray-900 to-black"
: "bg-gradient-to-br from-pink-50 via-purple-50 to-blue-50"
}`}
>
{/* SVG Filters */}
<svg className="absolute inset-0 w-0 h-0">
Expand Down Expand Up @@ -93,19 +97,36 @@ export default function ShaderBackground({ children }: ShaderBackgroundProps) {
<MeshGradient
className="absolute inset-0 w-full h-full"
style={{ filter: "url(#grain-filter)" }}
colors={[
"#f9a8d4", // pink
"#f0abfc", // fuchsia
"#d8b4fe", // purple
"#c4b5fd", // violet
"#fde68a", // amber
"#fef3c7", // light amber
]}
colors={
isDarkMode
? [
"#581c87", // dark purple
"#7c3aed", // purple
"#9333ea", // violet
"#a855f7", // light purple
"#c084fc", // lavender
"#e879f9", // magenta
]
: [
"#f9a8d4", // pink
"#f0abfc", // fuchsia
"#d8b4fe", // purple
"#c4b5fd", // violet
"#fde68a", // amber
"#fef3c7", // light amber
]
}
speed={0.15}
/>

{/* Overlay for depth */}
<div className="absolute inset-0 bg-gradient-to-t from-pink-100/20 via-transparent to-purple-50/10" />
<div
className={`absolute inset-0 ${
isDarkMode
? "bg-gradient-to-t from-purple-900/30 via-transparent to-gray-900/20"
: "bg-gradient-to-t from-pink-100/20 via-transparent to-purple-50/10"
}`}
/>

{children}
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/TypewriterText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const TypewriterText: React.FC = () => {

return (
<motion.span
className="text-3xl md:text-5xl lg:text-6xl font-serif font-medium text-gray-400 tracking-tight text-center"
className="text-3xl md:text-5xl lg:text-6xl font-serif font-medium text-gray-400 dark:text-purple-400 tracking-tight text-center"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5 }}
Expand All @@ -54,7 +54,7 @@ const TypewriterText: React.FC = () => {
<motion.span
animate={{ opacity: [1, 0] }}
transition={{ duration: 0.8, repeat: Infinity, repeatType: "reverse" }}
className="text-gray-400"
className="text-gray-400 dark:text-purple-400"
>
|
</motion.span>
Expand Down
Loading