+ {/* Mode Selector */}
+
+
+
+
+ {/* Demo Repo Buttons */}
+ {showDemoSelector && (
+
+ {DEMO_REPOS.map(repo => {
+ const isAvailable = availableRepos.length === 0 || availableRepos.includes(repo.id);
+ const isSelected = selectedDemo === repo.id;
+ return (
+
+ );
+ })}
+
+ )}
+
+ {/* Custom URL Input */}
+ {showUrlInput && (
+
+
+
+ )}
+
+ {/* Validation Status */}
+ {showValidation && (
+
+
+
+ )}
+
+ {/* Indexing Progress */}
+ {showIndexing && (
+
+
+
+ )}
+
+ {/* Ready State Banner */}
+ {mode === 'custom' && state.status === 'ready' && (
+
+
+ โ
+
+ {state.repoName} indexed ยท {state.fileCount} files ยท {state.functionsFound} functions
+
+
+
+
+ )}
+
+ {/* Search Box */}
+ {showSearch && (
+ <>
+
+
+ {/* Trust Indicators */}
+
+
+
+ ~100ms
+
+
+
No signup required
+
+
{session?.searches.remaining ?? remaining} searches left
+
+ >
+ )}
+
+ {/* Error State */}
+ {state.status === 'error' && (
+
+
{state.message}
+ {state.canRetry && (
+
+ )}
+
+ )}
+
+ {/* Upgrade CTA (when limit reached) */}
+ {remaining <= 0 && (
+
+
You've used all your free searches today
+
+
+ )}
+
+ );
+}
diff --git a/frontend/src/components/playground/index.ts b/frontend/src/components/playground/index.ts
index 097a740..2441356 100644
--- a/frontend/src/components/playground/index.ts
+++ b/frontend/src/components/playground/index.ts
@@ -9,3 +9,4 @@ export { RepoModeSelector, type RepoMode } from './RepoModeSelector';
export { RepoUrlInput } from './RepoUrlInput';
export { ValidationStatus } from './ValidationStatus';
export { IndexingProgress, type ProgressData } from './IndexingProgress';
+export { HeroPlayground } from './HeroPlayground';
diff --git a/frontend/src/contexts/AuthContext.tsx b/frontend/src/contexts/AuthContext.tsx
index bf59146..758aacb 100644
--- a/frontend/src/contexts/AuthContext.tsx
+++ b/frontend/src/contexts/AuthContext.tsx
@@ -1,5 +1,6 @@
import { createContext, useContext, useState, useEffect, ReactNode } from 'react';
-import { createClient, SupabaseClient, User, Session } from '@supabase/supabase-js';
+import { createClient } from '@supabase/supabase-js';
+import type { SupabaseClient, User, Session } from '@supabase/supabase-js';
interface AuthContextType {
user: User | null;
diff --git a/frontend/src/pages/LandingPage.tsx b/frontend/src/pages/LandingPage.tsx
index 1d55ad9..9bd0c90 100644
--- a/frontend/src/pages/LandingPage.tsx
+++ b/frontend/src/pages/LandingPage.tsx
@@ -6,20 +6,11 @@ import { Card } from '@/components/ui/card'
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
import { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism'
import { API_URL } from '../config/api'
+import { HeroPlayground } from '@/components/playground'
+import { playgroundAPI } from '@/services/playground-api'
import type { SearchResult } from '../types'
-// Icons
-const SearchIcon = () => (
-