Initial: portfolio template via tAI
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"permissions": {
|
||||||
|
"allow": [
|
||||||
|
"Read",
|
||||||
|
"Write",
|
||||||
|
"Edit",
|
||||||
|
"Bash",
|
||||||
|
"Glob",
|
||||||
|
"Grep"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"model": "claude-sonnet-4-20250514"
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Alex Rivera
|
||||||
|
Designer portfolio with project showcase, case studies, about, and contact
|
||||||
|
Stack: React 18 / TypeScript / Vite / Tailwind CSS / shadcn/ui
|
||||||
|
Pages: Index, Work, ProjectDetail, About, Contact
|
||||||
|
Palette: violet/purple dark theme
|
||||||
|
|
||||||
|
## Files
|
||||||
|
- src/components/Header.tsx (2KB)
|
||||||
|
- src/components/Footer.tsx (1KB)
|
||||||
|
- src/pages/Index.tsx (11KB)
|
||||||
|
- src/pages/Work.tsx (4KB)
|
||||||
|
- src/pages/ProjectDetail.tsx (11KB)
|
||||||
|
- src/pages/About.tsx (8KB)
|
||||||
|
- src/pages/Contact.tsx (6KB)
|
||||||
|
- src/App.tsx (1KB)
|
||||||
|
|
||||||
|
## Imports
|
||||||
|
UI: @/components/ui/{button,card,badge,input,textarea,tabs,accordion,dialog,sheet}
|
||||||
|
Icons: lucide-react
|
||||||
|
Toast: import { toast } from "sonner"
|
||||||
|
Theme: ThemeToggle in headers (next-themes)
|
||||||
|
Router: react-router-dom BrowserRouter
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
- MODIFY existing files — never rebuild from scratch
|
||||||
|
- Pages import Header + Footer from @/components/
|
||||||
|
- Tailwind only — no inline styles
|
||||||
|
- Use existing shadcn components — don't create custom ones
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Portfolio</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
||||||
|
import IndexPage from "@/pages/Index";
|
||||||
|
import WorkPage from "@/pages/Work";
|
||||||
|
import ProjectDetailPage from "@/pages/ProjectDetail";
|
||||||
|
import AboutPage from "@/pages/About";
|
||||||
|
import ContactPage from "@/pages/Contact";
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
return (
|
||||||
|
<BrowserRouter>
|
||||||
|
<Routes>
|
||||||
|
<Route path="/" element={<IndexPage />} />
|
||||||
|
<Route path="/work" element={<WorkPage />} />
|
||||||
|
<Route path="/project" element={<ProjectDetailPage />} />
|
||||||
|
<Route path="/about" element={<AboutPage />} />
|
||||||
|
<Route path="/contact" element={<ContactPage />} />
|
||||||
|
</Routes>
|
||||||
|
</BrowserRouter>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { Github, Linkedin, Twitter, Mail } from "lucide-react";
|
||||||
|
|
||||||
|
export default function Footer() {
|
||||||
|
return (
|
||||||
|
<footer className="border-t py-10 bg-background">
|
||||||
|
<div className="mx-auto max-w-6xl px-6 flex flex-col md:flex-row items-center justify-between gap-4">
|
||||||
|
<div className="text-sm text-muted-foreground">© 2026 Alex Rivera. Crafted with care.</div>
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
{[Github, Linkedin, Twitter, Mail].map((Icon, i) => (
|
||||||
|
<a key={i} href="#" className="text-muted-foreground hover:text-foreground transition-colors"><Icon className="h-5 w-5" /></a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet";
|
||||||
|
import { Menu } from "lucide-react";
|
||||||
|
import { ThemeToggle } from "@/components/ThemeToggle";
|
||||||
|
|
||||||
|
export default function Header() {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [scrolled, setScrolled] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fn = () => setScrolled(window.scrollY > 20);
|
||||||
|
window.addEventListener("scroll", fn);
|
||||||
|
return () => window.removeEventListener("scroll", fn);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const links = [
|
||||||
|
{ label: "Work", to: "/work" },
|
||||||
|
{ label: "About", to: "/about" },
|
||||||
|
{ label: "Contact", to: "/contact" },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<header className={\`fixed top-0 inset-x-0 z-50 transition-all duration-300 \${scrolled ? "bg-background/80 backdrop-blur-lg border-b shadow-sm" : "bg-transparent"}\`}>
|
||||||
|
<div className="mx-auto max-w-6xl flex items-center justify-between px-6 py-5">
|
||||||
|
<Link to="/" className="text-lg font-bold tracking-tight">Alex Rivera</Link>
|
||||||
|
<nav className="hidden md:flex items-center gap-8">
|
||||||
|
{links.map((l) => (
|
||||||
|
<Link key={l.to} to={l.to} className="text-sm text-muted-foreground hover:text-foreground transition-colors">{l.label}</Link>
|
||||||
|
))}
|
||||||
|
<ThemeToggle />
|
||||||
|
<Button asChild size="sm" className="active:scale-[0.98]"><Link to="/contact">Let's Talk</Link></Button>
|
||||||
|
</nav>
|
||||||
|
<Sheet open={open} onOpenChange={setOpen}>
|
||||||
|
<SheetTrigger asChild className="md:hidden">
|
||||||
|
<Button variant="ghost" size="icon"><Menu className="h-5 w-5" /></Button>
|
||||||
|
</SheetTrigger>
|
||||||
|
<SheetContent side="right" className="w-72">
|
||||||
|
<nav className="mt-8 flex flex-col gap-4">
|
||||||
|
{links.map((l) => (
|
||||||
|
<Link key={l.to} to={l.to} className="text-lg font-medium" onClick={() => setOpen(false)}>{l.label}</Link>
|
||||||
|
))}
|
||||||
|
<Button asChild className="mt-4 w-full"><Link to="/contact" onClick={() => setOpen(false)}>Let's Talk</Link></Button>
|
||||||
|
<ThemeToggle />
|
||||||
|
</nav>
|
||||||
|
</SheetContent>
|
||||||
|
</Sheet>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import React from "react";
|
||||||
|
import ReactDOM from "react-dom/client";
|
||||||
|
import App from "./App";
|
||||||
|
import "./index.css";
|
||||||
|
|
||||||
|
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>
|
||||||
|
);
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { Separator } from "@/components/ui/separator";
|
||||||
|
import {
|
||||||
|
Download, Award, Briefcase, GraduationCap, ArrowRight
|
||||||
|
} from "lucide-react";
|
||||||
|
import Header from "@/components/Header";
|
||||||
|
import Footer from "@/components/Footer";
|
||||||
|
|
||||||
|
const stats = [
|
||||||
|
{ value: "8+", label: "Years Experience" },
|
||||||
|
{ value: "50+", label: "Projects Completed" },
|
||||||
|
{ value: "30+", label: "Happy Clients" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const experience = [
|
||||||
|
{ company: "TechVentures Inc.", role: "Senior Product Designer", years: "2022 — Present", desc: "Leading design for the core product suite, managing a team of 4 designers, and establishing the company design system." },
|
||||||
|
{ company: "DesignLab Studio", role: "UI/UX Designer & Developer", years: "2020 — 2022", desc: "Designed and built web applications for Fortune 500 clients. Led the frontend development of 12+ projects." },
|
||||||
|
{ company: "Pixel Perfect Agency", role: "Junior Designer", years: "2018 — 2020", desc: "Crafted visual identities, marketing materials, and responsive websites for startups and SMBs." },
|
||||||
|
{ company: "Freelance", role: "Web Designer", years: "2016 — 2018", desc: "Built custom WordPress and React sites for local businesses while completing university studies." },
|
||||||
|
];
|
||||||
|
|
||||||
|
const awards = [
|
||||||
|
{ title: "Best Portfolio Design", org: "Awwwards", year: "2024" },
|
||||||
|
{ title: "Design Excellence", org: "CSS Design Awards", year: "2023" },
|
||||||
|
{ title: "Top 10 Designers", org: "Dribbble", year: "2023" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function AboutPage() {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-background text-foreground antialiased">
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
{/* ── HERO ── */}
|
||||||
|
<section className="pt-32 pb-24 px-6">
|
||||||
|
<div className="mx-auto max-w-6xl grid lg:grid-cols-2 gap-16 items-center">
|
||||||
|
<div>
|
||||||
|
<h1 className="text-4xl sm:text-5xl font-bold tracking-tight mb-6 animate-fade-up">About Me</h1>
|
||||||
|
<p className="text-muted-foreground leading-relaxed text-lg mb-4">I am a multidisciplinary designer and developer with 8+ years of experience crafting digital products that people love. I specialize in bridging the gap between design and engineering.</p>
|
||||||
|
<p className="text-muted-foreground leading-relaxed text-lg mb-10">When I am not pushing pixels or writing code, you will find me exploring national parks, experimenting with film photography, or contributing to open-source projects.</p>
|
||||||
|
<div className="grid grid-cols-3 gap-6 mb-8">
|
||||||
|
{stats.map((s, i) => (
|
||||||
|
<div key={i}>
|
||||||
|
<div className="text-3xl font-bold bg-gradient-to-r from-primary to-violet-500 bg-clip-text text-transparent">{s.value}</div>
|
||||||
|
<div className="text-sm text-muted-foreground mt-1">{s.label}</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<Button variant="outline" className="rounded-full px-6 active:scale-[0.98]">
|
||||||
|
<Download className="mr-2 h-4 w-4" /> Download Resume
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="flex-shrink-0">
|
||||||
|
<div className="aspect-square rounded-2xl bg-gradient-to-br from-primary/20 via-primary/10 to-primary/5 flex items-center justify-center relative overflow-hidden animate-scale-in">
|
||||||
|
<div className="absolute inset-0" style={{ backgroundImage: "radial-gradient(circle at 25% 25%, rgba(255,255,255,0.15) 1px, transparent 1px)", backgroundSize: "20px 20px" }} />
|
||||||
|
<div className="absolute top-8 left-8 w-24 h-24 rounded-full bg-primary/10 blur-2xl" />
|
||||||
|
<div className="absolute bottom-10 right-10 w-32 h-32 rounded-full bg-primary/10 blur-3xl" />
|
||||||
|
<div className="text-6xl font-black text-primary/20 relative z-10">
|
||||||
|
{("Alex Rivera").split(" ").map((n: string) => n[0]).join("")}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── EXPERIENCE ── */}
|
||||||
|
<section className="py-24 bg-muted/30">
|
||||||
|
<div className="mx-auto max-w-4xl px-6">
|
||||||
|
<h2 className="text-3xl sm:text-4xl font-bold tracking-tight mb-12 flex items-center gap-3 animate-fade-up">
|
||||||
|
<Briefcase className="h-7 w-7 text-primary" /> Experience
|
||||||
|
</h2>
|
||||||
|
<div className="space-y-0 stagger">
|
||||||
|
{experience.map((e, i) => (
|
||||||
|
<div key={i} className="relative pl-8 pb-12 last:pb-0 border-l-2 border-primary/20">
|
||||||
|
<div className="absolute -left-[9px] top-0 w-4 h-4 rounded-full bg-primary border-4 border-background ring-4 ring-primary/20" />
|
||||||
|
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between mb-2">
|
||||||
|
<h3 className="font-semibold text-lg">{e.role}</h3>
|
||||||
|
<span className="text-sm text-muted-foreground">{e.years}</span>
|
||||||
|
</div>
|
||||||
|
<div className="text-sm font-medium text-primary mb-2">{e.company}</div>
|
||||||
|
<p className="text-muted-foreground leading-relaxed">{e.desc}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── AWARDS ── */}
|
||||||
|
<section className="py-24">
|
||||||
|
<div className="mx-auto max-w-4xl px-6">
|
||||||
|
<h2 className="text-3xl sm:text-4xl font-bold tracking-tight mb-12 flex items-center gap-3 animate-fade-up">
|
||||||
|
<Award className="h-7 w-7 text-primary" /> Recognition
|
||||||
|
</h2>
|
||||||
|
<div className="grid md:grid-cols-3 gap-6 stagger">
|
||||||
|
{awards.map((a, i) => (
|
||||||
|
<Card key={i} className="hover-card-lift transition-all duration-300 backdrop-blur-sm bg-card/80">
|
||||||
|
<CardContent className="pt-6">
|
||||||
|
<Badge variant="secondary" className="mb-3">{a.year}</Badge>
|
||||||
|
<h3 className="font-semibold mb-1">{a.title}</h3>
|
||||||
|
<p className="text-sm text-muted-foreground">{a.org}</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── EDUCATION ── */}
|
||||||
|
<section className="py-24 bg-muted/30">
|
||||||
|
<div className="mx-auto max-w-4xl px-6">
|
||||||
|
<h2 className="text-3xl sm:text-4xl font-bold tracking-tight mb-12 flex items-center gap-3 animate-fade-up">
|
||||||
|
<GraduationCap className="h-7 w-7 text-primary" /> Education
|
||||||
|
</h2>
|
||||||
|
<div className="space-y-6">
|
||||||
|
<div>
|
||||||
|
<h3 className="font-semibold text-lg">B.S. Computer Science</h3>
|
||||||
|
<div className="text-sm text-primary">Stanford University</div>
|
||||||
|
<div className="text-sm text-muted-foreground">2012 — 2016</div>
|
||||||
|
</div>
|
||||||
|
<Separator />
|
||||||
|
<div>
|
||||||
|
<h3 className="font-semibold text-lg">UX Design Certificate</h3>
|
||||||
|
<div className="text-sm text-primary">Google / Coursera</div>
|
||||||
|
<div className="text-sm text-muted-foreground">2018</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── CTA ── */}
|
||||||
|
<section className="py-24">
|
||||||
|
<div className="mx-auto max-w-3xl px-6 text-center">
|
||||||
|
<h2 className="text-3xl sm:text-4xl font-bold tracking-tight mb-4 animate-fade-up">Interested in working together?</h2>
|
||||||
|
<p className="text-muted-foreground mb-8">I'm always open to new opportunities and collaborations.</p>
|
||||||
|
<Button asChild size="lg" className="rounded-full px-8 shadow-lg active:scale-[0.98]">
|
||||||
|
<Link to="/contact" className="inline-flex items-center gap-1 hover:gap-2 transition-all">Get in Touch <ArrowRight className="h-4 w-4" /></Link>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
|
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
|
||||||
|
import {
|
||||||
|
ArrowRight, Mail, MapPin, Linkedin, Github, Twitter, CheckCircle2
|
||||||
|
} from "lucide-react";
|
||||||
|
import Header from "@/components/Header";
|
||||||
|
import Footer from "@/components/Footer";
|
||||||
|
|
||||||
|
const faqs = [
|
||||||
|
{ q: "What is your typical project timeline?", a: "Most projects take 4-8 weeks depending on scope. I will provide a detailed timeline during our initial consultation." },
|
||||||
|
{ q: "What are your rates?", a: "I offer both project-based and retainer pricing. Rates depend on project scope and complexity. Let us chat to find the right fit." },
|
||||||
|
{ q: "Do you work with international clients?", a: "Absolutely! I work with clients worldwide and am comfortable with asynchronous communication across time zones." },
|
||||||
|
{ q: "What tools do you use?", a: "Figma for design, React/Next.js for development, and tools like Framer Motion, Tailwind CSS, and TypeScript for building modern interfaces." },
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function ContactPage() {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-background text-foreground antialiased">
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
<section className="pt-32 pb-24 px-6">
|
||||||
|
<div className="mx-auto max-w-6xl">
|
||||||
|
<h1 className="text-4xl sm:text-5xl font-bold tracking-tight mb-4 animate-fade-up">Let's Work Together</h1>
|
||||||
|
<p className="text-lg text-muted-foreground max-w-xl mb-16">Have a project in mind? I would love to hear about it. Send me a message and I will get back to you within 24 hours.</p>
|
||||||
|
|
||||||
|
<div className="grid gap-12 lg:grid-cols-2">
|
||||||
|
{/* ── LEFT: Contact info ── */}
|
||||||
|
<div className="space-y-8">
|
||||||
|
<div className="space-y-6">
|
||||||
|
{[
|
||||||
|
{ icon: Mail, label: "Email", value: "hello@alexrivera.dev" },
|
||||||
|
{ icon: MapPin, label: "Location", value: "San Francisco, CA" },
|
||||||
|
{ icon: Linkedin, label: "LinkedIn", value: "linkedin.com/in/alexrivera" },
|
||||||
|
].map((item, i) => (
|
||||||
|
<div key={i} className="flex items-start gap-4">
|
||||||
|
<div className="h-12 w-12 rounded-xl bg-primary/10 flex items-center justify-center flex-shrink-0 shadow-lg shadow-primary/10">
|
||||||
|
<item.icon className="h-5 w-5 text-primary" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="font-medium">{item.label}</div>
|
||||||
|
<div className="text-muted-foreground">{item.value}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-3 pt-4">
|
||||||
|
{[Github, Linkedin, Twitter].map((Icon, i) => (
|
||||||
|
<a key={i} href="#" className="h-10 w-10 rounded-full bg-muted flex items-center justify-center text-muted-foreground hover:text-foreground hover:bg-muted/80 transition-colors">
|
||||||
|
<Icon className="h-4 w-4" />
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ── RIGHT: Form ── */}
|
||||||
|
<Card className="border shadow-sm backdrop-blur-sm bg-card/80 border-border/50">
|
||||||
|
<CardContent className="p-6">
|
||||||
|
<form onSubmit={(e: React.FormEvent) => { e.preventDefault(); toast.success("Message sent! I'll get back to you within 24 hours."); (e.target as HTMLFormElement).reset(); }} className="space-y-4">
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<label className="text-sm font-medium mb-1.5 block">Name</label>
|
||||||
|
<Input placeholder="Your name" required />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="text-sm font-medium mb-1.5 block">Email</label>
|
||||||
|
<Input placeholder="your@email.com" type="email" required />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="text-sm font-medium mb-1.5 block">Subject</label>
|
||||||
|
<Input placeholder="Project inquiry" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="text-sm font-medium mb-1.5 block">Message</label>
|
||||||
|
<Textarea placeholder="Tell me about your project..." className="min-h-[140px] resize-none" required />
|
||||||
|
</div>
|
||||||
|
<Button type="submit" className="w-full rounded-full active:scale-[0.98]">
|
||||||
|
Send Message <ArrowRight className="ml-2 h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
<div className="flex items-center justify-center gap-2 text-sm text-muted-foreground mt-3">
|
||||||
|
<CheckCircle2 className="h-4 w-4 text-green-500" />
|
||||||
|
<span>Response time: within 24 hours</span>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── FAQ ── */}
|
||||||
|
<section className="py-24 bg-muted/30">
|
||||||
|
<div className="mx-auto max-w-3xl px-6">
|
||||||
|
<h2 className="text-3xl sm:text-4xl font-bold tracking-tight text-center mb-12 animate-fade-up">Frequently Asked Questions</h2>
|
||||||
|
<Accordion type="single" collapsible className="w-full stagger">
|
||||||
|
{faqs.map((f, i) => (
|
||||||
|
<AccordionItem key={i} value={\`faq-\${i}\`}>
|
||||||
|
<AccordionTrigger className="text-left">{f.q}</AccordionTrigger>
|
||||||
|
<AccordionContent className="text-muted-foreground">{f.a}</AccordionContent>
|
||||||
|
</AccordionItem>
|
||||||
|
))}
|
||||||
|
</Accordion>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,208 @@
|
|||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { Progress } from "@/components/ui/progress";
|
||||||
|
import {
|
||||||
|
ArrowRight, ExternalLink, Palette, Github, Star,
|
||||||
|
ChevronRight, ChevronDown
|
||||||
|
} from "lucide-react";
|
||||||
|
import Header from "@/components/Header";
|
||||||
|
import Footer from "@/components/Footer";
|
||||||
|
|
||||||
|
const projects = [
|
||||||
|
{ title: "Fintech Dashboard Redesign", desc: "Complete overhaul of the analytics dashboard for a Series B fintech startup, improving engagement by 40%.", tags: ["React", "TypeScript", "Figma"], gradient: "from-violet-400 to-purple-600" },
|
||||||
|
{ title: "E-Commerce Mobile App", desc: "End-to-end design and development of a premium shopping experience serving 100K+ monthly active users.", tags: ["React Native", "Node.js", "Stripe"], gradient: "from-sky-400 to-blue-600" },
|
||||||
|
{ title: "Healthcare Platform", desc: "HIPAA-compliant patient portal with appointment scheduling, telehealth, and real-time chat.", tags: ["Next.js", "PostgreSQL", "Tailwind"], gradient: "from-amber-400 to-orange-600" },
|
||||||
|
{ title: "SaaS Marketing Site", desc: "High-converting marketing website with interactive demos, resulting in 65% increase in trial signups.", tags: ["Astro", "GSAP", "Framer Motion"], gradient: "from-emerald-400 to-green-600" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const logos = ["Acme", "Globex", "Initech", "Umbrella", "Aperture", "Wayne"];
|
||||||
|
|
||||||
|
const testimonials = [
|
||||||
|
{ name: "Sarah Chen", role: "CTO, TechVentures", quote: "Working with Alex was transformational. Delivered beyond expectations and on time." },
|
||||||
|
{ name: "Marcus Lee", role: "Founder, DesignLab", quote: "Exceptional design sense combined with technical prowess. Highly recommended." },
|
||||||
|
];
|
||||||
|
|
||||||
|
const designSkills = [
|
||||||
|
{ name: "UI/UX Design", value: 95 },
|
||||||
|
{ name: "Design Systems", value: 90 },
|
||||||
|
{ name: "Prototyping", value: 85 },
|
||||||
|
];
|
||||||
|
|
||||||
|
const devSkills = [
|
||||||
|
{ name: "React / Next.js", value: 95 },
|
||||||
|
{ name: "TypeScript", value: 90 },
|
||||||
|
{ name: "Node.js", value: 85 },
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function IndexPage() {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-background text-foreground antialiased">
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
{/* ── HERO ── */}
|
||||||
|
<section className="relative pt-32 pb-24 px-6 overflow-hidden">
|
||||||
|
<div className="absolute top-20 left-10 w-72 h-72 rounded-full bg-primary/10 blur-[120px]" />
|
||||||
|
<div className="absolute top-40 right-20 w-96 h-96 rounded-full bg-violet-500/15 blur-[120px]" />
|
||||||
|
<div className="absolute bottom-10 left-1/3 w-64 h-64 rounded-full bg-primary/10 blur-[120px]" />
|
||||||
|
<div className="mx-auto max-w-6xl relative z-10">
|
||||||
|
<Badge variant="secondary" className="px-3 py-1 text-sm font-medium mb-6">
|
||||||
|
<span className="relative flex h-2 w-2 mr-2">
|
||||||
|
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75" />
|
||||||
|
<span className="relative inline-flex rounded-full h-2 w-2 bg-green-500" />
|
||||||
|
</span>
|
||||||
|
Available for hire
|
||||||
|
</Badge>
|
||||||
|
<h1 className="text-6xl md:text-9xl font-black tracking-tighter leading-[0.9]">Alex Rivera</h1>
|
||||||
|
<p className="mt-4 text-xl md:text-2xl text-muted-foreground font-light">Product Designer & Frontend Developer</p>
|
||||||
|
<div className="h-1 w-32 bg-gradient-to-r from-primary via-violet-500 to-primary/50 rounded-full mt-6 animate-fade-in" />
|
||||||
|
<div className="flex flex-col sm:flex-row gap-4 mt-8">
|
||||||
|
<Button asChild size="lg" className="rounded-full px-8 text-base shadow-lg active:scale-[0.98]">
|
||||||
|
<Link to="/work" className="inline-flex items-center gap-1 hover:gap-2 transition-all">View My Work <ArrowRight className="h-4 w-4" /></Link>
|
||||||
|
</Button>
|
||||||
|
<Button asChild size="lg" variant="outline" className="rounded-full px-8 text-base active:scale-[0.98]">
|
||||||
|
<Link to="/contact">Get in Touch</Link>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="absolute bottom-8 left-1/2 -translate-x-1/2 animate-bounce"><ChevronDown className="h-6 w-6 text-muted-foreground" /></div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── CLIENT LOGOS ── */}
|
||||||
|
<section className="py-24">
|
||||||
|
<div className="mx-auto max-w-6xl px-6 text-center animate-fade-in">
|
||||||
|
<div className="border-t border-border/50 mb-12" />
|
||||||
|
<p className="text-sm uppercase tracking-wider text-muted-foreground font-medium mb-8">Trusted By</p>
|
||||||
|
<div className="grid grid-cols-3 md:grid-cols-6 gap-8 items-center justify-items-center">
|
||||||
|
{logos.map((name, i) => (
|
||||||
|
<div key={i} className="grayscale opacity-40 hover:grayscale-0 hover:opacity-100 hover:text-primary transition-all duration-300 cursor-pointer text-xl font-bold text-muted-foreground">{name}</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="border-t border-border/50 mt-12" />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── FEATURED PROJECTS ── */}
|
||||||
|
<section className="py-24 bg-muted/30">
|
||||||
|
<div className="mx-auto max-w-6xl px-6">
|
||||||
|
<div className="flex items-end justify-between mb-16">
|
||||||
|
<h2 className="text-3xl sm:text-4xl font-bold tracking-tight animate-fade-up">Selected Work</h2>
|
||||||
|
<Button asChild variant="ghost" className="hidden sm:flex">
|
||||||
|
<Link to="/work">View All <ChevronRight className="ml-1 h-4 w-4" /></Link>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="grid gap-8 grid-cols-1 lg:grid-cols-2 stagger">
|
||||||
|
{projects.map((p, i) => (
|
||||||
|
<Link key={i} to="/project" className="group block hover:-translate-y-1 hover:shadow-xl transition-all duration-300 rounded-2xl">
|
||||||
|
<div className="relative overflow-hidden rounded-2xl animate-scale-in">
|
||||||
|
<div className={\`aspect-video bg-gradient-to-br \${p.gradient} flex items-center justify-center transition-transform duration-500 group-hover:scale-105 relative\`}>
|
||||||
|
<div className="absolute inset-0" style={{ backgroundImage: "radial-gradient(circle at 25% 25%, rgba(255,255,255,0.15) 1px, transparent 1px)", backgroundSize: "20px 20px" }} />
|
||||||
|
<div className="absolute top-6 left-6 w-20 h-20 rounded-full bg-white/10 blur-xl" />
|
||||||
|
<div className="absolute bottom-8 right-10 w-28 h-28 rounded-full bg-white/10 blur-2xl" />
|
||||||
|
<Palette className="h-16 w-16 text-white/30 relative z-10" />
|
||||||
|
</div>
|
||||||
|
<div className="absolute bottom-0 left-0 right-0 p-6 bg-gradient-to-t from-black/80 to-transparent translate-y-full group-hover:translate-y-0 transition-transform duration-500">
|
||||||
|
<h3 className="text-white font-semibold text-lg">{p.title}</h3>
|
||||||
|
<p className="text-white/70 text-sm mt-1">{p.desc}</p>
|
||||||
|
<div className="flex flex-wrap gap-2 mt-3">
|
||||||
|
{p.tags.map((tag, j) => (
|
||||||
|
<Badge key={j} variant="secondary" className="text-xs bg-white/10 text-white/90 border-white/20">{tag}</Badge>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── TESTIMONIALS ── */}
|
||||||
|
<section className="py-24">
|
||||||
|
<div className="mx-auto max-w-4xl px-6">
|
||||||
|
<h2 className="text-3xl sm:text-4xl font-bold tracking-tight text-center mb-16 animate-fade-up">What Clients Say</h2>
|
||||||
|
<div className="grid md:grid-cols-2 gap-8 stagger">
|
||||||
|
{testimonials.map((t, i) => (
|
||||||
|
<Card key={i} className="hover-card-lift transition-all duration-300">
|
||||||
|
<CardContent className="pt-6">
|
||||||
|
<div className="flex gap-0.5 mb-4">
|
||||||
|
{[...Array(5)].map((_, j) => (
|
||||||
|
<Star key={j} className="h-4 w-4 fill-amber-400 text-amber-400" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<p className="text-muted-foreground italic leading-relaxed">"{t.quote}"</p>
|
||||||
|
<div className="mt-6 flex items-center gap-3">
|
||||||
|
<div className="w-10 h-10 rounded-full bg-gradient-to-br from-primary/60 to-violet-500/60 flex items-center justify-center text-xs font-bold text-white">
|
||||||
|
{t.name.split(" ").map((n: string) => n[0]).join("")}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="font-semibold text-sm">{t.name}</div>
|
||||||
|
<div className="text-xs text-muted-foreground">{t.role}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── SKILLS PREVIEW ── */}
|
||||||
|
<section className="py-24 bg-muted/30">
|
||||||
|
<div className="mx-auto max-w-4xl px-6">
|
||||||
|
<h2 className="text-3xl sm:text-4xl font-bold tracking-tight text-center mb-16 animate-fade-up">Skills & Expertise</h2>
|
||||||
|
<div className="grid gap-8 md:grid-cols-2 stagger">
|
||||||
|
<Card className="border shadow-sm hover-card-lift transition-all duration-300">
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle className="flex items-center gap-2"><Palette className="h-5 w-5 text-primary" /> Design</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="space-y-5">
|
||||||
|
{designSkills.map((s, i) => (
|
||||||
|
<div key={i}>
|
||||||
|
<div className="flex justify-between text-sm mb-1.5">
|
||||||
|
<span className="font-medium">{s.name}</span>
|
||||||
|
<span className="text-muted-foreground">{s.value}%</span>
|
||||||
|
</div>
|
||||||
|
<Progress value={s.value} className="h-2" />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
<Card className="border shadow-sm hover-card-lift transition-all duration-300">
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle className="flex items-center gap-2"><Github className="h-5 w-5 text-primary" /> Development</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="space-y-5">
|
||||||
|
{devSkills.map((s, i) => (
|
||||||
|
<div key={i}>
|
||||||
|
<div className="flex justify-between text-sm mb-1.5">
|
||||||
|
<span className="font-medium">{s.name}</span>
|
||||||
|
<span className="text-muted-foreground">{s.value}%</span>
|
||||||
|
</div>
|
||||||
|
<Progress value={s.value} className="h-2" />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── CTA ── */}
|
||||||
|
<section className="py-24">
|
||||||
|
<div className="mx-auto max-w-3xl px-6 text-center">
|
||||||
|
<h2 className="text-3xl sm:text-4xl font-bold tracking-tight mb-4 animate-fade-up">Let's Build Something Amazing</h2>
|
||||||
|
<p className="text-muted-foreground mb-8 max-w-xl mx-auto">Have a project in mind? I would love to hear about it and explore how we can work together.</p>
|
||||||
|
<div className="flex gap-4 justify-center">
|
||||||
|
<Button asChild size="lg" className="rounded-full px-8 shadow-lg active:scale-[0.98]">
|
||||||
|
<Link to="/contact">Start a Project <ArrowRight className="ml-2 h-4 w-4" /></Link>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,204 @@
|
|||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { Separator } from "@/components/ui/separator";
|
||||||
|
import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog";
|
||||||
|
import {
|
||||||
|
ArrowLeft, ArrowRight, Star, ExternalLink, Palette, ZoomIn, Quote
|
||||||
|
} from "lucide-react";
|
||||||
|
import Header from "@/components/Header";
|
||||||
|
import Footer from "@/components/Footer";
|
||||||
|
|
||||||
|
const metrics = [
|
||||||
|
{ value: "+40%", label: "Engagement" },
|
||||||
|
{ value: "-55%", label: "Support Tickets" },
|
||||||
|
{ value: "2x", label: "Session Duration" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const techStack = ["React", "TypeScript", "Tailwind CSS", "D3.js", "Framer Motion"];
|
||||||
|
|
||||||
|
export default function ProjectDetailPage() {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-background text-foreground antialiased">
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
{/* ── HERO ── */}
|
||||||
|
<section className="pt-32 pb-16 px-6">
|
||||||
|
<div className="mx-auto max-w-4xl">
|
||||||
|
<Link to="/work" className="inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors mb-8">
|
||||||
|
<ArrowLeft className="h-4 w-4" /> Back to Work
|
||||||
|
</Link>
|
||||||
|
<Badge variant="secondary" className="mb-4">Web Design</Badge>
|
||||||
|
<h1 className="text-4xl sm:text-5xl font-bold tracking-tight animate-fade-up">Fintech Dashboard Redesign</h1>
|
||||||
|
<p className="mt-4 text-lg text-muted-foreground">A complete overhaul of the analytics dashboard for a Series B fintech startup.</p>
|
||||||
|
<div className="flex flex-wrap gap-6 mt-6 text-sm text-muted-foreground">
|
||||||
|
<span><strong className="text-foreground">Client:</strong> FinanceFlow</span>
|
||||||
|
<span><strong className="text-foreground">Year:</strong> 2025</span>
|
||||||
|
<span><strong className="text-foreground">Duration:</strong> 3 months</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── HERO IMAGE ── */}
|
||||||
|
<section className="px-6 pb-16">
|
||||||
|
<div className="mx-auto max-w-5xl">
|
||||||
|
<Dialog>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<div className="aspect-video rounded-2xl bg-gradient-to-br from-violet-400 to-purple-600 flex items-center justify-center relative overflow-hidden animate-scale-in cursor-pointer group">
|
||||||
|
<div className="absolute inset-0" style={{ backgroundImage: "radial-gradient(circle at 25% 25%, rgba(255,255,255,0.15) 1px, transparent 1px)", backgroundSize: "20px 20px" }} />
|
||||||
|
<div className="absolute top-10 left-10 w-32 h-32 rounded-full bg-white/10 blur-2xl" />
|
||||||
|
<div className="absolute bottom-12 right-16 w-40 h-40 rounded-full bg-white/10 blur-3xl" />
|
||||||
|
<Palette className="h-24 w-24 text-white/20 relative z-10" />
|
||||||
|
<div className="absolute bottom-4 right-4 z-20 flex items-center gap-1.5 bg-black/40 backdrop-blur-sm text-white/70 text-xs px-3 py-1.5 rounded-full opacity-0 group-hover:opacity-100 transition-opacity">
|
||||||
|
<ZoomIn className="h-3.5 w-3.5" /> Click to enlarge
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className="max-w-5xl p-0 overflow-hidden rounded-2xl">
|
||||||
|
<div className="aspect-video bg-gradient-to-br from-violet-400 to-purple-600 flex items-center justify-center relative overflow-hidden">
|
||||||
|
<div className="absolute inset-0" style={{ backgroundImage: "radial-gradient(circle at 25% 25%, rgba(255,255,255,0.15) 1px, transparent 1px)", backgroundSize: "20px 20px" }} />
|
||||||
|
<div className="absolute top-10 left-10 w-32 h-32 rounded-full bg-white/10 blur-2xl" />
|
||||||
|
<div className="absolute bottom-12 right-16 w-40 h-40 rounded-full bg-white/10 blur-3xl" />
|
||||||
|
<Palette className="h-24 w-24 text-white/20 relative z-10" />
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── CHALLENGE / SOLUTION / RESULTS ── */}
|
||||||
|
<section className="py-24 px-6">
|
||||||
|
<div className="mx-auto max-w-5xl grid lg:grid-cols-[1fr_280px] gap-12">
|
||||||
|
<div className="grid md:grid-cols-3 gap-12">
|
||||||
|
<div>
|
||||||
|
<h3 className="text-sm font-semibold uppercase tracking-wider text-primary mb-3">The Challenge</h3>
|
||||||
|
<p className="text-muted-foreground leading-relaxed">The existing dashboard was cluttered and had a 60% drop-off rate. Users struggled to find critical financial data and the interface felt outdated.</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className="text-sm font-semibold uppercase tracking-wider text-primary mb-3">The Solution</h3>
|
||||||
|
<p className="text-muted-foreground leading-relaxed">Redesigned the information architecture, introduced a modular card system, and built real-time data visualizations with smooth animations.</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className="text-sm font-semibold uppercase tracking-wider text-primary mb-3">The Impact</h3>
|
||||||
|
<p className="text-muted-foreground leading-relaxed">User engagement increased by 40%, support tickets dropped 55%, and the average session duration doubled within the first month.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Card className="h-fit backdrop-blur-sm bg-card/80 border-border/50">
|
||||||
|
<CardContent className="pt-6 space-y-4">
|
||||||
|
<h4 className="font-semibold text-sm uppercase tracking-wider text-primary">Project Overview</h4>
|
||||||
|
<div>
|
||||||
|
<div className="text-xs text-muted-foreground">Client</div>
|
||||||
|
<div className="font-medium text-sm">FinanceFlow</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="text-xs text-muted-foreground">Duration</div>
|
||||||
|
<div className="font-medium text-sm">3 months</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="text-xs text-muted-foreground">Role</div>
|
||||||
|
<div className="font-medium text-sm">Design & Development</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="text-xs text-muted-foreground">Tech Stack</div>
|
||||||
|
<div className="flex flex-wrap gap-1.5 mt-1">
|
||||||
|
{["React", "TypeScript", "Tailwind CSS"].map((t, i) => (
|
||||||
|
<Badge key={i} variant="secondary" className="text-xs">{t}</Badge>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── KEY METRICS ── */}
|
||||||
|
<section className="py-24 bg-muted/30">
|
||||||
|
<div className="mx-auto max-w-4xl px-6 grid grid-cols-3 gap-8">
|
||||||
|
{metrics.map((m, i) => (
|
||||||
|
<div key={i} className="text-center">
|
||||||
|
<div className="text-4xl font-black bg-gradient-to-r from-primary to-violet-500 bg-clip-text text-transparent">{m.value}</div>
|
||||||
|
<div className="text-sm text-muted-foreground mt-1">{m.label}</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── SECOND IMAGE ── */}
|
||||||
|
<section className="py-24 px-6">
|
||||||
|
<div className="mx-auto max-w-5xl">
|
||||||
|
<Dialog>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<div className="aspect-[2/1] rounded-2xl bg-gradient-to-br from-sky-400 to-indigo-600 flex items-center justify-center relative overflow-hidden animate-scale-in cursor-pointer group">
|
||||||
|
<div className="absolute inset-0" style={{ backgroundImage: "radial-gradient(circle at 25% 25%, rgba(255,255,255,0.15) 1px, transparent 1px)", backgroundSize: "20px 20px" }} />
|
||||||
|
<div className="absolute top-8 right-12 w-28 h-28 rounded-full bg-white/10 blur-2xl" />
|
||||||
|
<div className="absolute bottom-10 left-8 w-36 h-36 rounded-full bg-white/10 blur-3xl" />
|
||||||
|
<Palette className="h-24 w-24 text-white/20 relative z-10" />
|
||||||
|
<div className="absolute bottom-4 right-4 z-20 flex items-center gap-1.5 bg-black/40 backdrop-blur-sm text-white/70 text-xs px-3 py-1.5 rounded-full opacity-0 group-hover:opacity-100 transition-opacity">
|
||||||
|
<ZoomIn className="h-3.5 w-3.5" /> Click to enlarge
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className="max-w-5xl p-0 overflow-hidden rounded-2xl">
|
||||||
|
<div className="aspect-[2/1] bg-gradient-to-br from-sky-400 to-indigo-600 flex items-center justify-center relative overflow-hidden">
|
||||||
|
<div className="absolute inset-0" style={{ backgroundImage: "radial-gradient(circle at 25% 25%, rgba(255,255,255,0.15) 1px, transparent 1px)", backgroundSize: "20px 20px" }} />
|
||||||
|
<div className="absolute top-8 right-12 w-28 h-28 rounded-full bg-white/10 blur-2xl" />
|
||||||
|
<div className="absolute bottom-10 left-8 w-36 h-36 rounded-full bg-white/10 blur-3xl" />
|
||||||
|
<Palette className="h-24 w-24 text-white/20 relative z-10" />
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── CLIENT TESTIMONIAL ── */}
|
||||||
|
<section className="py-24 px-6">
|
||||||
|
<div className="mx-auto max-w-3xl">
|
||||||
|
<Card className="backdrop-blur-sm bg-card/80 border-border/50">
|
||||||
|
<CardContent className="pt-8 pb-8 text-center">
|
||||||
|
<Quote className="h-10 w-10 text-primary/30 mx-auto mb-4" />
|
||||||
|
<div className="flex justify-center gap-0.5 mb-6">
|
||||||
|
{[...Array(5)].map((_, j) => (
|
||||||
|
<Star key={j} className="h-5 w-5 fill-amber-400 text-amber-400" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<blockquote className="text-xl italic text-muted-foreground leading-relaxed">"Alex completely transformed our product. The new dashboard is intuitive, beautiful, and our users love it."</blockquote>
|
||||||
|
<div className="mt-6">
|
||||||
|
<div className="font-semibold">David Park</div>
|
||||||
|
<div className="text-sm text-muted-foreground">CPO, FinanceFlow</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Separator className="mx-auto max-w-4xl" />
|
||||||
|
|
||||||
|
{/* ── TECH STACK ── */}
|
||||||
|
<section className="py-24 px-6">
|
||||||
|
<div className="mx-auto max-w-4xl">
|
||||||
|
<h2 className="text-3xl sm:text-4xl font-bold tracking-tight mb-12 animate-fade-up">Tech Stack</h2>
|
||||||
|
<div className="flex flex-wrap gap-3 stagger">
|
||||||
|
{techStack.map((t, i) => (
|
||||||
|
<Badge key={i} variant="outline" className="text-sm px-4 py-2 hover-card-lift transition-all duration-300 cursor-default">{t}</Badge>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── NEXT/PREV ── */}
|
||||||
|
<section className="py-24 px-6 border-t">
|
||||||
|
<div className="mx-auto max-w-4xl flex items-center justify-between">
|
||||||
|
<Button asChild variant="ghost" className="active:scale-[0.98]">
|
||||||
|
<Link to="/work" className="inline-flex items-center gap-1 hover:gap-2 transition-all"><ArrowLeft className="h-4 w-4" /> Previous Project</Link>
|
||||||
|
</Button>
|
||||||
|
<Button asChild variant="ghost" className="active:scale-[0.98]">
|
||||||
|
<Link to="/work" className="inline-flex items-center gap-1 hover:gap-2 transition-all">Next Project <ArrowRight className="h-4 w-4" /></Link>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { Palette, ExternalLink, ChevronRight } from "lucide-react";
|
||||||
|
import Header from "@/components/Header";
|
||||||
|
import Footer from "@/components/Footer";
|
||||||
|
|
||||||
|
const categories = ["All", "Web Design", "Mobile", "Branding", "Full-Stack"];
|
||||||
|
|
||||||
|
const projects = [
|
||||||
|
{ title: "", desc: "", tags: ["", "", ""], cat: "Web Design", gradient: "from-violet-400 to-purple-600" },
|
||||||
|
{ title: "", desc: "", tags: ["", "", ""], cat: "Web Design", gradient: "from-sky-400 to-blue-600" },
|
||||||
|
{ title: "", desc: "", tags: ["", "", ""], cat: "Mobile", gradient: "from-amber-400 to-orange-600" },
|
||||||
|
{ title: "", desc: "", tags: ["", "", ""], cat: "Branding", gradient: "from-emerald-400 to-green-600" },
|
||||||
|
{ title: "Fitness Tracking App", desc: "Cross-platform fitness app with AI-powered workout recommendations and social features.", tags: ["Flutter", "Firebase", "TensorFlow"], cat: "Mobile", gradient: "from-rose-400 to-pink-600" },
|
||||||
|
{ title: "Real Estate Platform", desc: "Property listing platform with 3D tours, map integration, and AI-powered price predictions.", tags: ["Next.js", "Three.js", "Mapbox"], cat: "Full-Stack", gradient: "from-cyan-400 to-teal-600" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function WorkPage() {
|
||||||
|
const [filter, setFilter] = useState("All");
|
||||||
|
const filtered = filter === "All" ? projects : projects.filter((p) => p.cat === filter);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-background text-foreground antialiased">
|
||||||
|
<Header />
|
||||||
|
<section className="pt-32 pb-8 px-6">
|
||||||
|
<div className="mx-auto max-w-6xl">
|
||||||
|
<div className="flex items-center gap-2 text-sm text-muted-foreground mb-4">
|
||||||
|
<Link to="/" className="hover:text-foreground transition-colors">Home</Link>
|
||||||
|
<ChevronRight className="h-3 w-3" />
|
||||||
|
<span>Work</span>
|
||||||
|
</div>
|
||||||
|
<h1 className="text-4xl sm:text-5xl font-bold tracking-tight animate-fade-up">My Work</h1>
|
||||||
|
<p className="mt-4 text-lg text-muted-foreground max-w-2xl">A collection of projects I have worked on, from design systems to full-stack applications.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="pb-24 px-6">
|
||||||
|
<div className="mx-auto max-w-6xl">
|
||||||
|
<div className="flex flex-wrap gap-2 mb-12">
|
||||||
|
{categories.map((c) => (
|
||||||
|
<Button key={c} variant={filter === c ? "default" : "outline"} size="sm" className="rounded-full active:scale-[0.98]" onClick={() => setFilter(c)}>
|
||||||
|
{c}
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="grid gap-8 grid-cols-1 lg:grid-cols-2 stagger">
|
||||||
|
{filtered.map((p, i) => (
|
||||||
|
<Link key={i} to="/project" className="group block hover:-translate-y-1 hover:shadow-xl transition-all duration-300 rounded-2xl">
|
||||||
|
<div className="relative overflow-hidden rounded-2xl animate-scale-in">
|
||||||
|
<div className={\`aspect-video bg-gradient-to-br \${p.gradient} flex items-center justify-center transition-transform duration-500 group-hover:scale-105 relative\`}>
|
||||||
|
<div className="absolute inset-0" style={{ backgroundImage: "radial-gradient(circle at 25% 25%, rgba(255,255,255,0.15) 1px, transparent 1px)", backgroundSize: "20px 20px" }} />
|
||||||
|
<div className="absolute top-6 left-6 w-20 h-20 rounded-full bg-white/10 blur-xl" />
|
||||||
|
<div className="absolute bottom-8 right-10 w-28 h-28 rounded-full bg-white/10 blur-2xl" />
|
||||||
|
<Palette className="h-16 w-16 text-white/30 relative z-10" />
|
||||||
|
</div>
|
||||||
|
<div className="absolute bottom-0 left-0 right-0 p-6 bg-gradient-to-t from-black/80 to-transparent translate-y-full group-hover:translate-y-0 transition-transform duration-500">
|
||||||
|
<h3 className="text-white font-semibold text-lg">{p.title}</h3>
|
||||||
|
<p className="text-white/70 text-sm mt-1">{p.desc}</p>
|
||||||
|
<div className="flex flex-wrap gap-2 mt-3">
|
||||||
|
{p.tags.map((tag, j) => (
|
||||||
|
<Badge key={j} variant="secondary" className="text-xs bg-white/10 text-white/90 border-white/20">{tag}</Badge>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user