# GeekBrain.io VC Fund Website - Complete Implementation Specification
**Project:** GeekBrain.io single-page website
**Status:** Ready for Implementation
**Date:** 2026-03-21
**Based on:** `2026-03-21-geekbrain-vc-webpage-design.md`
---
## Overview
A single-page website for GeekBrain.io, a VC fund. The site establishes brand presence with a futuristic/tech aesthetic, showcasing the fund's identity with particle effects, glitch text animations, and glowing UI elements. This is a minimal launch site (no portfolio yet) designed for easy expansion later.
**Goals:**
- Establish GeekBrain.io's brand presence online
- Create a visually striking first impression with futuristic effects
- Provide basic information about the fund
- Enable contact via LinkedIn
- Built for future expansion when portfolio companies are added
**Type:** Static website (no backend required)
---
## Tech Stack
| Technology | Version | Purpose |
|------------|---------|---------|
| Next.js | 14.x (App Router) | Framework |
| React | 18.x | UI library |
| TypeScript | 5.x | Type safety |
| Tailwind CSS | 3.x | Styling with custom utilities |
| @tsparticles/react | 3.x | Particle background system |
| @tsparticles/slim | 3.x | Lightweight particle preset |
| next/font | built-in | Font optimization |
| Google Fonts | - | Space Grotesk, Inter |
**Why this stack:**
- Next.js 14 App Router provides modern React patterns with minimal configuration
- Static generation (no SSR needed) = fast, cheap hosting
- Tailwind enables rapid development with consistent design system
- tsparticles provides performant, customizable particle effects
- next/font optimizes font loading without layout shift
---
## Project Structure
```
geekbrain-site/
├── app/
│ ├── layout.tsx # Root layout with fonts, dark theme, metadata
│ ├── page.tsx # Main page composing all sections
│ └── globals.css # Tailwind imports + custom animations
├── components/
│ ├── Hero.tsx # Full-screen hero with GlitchText
│ ├── About.tsx # Glassmorphism card with fund info
│ ├── Contact.tsx # LinkedIn social link (uses GlowButton)
│ ├── ParticleBackground.tsx # Full-screen particle canvas
│ ├── GlitchText.tsx # Reusable glitch text component
│ └── GlowButton.tsx # Reusable glowing button/link component
├── public/
│ ├── assets/
│ │ └── images/
│ │ └── Geekbrain-io.png # Logo/brand image
│ └── favicon.ico # Favicon (optional, to be added)
├── lib/
│ └── particles-config.ts # tsparticles configuration
├── tailwind.config.ts # Custom glow utilities, colors
├── next.config.js # Next.js configuration
├── tsconfig.json # TypeScript configuration
├── package.json # Dependencies & scripts
├── .env.example # Environment variable template
├── .gitignore # Git ignore rules
└── README.md # Project documentation
```
---
## Design System
### Color Palette
**Theme:** Dark mode, blue-dominant, cyber aesthetic
| Name | Hex | Tailwind Name | Usage |
|------|-----|---------------|-------|
| Background | `#050510` | `bg-primary-dark` | Page background |
| Primary Accent | `#0088ff` | `text-primary` / `border-primary` | Main glows, highlights, borders |
| Secondary Accent | `#00ddff` | `text-secondary` | Bright accents, hover states |
| Tertiary Accent | `#6600ff` | `accent-purple` | Subtle contrast, depth |
| Heading Text | `#ffffff` | `text-white` | Headings |
| Body Text | `#8899bb` | `text-muted` | Body text |
| Card Background | `rgba(0, 40, 80, 0.3)` | `bg-card` | Glassmorphism cards |
| Glow Layer | `rgba(0, 136, 255, 0.3)` | `glow-blue` | Box shadow glow |
**Tailwind Color Extension (tailwind.config.ts):**
```typescript
theme: {
extend: {
colors: {
primary: {
DEFAULT: '#0088ff',
dark: '#0066cc',
light: '#00aaff',
},
secondary: {
DEFAULT: '#00ddff',
dark: '#00aacc',
},
accent: {
purple: '#6600ff',
},
}
}
}
```
### Typography
| Element | Font | Weight | Size (mobile → desktop) |
|---------|------|--------|------------------------|
| H1 (Hero) | Space Grotesk | 700 | 3xl → 6xl |
| H2 (Section) | Space Grotesk | 600 | 2xl → 3xl |
| Body | Inter | 400 | base → lg |
| Code/Mono | JetBrains Mono | 400 | (optional) |
**Font loading (layout.tsx):**
```tsx
import { Space_Grotesk, Inter } from 'next/font/google'
const spaceGrotesk = Space_Grotesk({
weight: ['600', '700'],
subsets: ['latin'],
variable: '--font-space-grotesk',
})
const inter = Inter({
weight: ['400', '500'],
subsets: ['latin'],
variable: '--font-inter',
})
```
---
## Visual Effects
### Particle Background
**Implementation:** @tsparticles/react with `tsparticles-slim` preset + custom blue/cyan config.
**Configuration:**
```typescript
// lib/particles-config.ts
export const particlesConfig = {
fullScreen: { enable: true, zIndex: -1 },
particles: {
number: { value: 100, density: { enable: true, value_area: 800 } },
color: { value: ['#0088ff', '#00ddff', '#6600ff'] },
shape: { type: 'circle' },
opacity: { value: 0.5, random: true },
size: { value: { min: 1, max: 3 } },
move: {
enable: true,
speed: 0.5,
direction: 'none',
random: true,
straight: false,
outModes: { default: 'out' },
},
links: {
enable: true,
distance: 150,
color: '#0088ff',
opacity: 0.3,
width: 1,
},
},
interactivity: {
events: {
onHover: { enable: true, mode: 'repulse' },
onClick: { enable: true, mode: 'push' },
},
modes: {
repulse: { distance: 100, duration: 0.4 },
push: { quantity: 4 },
},
},
detectRetina: true,
}
```
**Performance optimizations:**
- Pauses when tab is not visible (browser `visibilitychange` event)
- Uses `requestAnimationFrame` (built into tsparticles)
- Limited to 100 particles for smooth 60fps on most devices
### Glitch Text Effect
**Implementation:** CSS keyframes with pseudo-elements for chromatic aberration
**Component:** `GlitchText.tsx`
```tsx
interface GlitchTextProps {
text: string;
as?: 'h1' | 'h2' | 'h3' | 'span';
className?: string;
intensity?: 'subtle' | 'normal' | 'aggressive'; // controls animation speed
}
```
**CSS Animation (globals.css):**
```css
@keyframes glitch-anim-1 {
0%, 100% { clip-path: inset(40% 0 61% 0); transform: translate(-2px, 2px); }
20% { clip-path: inset(92% 0 1% 0); transform: translate(2px, -2px); }
40% { clip-path: inset(43% 0 1% 0); transform: translate(-1px, 1px); }
60% { clip-path: inset(25% 0 58% 0); transform: translate(1px, -1px); }
80% { clip-path: inset(54% 0 7% 0); transform: translate(0px, 0px); }
}
@keyframes glitch-anim-2 {
0%, 100% { clip-path: inset(65% 0 36% 0); transform: translate(2px, -2px); }
20% { clip-path: inset(79% 0 14% 0); transform: translate(-2px, 2px); }
40% { clip-path: inset(51% 0 68% 0); transform: translate(1px, -1px); }
60% { clip-path: inset(87% 0 13% 0); transform: translate(-1px, 1px); }
80% { clip-path: inset(32% 0 67% 0); transform: translate(0px, 0px); }
}
.glitch {
position: relative;
color: white;
}
.glitch::before,
.glitch::after {
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.glitch::before {
color: #00ddff;
animation: glitch-anim-1 2.5s infinite linear alternate-reverse;
z-index: -1;
}
.glitch::after {
color: #0066cc;
animation: glitch-anim-2 2.5s infinite linear alternate-reverse;
z-index: -2;
}
@media (prefers-reduced-motion: reduce) {
.glitch::before,
.glitch::after {
animation: none;
}
}
```
**Usage:**
```tsx
<GlitchText text="GEEKBRAIN.IO" as="h1" intensity="normal" />
```
**Timing:** 2.5s loop, ~70% stable, 30% glitching
### Glow Effects
**Custom Tailwind utilities (tailwind.config.ts):**
```typescript
plugin: function({ addUtilities }) {
addUtilities({
'.glow-blue': {
boxShadow: `
0 0 5px rgba(0, 136, 255, 0.5),
0 0 10px rgba(0, 136, 255, 0.3),
0 0 15px rgba(0, 136, 255, 0.2)
`,
},
'.glow-cyan': {
boxShadow: `
0 0 5px rgba(0, 221, 255, 0.5),
0 0 10px rgba(0, 221, 255, 0.3)
`,
},
'.text-glow-blue': {
textShadow: `
0 0 5px rgba(0, 136, 255, 0.7),
0 0 10px rgba(0, 136, 255, 0.5)
`,
},
'.animate-pulse-glow': {
animation: 'pulse-glow 2s ease-in-out infinite',
},
})
}
```
**Additional keyframe:**
```css
@keyframes pulse-glow {
0%, 100% { box-shadow: 0 0 5px rgba(0, 136, 255, 0.5); }
50% { box-shadow: 0 0 15px rgba(0, 136, 255, 0.8); }
}
```
**GlowButton component:**
```tsx
interface GlowButtonProps {
children: React.ReactNode;
onClick?: () => void;
href?: string;
variant?: 'primary' | 'secondary' | 'outline';
className?: string;
}
```
### Scroll Animations
**Implementation:** IntersectionObserver API (native, no library needed)
**Utility hook (optional):** `useIntersectionObserver` to trigger fade-in when elements enter viewport
**Animation classes:**
```css
.scroll-reveal {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}
.scroll-reveal.visible {
opacity: 1;
transform: translateY(0);
}
/* Staggered for list items */
.stagger-1 { transition-delay: 0.1s; }
.stagger-2 { transition-delay: 0.2s; }
.stagger-3 { transition-delay: 0.3s; }
```
---
## Components
### Hero
**Content:**
- Headline: `GEEKBRAIN.IO` (GlitchText component, default glitch effect)
- Tagline: "Backing the builders of tomorrow"
- Optional: Subtle animated scroll indicator (down arrow)
**Layout:**
- Full viewport height (`min-h-screen`)
- Centered content, transparent background
- Particles visible behind
- Fade-in animation on page load
**Implementation:**
```tsx
export default function Hero() {
return (
<section className="flex flex-col items-center justify-center min-h-screen relative z-10">
<GlitchText text="GEEKBRAIN.IO" as="h1" intensity="normal" />
<p className="mt-4 text-xl md:text-2xl text-muted font-light">
Backing the builders of tomorrow
</p>
<ScrollIndicator /> {/* Optional */}
</section>
)
}
```
### About
**Content:**
- Heading: "About"
- Body:
> GeekBrain.io is a venture capital fund focused on backing technical founders building transformative technologies. We believe the best companies start with builders who understand the problem they're solving. Our mission is to provide the capital, network, and strategic support these founders need to turn bold ideas into reality.
**Layout:**
- Glassmorphism card: `rgba(0, 40, 80, 0.3)` background with border
- Blue glow border on hover: `border-primary glow-blue`
- Padding: `p-6 md:p-8`
- Fade-in animation on scroll
- Max-width: `max-w-3xl` centered
**Implementation:**
```tsx
export default function About() {
return (
<section className="py-20 px-4 relative z-10">
<div className="max-w-3xl mx-auto">
<h2 className="text-3xl font-bold text-white mb-6 text-center">About</h2>
<div className="bg-card border border-primary rounded-lg p-6 md:p-8 glow-blue scroll-reveal">
<p className="text-muted leading-relaxed">
GeekBrain.io is a venture capital fund focused on backing technical founders...
</p>
</div>
</div>
</section>
)
}
```
### Contact
**Content:**
- Heading: "Connect"
- LinkedIn icon link with glow effect (GlowButton)
- Optional brief text
**Layout:**
- Centered, horizontal arrangement
- Icon: Blue glow on hover, subtle pulse when idle
- Fade-in animation on scroll
**Implementation:**
```tsx
export default function Contact() {
return (
<section className="py-20 px-4 relative z-10">
<div className="max-w-2xl mx-auto text-center">
<h2 className="text-3xl font-bold text-white mb-6">Connect</h2>
<GlowButton
href="https://linkedin.com/company/geekbrainio"
target="_blank"
rel="noopener noreferrer"
aria-label="Connect with GeekBrain.io on LinkedIn"
className="inline-flex items-center gap-2"
>
<LinkedInIcon className="w-6 h-6" />
<span>LinkedIn</span>
</GlowButton>
</div>
</section>
)
}
```
---
## Component Specifications
### GlitchText
**Purpose:** Animated glitch text effect for headings
**Interface:**
```tsx
interface GlitchTextProps {
text: string; // Required: text to display
as?: 'h1' | 'h2' | 'h3' | 'span'; // HTML element, default 'h1'
className?: string; // Additional CSS classes
intensity?: 'subtle' | 'normal' | 'aggressive'; // Animation intensity
}
```
**Implementation details:**
- Uses CSS custom properties to control animation duration based on intensity
- `subtle`: 3s interval (63% stable, 37% glitch)
- `normal`: 2.5s interval (70% stable, 30% glitch) ← **default**
- `aggressive`: 1.5s interval (50% stable, 50% glitch)
- Respects `prefers-reduced-motion` by disabling animation
- Attributes `data-text` for CSS pseudo-element content
### GlowButton
**Purpose:** Interactive button/link with glowing hover effect
**Interface:**
```tsx
interface GlowButtonProps {
children: React.ReactNode;
onClick?: () => void;
href?: string; // If provided, renders as <a>
variant?: 'primary' | 'secondary' | 'outline';
className?: string;
[rest: React.HTMLAttributes<HTMLButtonElement | HTMLAnchorElement>]: any;
}
```
**Variants:**
- `primary`: Filled background (`bg-primary`), white text, blue glow on hover
- `secondary`: Transparent background, cyan border/text, cyan glow on hover
- `outline`: Transparent, primary border, blue glow on hover ← **default**
**Styling:**
- Padding: `px-6 py-3` (adjustable via className)
- Rounded: `rounded-lg`
- Transition: `transition-all duration-300 ease-out`
- Glow effect: `hover:glow-blue` (or `hover:glow-cyan` for secondary)
- Focus ring: `focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2`
### ParticleBackground
**Purpose:** Full-screen particle canvas behind all content
**Interface:**
```tsx
interface ParticleBackgroundProps {
config?: ParticlesConfig; // Optional override of default config
className?: string;
}
```
**Behavior:**
- Renders as fixed, full-viewport canvas with `z-index: -1`
- Uses `Particles` component from @tsparticles/react
- Loads config from `lib/particles-config.ts` by default
- Pauses animation when tab is not visible
- Automatically handles resize
**Implementation:**
```tsx
'use client'
import { Particles } from '@tsparticles/react'
import { particlesConfig } from '@/lib/particles-config'
export default function ParticleBackground({ className }: { className?: string }) {
return (
<Particles
id="tsparticles"
className={className}
options={particlesConfig}
/>
)
}
```
---
## Page Layout
**Structure:**
```
┌─────────────────────────────────────────────┐
│ [ParticleBackground - fixed, z-index: -1] │
│ ┌─────────────────────────────────────┐ │
│ │ HERO (100vh, flex center) │ │
│ │ ┌─────────────────────────────┐ │ │
│ │ │ GEEKBRAIN.IO (glitch) │ │ │
│ │ │ "Backing the builders... │ │ │
│ │ └─────────────────────────────┘ │ │
│ │ ↓ (optional) │ │
│ └─────────────────────────────────────┘ │
│ ┌─────────────────────────────────────┐ │
│ │ ABOUT (py-20 px-4) │ │
│ │ ┌─────────────────────────────┐ │ │
│ │ │ [Glass card, blue glow] │ │ │
│ │ │ About text... │ │ │
│ │ └─────────────────────────────┘ │ │
│ └─────────────────────────────────────┘ │
│ ┌─────────────────────────────────────┐ │
│ │ CONTACT (py-20 px-4, center) │ │
│ │ ┌─────────────────────────────┐ │ │
│ │ │ [GlowButton - LinkedIn] │ │ │
│ │ └─────────────────────────────┘ │ │
│ └─────────────────────────────────────┘ │
│ [Footer - optional (copyright)] │
└─────────────────────────────────────────────┘
```
**Sizing:**
- Mobile-first responsive design
- Padding: `px-4` on mobile, larger sections use container `max-w-6xl mx-auto`
- Text sizes scale with Tailwind's responsive prefixes (`sm:`, `md:`, `lg:`)
---
## Accessibility Requirements
### Mandatory Standards
- **WCAG 2.1 AA** compliance minimum
- **Semantic HTML** - proper heading hierarchy (h1 → h2 → h3)
- **Keyboard navigation** - all interactive elements focusable with visible focus states
- **Screen reader** - ARIA labels where needed, meaningful link text
- **Color contrast** - minimum 4.5:1 for normal text, 3:1 for large text
### Implementation Checklist
- [ ] `GlitchText` respects `prefers-reduced-motion` (disables animation)
- [ ] All animations can be reduced via `@media (prefers-reduced-motion: reduce)`
- [ ] Scroll-reveal animations do not trap focus
- [ ] Links have descriptive text (not just "click here")
- [ ] Social links include `aria-label` (e.g., "GeekBrain.io on LinkedIn")
- [ ] Logo image has appropriate `alt` text (if decorative, use `alt=""`)
- [ ] Focus visible states with sufficient contrast (use `focus-visible` classes)
- [ ] Heading hierarchy: H1 (site title) → H2 (section titles) → no skipping
- [ ] Color contrast tests: text on dark background meets AA standards
### Testing
- Test with VoiceOver (macOS) or NVDA (Windows)
- Navigate entirely with keyboard (Tab, Enter, Arrow keys)
- Use browser DevTools Lighthouse for accessibility audit
---
## Performance Targets
### Lighthouse Goals
- **Performance**: >90
- **Accessibility**: >90
- **Best Practices**: >90
- **SEO**: >100 (static site with proper meta tags)
### Bundle Size
- Total JavaScript < 200KB (gzipped)
- tsparticles-slim: ~30KB (already lightweight)
- No heavy image assets (only logo)
### Optimizations Applied
- Static generation (no SSR)
- Fonts loaded via `next/font` (no layout shift)
- Images optimized with Next.js Image component (if any)
- Particles pause when tab hidden
- CSS animations use GPU-accelerated properties (transform, opacity)
- Code splitting automatic via Next.js
---
## SEO & Metadata
**layout.tsx head elements:**
```tsx
export const metadata: Metadata = {
title: 'GeekBrain.io - Venture Capital for Technical Founders',
description: 'GeekBrain.io is a venture capital fund backing technical founders building transformative technologies.',
keywords: ['venture capital', 'VC fund', 'technical founders', 'startup funding', 'GeekBrain'],
openGraph: {
title: 'GeekBrain.io',
description: 'Backing the builders of tomorrow',
type: 'website',
locale: 'en_US',
siteName: 'GeekBrain.io',
},
twitter: {
card: 'summary_large_image',
title: 'GeekBrain.io',
description: 'Backing the builders of tomorrow',
},
}
```
**Favicon/OG Image:**
- Place `favicon.ico` in `/public`
- Create Open Graph image `og-image.jpg` (1200×630px) with logo and tagline
- Place in `/public/assets/images/`
---
## Responsive Breakpoints
Based on Tailwind defaults:
| Breakpoint | Width | Usage |
|------------|-------|-------|
| mobile (default) | < 640px | Stack layout, smaller text (text-base, h1: text-3xl) |
| sm | 640px+ | Tablet portrait |
| md | 768px+ | Tablet landscape, smaller laptop |
| lg | 1024px+ | Standard laptop/desktop |
| xl | 1280px+ | Large desktop screens |
**Typography scaling:**
- H1: `text-3xl sm:text-4xl md:text-5xl lg:text-6xl`
- Body: `text-base md:text-lg`
- Padding: `p-6 md:p-8 lg:p-12`
**Container strategy:**
```tsx
<div className="max-w-6xl mx-auto w-full px-4 sm:px-6 lg:px-8">
{/* Content */}
</div>
```
---
## Next.js Configuration
**next.config.js:**
```javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
// Optional: output 'standalone' for Docker deployment
// output: 'standalone',
}
module.exports = nextConfig
```
**No special configuration needed** for this static site. Default settings suffice.
---
## TypeScript Configuration
**tsconfig.json (use Next.js default):**
```json
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
```
---
## Dependencies
**package.json:**
```json
{
"name": "geekbrain-site",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "^14.2.5",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"@tsparticles/react": "^3.0.0",
"@tsparticles/slim": "^3.0.0"
},
"devDependencies": {
"typescript": "^5.5.3",
"@types/node": "^20.14.10",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"tailwindcss": "^3.4.7",
"postcss": "^8.4.40",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
"eslint-config-next": "^14.2.5"
}
}
```
---
## Environment Variables
**Not required** for this static site. If any APIs are added later, use `.env.local`:
```
# Example (not used currently)
# NEXT_PUBLIC_ANALYTICS_ID=...
```
---
## Setup Instructions (for developer)
1. **Initialize Next.js project:**
```bash
npx create-next-app@latest geekbrain-site --typescript --tailwind --eslint --app --src-dir=false --import-alias="@/*"
cd geekbrain-site
```
2. **Install additional dependencies:**
```bash
npm install @tsparticles/react @tsparticles/slim
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```
3. **Configure Tailwind** (use config from this spec)
4. **Create file structure** as shown above
5. **Add fonts** via `next/font` in `layout.tsx`
6. **Add logo** to `public/assets/images/Geekbrain-io.png`
7. **Run dev server:**
```bash
npm run dev
```
---
## Deployment
**Recommended:** Vercel (zero-config for Next.js)
**Alternative:** Netlify
**Steps:**
1. Push code to GitHub repository
2. Import project in Vercel
3. Build command: `npm run build`
4. Output directory: `.next` (automatically detected)
5. Environment: Node.js 18+
6. Deploy
**Domain:** Configure DNS for geekbrain.io to point to Vercel
---
## Future Expansion
The architecture supports easy additions:
1. **Portfolio page** (`app/portfolio/page.tsx`) - showcase investments
2. **Team page** (`app/team/page.tsx`) - team bios
3. **Incubation section** - explain services for incubated startups
4. **Contact form** - would require API route (`app/api/contact/route.ts`) + email service
5. **Blog/News** - `app/blog/[...slug]/page.tsx` with MDX or CMS
6. **Additional social links** - Twitter/X, GitHub, etc.
7. **Theme toggle** - light/dark mode (currently dark-only)
---
## Implementation Checklist
### Phase 1: Foundation
- [x] Project initialized with Next.js 14 + TypeScript + Tailwind
- [x ] Dependencies installed (tsparticles)
- [ ] `tailwind.config.ts` configured with custom colors, glow utilities
- [ ] `next.config.js` created
- [ ] `lib/particles-config.ts` written
- [ ] `app/globals.css` includes Tailwind directives + custom glitch keyframes
### Phase 2: Components
- [ ] `components/GlitchText.tsx` implemented + tests
- [ ] `components/GlowButton.tsx` implemented + tests
- [ ] `components/ParticleBackground.tsx` implemented
- [ ] `components/Hero.tsx` implemented
- [ ] `components/About.tsx` implemented
- [ ] `components/Contact.tsx` implemented
### Phase 3: Pages & Layout
- [ ] `app/layout.tsx` - font setup, metadata, dark background
- [ ] `app/page.tsx` - compose all components
- [ ] Logo added to `public/assets/images/`
### Phase 4: Polish & Testing
- [ ] Accessibility audit (Lighthouse)
- [ ] Performance testing (Lighthouse >90)
- [ ] Cross-browser testing (Chrome, Firefox, Safari)
- [ ] Mobile responsiveness testing
- [ ] Reduced motion testing
- [ ] Keyboard navigation test
### Phase 5: Deployment Prep
- [ ] Environment variables documentation
- [ ] Favicon added
- [ ] Open Graph image created
- [ ] robots.txt added
- [ ] sitemap.xml (optional)
---
## Notes for Implementer
1. **All components are client components** only when necessary (`ParticleBackground`, `GlitchText` with animations). Use `'use client'` directive only in those files. Layout and page can remain server components.
2. **Animation performance:** Use `transform` and `opacity` for 60fps. Avoid animating `top`, `left`, `width`, `height`.
3. **Scroll reveal:** Can be implemented in page root with `IntersectionObserver` hook that adds `.visible` class to elements with `.scroll-reveal`.
4. **Glassmorphism:** Uses `backdrop-filter: blur()` if desired. Test browser support. Fallback to semi-transparent background only.
5. **Logo usage:** Use Next.js `Image` component for optimization:
```tsx
import Image from 'next/image'
<Image src="/assets/images/Geekbrain-io.png" alt="GeekBrain.io" width={200} height={60} />
```
6. **Code quality:** Follow TypeScript best practices, proper error boundaries if needed (no error boundaries needed for this static site).
7. **Git:** Commit frequently with clear messages. Create feature branches if needed.
---
## Revision History
| Date | Version | Changes |
|------|---------|---------|
| 2026-03-21 | 1.0 | Consolidated spec created, ready for implementation |
---
**Ready to build!** 🚀