Skip to content
Open
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
55 changes: 55 additions & 0 deletions frontend/app/landing/landing.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* Full-page container */
.landing-container {
display: flex;
flex-direction: column; /* Stack vertically */
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #ffffff; /* White background */
padding: 40px;
color: black; /* Default text black */
text-align: center; /* Center text */
}

/* Text block */
.text-content {
display: flex;
flex-direction: column;
align-items: center; /* Center horizontally */
justify-content: center;
gap: 20px;
max-width: 600px;
}

/* Typewriter headline */
.typewriter-text {
font-size: 36px;
font-weight: bold;
line-height: 1.2;
color: black; /* Ensure headline text is black by default */
}

/* Description paragraph */
.description-text {
font-size: 18px;
color: #333333; /* Dark gray for readability */
line-height: 1.5;
}

/* CTA button */
.start-button {
padding: 12px 24px;
font-size: 18px;
background-color: #800000; /* maroon */
color: white; /* keep white text for contrast */
border: none;
border-radius: 8px;
cursor: pointer;
transition: background 0.3s ease, transform 0.2s ease;
width: fit-content;
}

.start-button:hover {
background-color: #600000; /* darker maroon */
transform: scale(1.05); /* subtle hover effect */
}
61 changes: 61 additions & 0 deletions frontend/app/landing/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"use client";

import { useRouter } from "next/navigation";
import dynamic from "next/dynamic";
import "./landing.css";

const Typewriter = dynamic(() => import("typewriter-effect"), { ssr: false });

const Landing = () => {
const router = useRouter();

const handleStartClick = () => {
router.push("/upload");
};

return (
<div className="landing-container">
<div className="text-content">
<div className="typewriter-text">
<Typewriter
options={{ delay: 45 }}
onInit={(typewriter) => {
typewriter
// First "Revision"
.typeString(
"<span style='font-size:50px'>Re</span><span style='color: #800000; font-size:50px'>Vision</span>"
)
.pauseFor(3000)
.deleteAll()

// Tagline
.typeString("The smart ")
.typeString("<span style='color: #800000;'>whiteboard</span>")
.typeString(" that you always ")
.typeString("<span style='color: #800000;'>needed</span>")
.typeString(".")
.pauseFor(2000)
.deleteAll()

// Final "Revision" → stays forever
.typeString(
"<span style='font-size:50px'>Re</span><span style='color: #800000; font-size:50px'>Vision</span>"
)
.start();
}}
/>
</div>

<p className="description-text">
An AI-powered tutor that turns scanned questions into interactive practice with <b>real-time feedback</b>.
</p>

<button className="start-button" onClick={handleStartClick}>
Start Now
</button>
</div>
</div>
);
};

export default Landing;
152 changes: 56 additions & 96 deletions frontend/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,103 +1,63 @@
import Image from "next/image";
"use client";
import { useRouter } from "next/navigation";
import dynamic from "next/dynamic";

const Typewriter = dynamic(() => import("typewriter-effect"), { ssr: false });

const Landing = () => {
const router = useRouter();

const handleStartClick = () => {
router.push("/upload");
};

export default function Home() {
return (
<div className="font-sans grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
<main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start">
<Image
className="dark:invert"
src="/next.svg"
alt="Next.js logo"
width={180}
height={38}
priority
/>
<ol className="font-mono list-inside list-decimal text-sm/6 text-center sm:text-left">
<li className="mb-2 tracking-[-.01em]">
Get started by editing{" "}
<code className="bg-black/[.05] dark:bg-white/[.06] font-mono font-semibold px-1 py-0.5 rounded">
app/page.tsx
</code>
.
</li>
<li className="tracking-[-.01em]">
Save and see your changes instantly.
</li>
</ol>
<div className="flex flex-col justify-center items-center min-h-screen bg-white px-10 text-black text-center">
<div className="flex flex-col items-center justify-center gap-5 max-w-xl">
<div className="text-3xl font-bold leading-tight text-black typewriter-text">
<Typewriter
options={{ delay: 45 }}
onInit={(typewriter) => {
typewriter
// First "Revision"
.typeString(
"<span style='font-size:50px'>Re</span><span style='color: #800000; font-size:50px'>Vision</span>"
)
.pauseFor(3000)
.deleteAll()

<div className="flex gap-4 items-center flex-col sm:flex-row">
<a
className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:w-auto"
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
className="dark:invert"
src="/vercel.svg"
alt="Vercel logomark"
width={20}
height={20}
/>
Deploy now
</a>
<a
className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 w-full sm:w-auto md:w-[158px]"
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Read our docs
</a>
</div>
</main>
<footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center">
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/file.svg"
alt="File icon"
width={16}
height={16}
/>
Learn
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/window.svg"
alt="Window icon"
width={16}
height={16}
// Tagline
.typeString("The smart ")
.typeString("<span style='color: #800000;'>whiteboard</span>")
.typeString(" that you always ")
.typeString("<span style='color: #800000;'>needed</span>")
.typeString(".")
.pauseFor(2000)
.deleteAll()

// Final "Revision"
.typeString(
"<span style='font-size:50px'>Re</span><span style='color: #800000; font-size:50px'>Vision</span>"
)
.start();
}}
/>
Examples
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
</div>

<p className="text-lg text-gray-700 leading-relaxed">
An AI-powered tutor that turns scanned questions into interactive
practice with <b>real-time feedback</b>.
</p>

<button
onClick={handleStartClick}
className="px-6 py-3 text-lg bg-[#800000] text-white rounded-lg transition ease-in-out duration-300 transform hover:bg-[#600000] hover:scale-105"
>
<Image
aria-hidden
src="/globe.svg"
alt="Globe icon"
width={16}
height={16}
/>
Go to nextjs.org →
</a>
</footer>
Start Now
</button>
</div>
</div>
);
}
};

export default Landing;
Loading