Files

342 lines
7.7 KiB
Markdown
Raw Permalink Normal View History

# Portfolio Design System
## Color Palette
### Primary Colors
- **Blue**: `blue-600` (primary actions, links, accents)
- **Purple**: `purple-600` (gradients, secondary accents)
- **Green**: `green-500` (live status, success)
### Neutral Colors
- **Light Mode**:
- Background: `white`, `gray-50`
- Text Primary: `gray-900`
- Text Secondary: `gray-600`, `gray-700`
- Borders: `gray-200`, `gray-300`
- **Dark Mode**:
- Background: `gray-950`, `gray-900`
- Text Primary: `white`
- Text Secondary: `gray-400`, `gray-300`
- Borders: `gray-800`, `gray-700`
### Status Colors
- Live: `green-100/900` bg, `green-800/200` text
- Building: `blue-100/900` bg, `blue-800/200` text
- Planning: `gray-100/800` bg, `gray-800/200` text
### Timeline Colors (gradients)
- riotpiao.com: `from-green-500 to-green-600`
- RBC: `from-red-500 to-red-600`
- AWS: `from-orange-500 to-orange-600`
- Titus: `from-cyan-500 to-cyan-600`
- NAV Canada: `from-blue-500 to-blue-600`
---
## Typography
### Font Sizes
- Hero Title: `text-4xl md:text-5xl font-bold`
- Section Title: `text-4xl font-bold`
- Card Title: `text-2xl font-bold` or `text-xl font-bold`
- Subtitle: `text-xl font-medium` or `text-lg`
- Body: `text-sm` or `text-base`
- Caption: `text-xs`
- Mono/Code: `font-mono text-xs`
### Font Weights
- Bold: `font-bold` (titles, emphasis)
- Semibold: `font-semibold` (subtitles, labels)
- Medium: `font-medium` (secondary text)
---
## Spacing
### Layout
- Max Width: `max-w-6xl` (main container), `max-w-4xl` (content), `max-w-3xl` (cards), `max-w-5xl` (hero image)
- Padding: `px-6` (horizontal), `py-20` or `py-24` (section vertical)
- Gap: `gap-8` (cards), `gap-6` (nav items), `gap-4` (buttons), `gap-2` (tags)
### Component Spacing
- Section margin bottom: `mb-16`
- Card padding: `p-6`
- Button padding: `px-8 py-3` (large), `px-4 py-2` (medium), `px-3 py-1` (small)
---
## Components
### Buttons
**Primary Button**
```jsx
className="bg-blue-600 hover:bg-blue-700 text-white px-8 py-3 rounded-lg font-semibold transition"
```
**Secondary/Outline Button**
```jsx
className="border-2 border-gray-300 dark:border-gray-600 text-gray-900 dark:text-white hover:bg-gray-100 dark:hover:bg-gray-800 px-4 py-2 rounded-lg font-semibold transition"
```
**Language Toggle**
```jsx
className="px-3 py-1 text-sm font-semibold rounded border border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-800"
```
**Icon Button**
```jsx
className="p-2 hover:bg-gray-100 dark:hover:bg-gray-800 rounded"
```
### Cards
**Standard Card**
```jsx
className="bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-800 p-6 hover:shadow-lg transition-shadow"
```
**Project Showcase Card**
```jsx
className="bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-800 overflow-hidden hover:shadow-lg transition-shadow"
```
### Tags/Pills
**Skill Tag**
```jsx
className="text-xs px-3 py-1 rounded-full bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300"
```
**Status Badge**
```jsx
// Live
className="px-3 py-1 rounded-full text-xs font-semibold bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200"
// Building
className="px-3 py-1 rounded-full text-xs font-semibold bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200"
```
### Dropdowns
**Dropdown Container**
```jsx
className="absolute right-0 mt-2 w-64 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-lg shadow-lg p-4 space-y-3"
```
### Modals
**Modal Overlay**
```jsx
className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4"
```
**Modal Content**
```jsx
className="bg-white dark:bg-gray-900 rounded-lg shadow-2xl max-w-2xl w-full max-h-96 overflow-y-auto"
```
**Modal Header (Gradient)**
```jsx
className="sticky top-0 bg-gradient-to-r from-blue-600 to-purple-600 px-6 py-6 flex justify-between items-center"
```
---
## Animations (Framer Motion)
### Fade In Up
```jsx
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 0.2 }}
```
### Scale In
```jsx
initial={{ scale: 0, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ duration: 0.8, delay: 0.2 }}
```
### Stagger Children
```jsx
variants={{
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: { staggerChildren: 0.15 },
},
}}
```
### Role Text Rotation
```jsx
initial={{ opacity: 0, y: 20, scale: 0.95 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
exit={{ opacity: 0, y: -20, scale: 0.95 }}
transition={{ duration: 0.6, ease: 'easeInOut' }}
```
### Background Pulse
```jsx
animate={{
scale: [1, 1.15, 1],
opacity: [0.25, 0.4, 0.25],
}}
transition={{
duration: 6,
repeat: Infinity,
ease: 'easeInOut',
}}
```
---
## Gradients
### Hero Background
```jsx
className="bg-gradient-to-br from-blue-50 to-purple-50 dark:from-gray-950 dark:to-gray-900"
```
### Timeline Line
```jsx
className="bg-gradient-to-b from-blue-500 via-purple-500 to-green-500"
```
### Stat Highlight
```jsx
className="bg-gradient-to-r from-blue-50 to-purple-50 dark:from-gray-800 dark:to-gray-800"
```
### Modal Header
```jsx
className="bg-gradient-to-r from-blue-600 to-purple-600"
```
---
## Z-Index Layers
- `z-0`: Background images
- `z-10`: Content overlays (avatar, text)
- `z-20`: Avatar + rotating text group
- `z-40`: Terminal button
- `z-50`: Header, Modals
---
## Responsive Breakpoints
- Mobile: Default (no prefix)
- Tablet/Desktop: `md:` (768px+)
- Large Desktop: `lg:` (1024px+)
### Common Patterns
```jsx
// Hide on mobile, show on desktop
className="hidden md:flex"
// Show on mobile, hide on desktop
className="md:hidden"
// Responsive grid
className="grid grid-cols-1 md:grid-cols-2 gap-8"
// Responsive text
className="text-4xl md:text-5xl"
// Responsive padding
className="px-4 md:px-6"
```
---
## Icons (Lucide React)
### Sizes
- Navigation: `size={20}`
- Buttons: `size={16}`
- Cards: `size={24}`
- Hero: `size={32}`
- Close: `size={24}`
### Common Icons
- `Menu`, `X` - Mobile nav
- `Moon`, `Sun` - Theme toggle
- `ExternalLink` - External links
- `Network`, `Shield`, `Code`, `Sparkles`, `Zap`, `Cpu` - Role icons
- `GitBranch`, `Database`, `MessageSquare`, `Layers`, `BarChart3` - Feature icons
---
## Internationalization (i18n)
### Structure
```
lib/
translations.json # All translations
LanguageContext.tsx # React context provider
```
### Usage
```jsx
import { useLanguage } from '@/lib/LanguageContext'
const { lang, setLang, t } = useLanguage()
// Access translations
<h1>{t.hero.title}</h1>
```
### Language Toggle Button
Shows opposite language:
- When `en`: Shows `中文`
- When `zh`: Shows `EN`
---
## File Structure
```
components/
Header.tsx # Navigation, dropdowns, language toggle
HeroBlobFlow.tsx # Hero with avatar, rotating roles
ExperienceTimeline.tsx # Work history timeline
ProjectShowcase.tsx # Project cards
InteractiveTerminal.tsx # Cmd+K terminal
TypewriterText.tsx # Typewriter effect
lib/
TerminalContext.tsx # Terminal open/close state
LanguageContext.tsx # Language state + translations
translations.json # EN/ZH translations
app/
page.tsx # Main page
layout.tsx # Root layout with providers
globals.css # Tailwind + global styles
public/
avatar.jpeg # Profile photo
hire-me.png # Dark mode hero background
hire-me-light.png # Light mode hero background
```
---
## Dark Mode
Implemented via Tailwind's `dark:` prefix. Toggle class on `<html>` element.
```jsx
// Toggle
document.documentElement.classList.toggle('dark')
// Check
document.documentElement.classList.contains('dark')
```
Observe changes via MutationObserver for components that need to react to theme changes (e.g., background image swap).