Conversation
There was a problem hiding this comment.
Pull request overview
Implements a new single-page, responsive landing page (Moola-inspired) in the Next.js app, including a fixed navbar with active-section tracking, scroll-driven section navigation, and custom global styling.
Changes:
- Replaced the default Next.js starter page with a landing page composed of
Navbar,Hero, andFeaturessections. - Added new UI components for navigation, hero content, steps/brands/testimonials/rewards, plus scroll reveal behaviors.
- Introduced a custom global CSS design system (tokens + component styles) and updated Google fonts + site metadata.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
frontend/src/components/Navbar.tsx |
Adds fixed navbar, smooth scroll behavior, active section tracking, and mobile drawer menu. |
frontend/src/components/Hero.tsx |
Adds hero section with CTA buttons and stats. |
frontend/src/components/Features.tsx |
Adds “How it Works”, Brands, Testimonials, Rewards + Footer sections and reveal hooks. |
frontend/src/app/page.tsx |
Swaps starter content for the new landing page composition and defines #scroll-area. |
frontend/src/app/layout.tsx |
Updates fonts (Syne + DM Sans) and page metadata for the landing page. |
frontend/src/app/globals.css |
Adds global design tokens and full styling for nav/sections/drawer + scroll container. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ))} | ||
| </ul> | ||
|
|
||
| <a href="#" className="nav-cta" onClick={(e) => e.preventDefault()}> |
There was a problem hiding this comment.
The "Get Started Free" CTA is an <a href="#"> that calls preventDefault() and doesn't trigger any navigation/scroll, so it’s a dead control. Point it to a real destination (e.g., scroll to #rewards or route to a signup page) or switch to a <button> with an implemented action.
| <a href="#" className="nav-cta" onClick={(e) => e.preventDefault()}> | |
| <a | |
| href="#rewards" | |
| className="nav-cta" | |
| onClick={(e) => handleLink(e, "#rewards")} | |
| > |
| <a href="#" className="drawer-btn" onClick={(e) => e.preventDefault()}> | ||
| Get Started Free | ||
| </a> |
There was a problem hiding this comment.
The drawer "Get Started Free" CTA is also an <a href="#"> with preventDefault() and no action, so it’s non-functional in the mobile menu as well. Wire it to a real destination (scroll/route) or make it a button with an implemented handler.
| <p className="brands-sub"> | ||
| From your morning coffee to your next vacation — earn cash back everywhere you already spend. | ||
| </p> | ||
| <div className="brands-scroll" ref={brandRef as React.Ref<HTMLDivElement>}> |
There was a problem hiding this comment.
brandRef uses useReveal() (which adds a visible class) but .brands-scroll doesn’t have the reveal class and there are no styles for .brands-scroll.visible, so the observer work won’t produce the intended reveal animation. Either add the reveal class here (and ensure initial hidden styles apply) or remove the reveal hook/ref for this element.
| <div className="brands-scroll" ref={brandRef as React.Ref<HTMLDivElement>}> | |
| <div className="brands-scroll reveal" ref={brandRef as React.Ref<HTMLDivElement>}> |
| {menuOpen && ( | ||
| <div className="mobile-drawer"> | ||
| <div className="drawer-header"> | ||
| <a href="#" className="nav-logo" onClick={(e) => handleLink(e, "#")}>moola</a> | ||
| <button className="drawer-close" onClick={() => setMenuOpen(false)} aria-label="Close menu"> | ||
| <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"> | ||
| <path d="M18 6 6 18M6 6l12 12"/> | ||
| </svg> | ||
| </button> |
There was a problem hiding this comment.
The drawer is effectively a fullscreen modal, but it lacks dialog semantics (e.g., role="dialog" + aria-modal="true") and focus management (initial focus, focus trap, ESC to close). Adding these will improve keyboard/screen-reader usability of the mobile navigation.
| transition: color .2s; | ||
| animation: fadeUp .35s var(--ease-out) both; | ||
| } | ||
| .drawer-link:last-child { border-bottom: none; } |
There was a problem hiding this comment.
.drawer-link:last-child { border-bottom: none; } won’t match the last nav link because the CTA button comes after the links, so the final link still gets a bottom border. Use :last-of-type (or target the last .drawer-link explicitly) to remove the border from the final link as intended.
| .drawer-link:last-child { border-bottom: none; } | |
| .drawer-link:last-of-type { border-bottom: none; } |
| .mobile-drawer { | ||
| position: fixed; inset: 0; z-index: 99; | ||
| background: #f4faf1; | ||
| display: flex; | ||
| flex-direction: column; | ||
| padding: 0 1.5rem 2.5rem; | ||
| } |
There was a problem hiding this comment.
.mobile-drawer is rendered while the fixed .nav stays at z-index: 100, but the drawer is z-index: 99, so the navbar will overlay the drawer header (including the close button) when the menu is open. Increase the drawer z-index above the nav (or lower the nav while open) so the drawer is fully interactive.
Implemented a responsive landing page inspired by Moola.com using Next.js and TypeScript.
What's included
Technical highlights