diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 43ca19e..95b32c9 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -1,5 +1,7 @@
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import { AuthProvider, useAuth } from './contexts/AuthContext';
+import { ThemeProvider } from './components/providers/ThemeProvider';
+import { TooltipProvider } from './components/ui/tooltip';
import { LoginPage } from './pages/LoginPage';
import { SignupPage } from './pages/SignupPage';
import { LandingPage } from './pages/LandingPage';
@@ -78,12 +80,29 @@ function AppRoutes() {
);
}
+/**
+ * Root application component that sets up global providers and routing.
+ *
+ * Wraps the app with theme and tooltip contexts, initializes the router, and
+ * provides authentication state to the route tree.
+ *
+ * @returns The root React element with ThemeProvider, TooltipProvider, BrowserRouter, and AuthProvider applied.
+ */
export function App() {
return (
-
-
-
-
-
+
+
+
+
+
+
+
+
+
);
-}
+}
\ No newline at end of file
diff --git a/frontend/src/components/landing/FAQ.tsx b/frontend/src/components/landing/FAQ.tsx
new file mode 100644
index 0000000..7c58381
--- /dev/null
+++ b/frontend/src/components/landing/FAQ.tsx
@@ -0,0 +1,102 @@
+import { motion } from 'framer-motion'
+import {
+ Accordion,
+ AccordionContent,
+ AccordionItem,
+ AccordionTrigger,
+} from '@/components/ui/accordion'
+
+const FAQS = [
+ {
+ q: 'How is this different from GitHub search or grep?',
+ a: `Think about the last time you joined a new codebase. You knew what you needed ("the function that retries API calls") but had no idea what it was called. GitHub search and grep need exact keywords. If the function is named make_request_with_backoff, you'd never find it by searching "retry logic."
+
+CodeIntel actually understands what code does, not just what it's named. We use AI embeddings trained specifically on code semantics. So you can search "retry logic with exponential backoff" and find it, even if those words appear nowhere in the file.`,
+ },
+ {
+ q: 'What languages do you support?',
+ a: `Right now, Python is our focus. We have deep support for Flask, FastAPI, and Django, meaning we understand routes, middleware, decorators, and framework-specific patterns.
+
+TypeScript and JavaScript are next on our roadmap, followed by Go and Rust. The good news: CodeIntel is completely open source. If you need a language we don't support yet, you can contribute a parser or sponsor its development. Our architecture is built to be language-agnostic from day one.`,
+ },
+ {
+ q: 'How does MCP integration work?',
+ a: `MCP (Model Context Protocol) is how AI assistants like Claude and Cursor talk to external tools. CodeIntel runs as an MCP server that these tools can connect to.
+
+Once connected, your AI assistant gains the ability to semantically search your entire codebase. When you ask Claude "how does authentication work in this project?", it can actually find and read the relevant code instead of guessing. It's like giving your AI assistant a senior developer's knowledge of your codebase.`,
+ },
+ {
+ q: 'Is my code stored on your servers?',
+ a: `We never store your raw source code. What we store are vector embeddings, which are mathematical representations of what your code does. Think of it like storing a summary, not the actual document. You can delete these anytime from your dashboard.
+
+But if you want complete control, you can self-host CodeIntel on your own infrastructure. It's fully open source under MIT license. Your code never leaves your servers, and you get the same search quality. Many teams with sensitive codebases go this route.`,
+ },
+ {
+ q: 'How fast is indexing?',
+ a: `For most repositories under 100,000 lines of code, initial indexing takes about 1-2 minutes. We parse your code, generate embeddings, and build the search index in parallel.
+
+After the first index, updates are incremental. Change a file, and only that file gets re-indexed. This usually takes seconds. Search itself returns results in under 100ms regardless of how large your codebase is, because we're searching vectors, not scanning text.`,
+ },
+]
+
+/**
+ * Renders the FAQ section with an animated header, an accordion of frequently asked questions, and a contact link.
+ *
+ * @returns The section element containing the FAQ accordion and contact paragraph
+ */
+export function FAQ() {
+ return (
+
+
- Works with any Python repository • Now in beta
-
+
+
+ Index your first repo free
+ →
+
+
+
+ View on GitHub
+
+
+
Works with any Python repository • Self-host or cloud
)
-}
+}
\ No newline at end of file
diff --git a/frontend/src/components/landing/MobileMenu.tsx b/frontend/src/components/landing/MobileMenu.tsx
new file mode 100644
index 0000000..3102761
--- /dev/null
+++ b/frontend/src/components/landing/MobileMenu.tsx
@@ -0,0 +1,76 @@
+import { Menu, X } from 'lucide-react'
+import { Sheet, SheetContent, SheetTrigger, SheetClose } from '@/components/ui/sheet'
+import { ThemeToggle } from './ThemeToggle'
+import { GitHubStars } from './GitHubStars'
+
+interface MobileMenuProps {
+ onNavigate: (path: string) => void
+}
+
+const NAV_LINKS = [
+ { label: 'Features', href: '#features' },
+ { label: 'Pricing', href: '#pricing' },
+ { label: 'Docs', href: '/docs' },
+]
+
+/**
+ * Render a right-anchored slide-out mobile navigation menu with navigation links, authentication actions, and bottom utilities.
+ *
+ * @param onNavigate - Callback invoked with a path string when a navigation action is requested (called with '/login' for Sign in and '/signup' for Get Started).
+ * @returns A JSX element that displays the mobile navigation sheet.
+ */
+export function MobileMenu({ onNavigate }: MobileMenuProps) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/frontend/src/components/landing/Navbar.tsx b/frontend/src/components/landing/Navbar.tsx
index 3f8d373..d4ff148 100644
--- a/frontend/src/components/landing/Navbar.tsx
+++ b/frontend/src/components/landing/Navbar.tsx
@@ -1,10 +1,27 @@
import { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
+import { ThemeToggle } from './ThemeToggle'
+import { GitHubStars } from './GitHubStars'
+import { MobileMenu } from './MobileMenu'
interface NavbarProps {
minimal?: boolean
}
+const NAV_LINKS = [
+ { label: 'Features', href: '#features' },
+ { label: 'Pricing', href: '#pricing' },
+ { label: 'Docs', href: '/docs' },
+]
+
+/**
+ * Renders the top navigation bar with logo, responsive navigation links, and action controls.
+ *
+ * The bar updates its background and border when the page is scrolled beyond 20px, and it cleans up the scroll listener on unmount. When `minimal` is true, desktop navigation links and right-side controls are hidden. Sign in and Get Started buttons navigate to '/login' and '/signup' respectively; the mobile menu receives a navigation handler.
+ *
+ * @param minimal - When true, hide desktop navigation links and right-side controls
+ * @returns The rendered navbar element
+ */
export function Navbar({ minimal }: NavbarProps) {
const navigate = useNavigate()
const [scrolled, setScrolled] = useState(false)
@@ -19,37 +36,60 @@ export function Navbar({ minimal }: NavbarProps) {