feat: youtube preview
This commit is contained in:
168
specs/002-youtube-design-preview/research.md
Normal file
168
specs/002-youtube-design-preview/research.md
Normal file
@@ -0,0 +1,168 @@
|
||||
# Research: YouTube Design Preview Replica
|
||||
|
||||
**Date**: 2026-01-29
|
||||
**Method**: Playwright MCP automated extraction from live YouTube (1920x1080)
|
||||
|
||||
## YouTube CSS Design Tokens (January 2026)
|
||||
|
||||
### Typography
|
||||
|
||||
| Element | Font Family | Size | Weight | Line Height | Color (Light) | Color (Dark) |
|
||||
|---------|-------------|------|--------|-------------|---------------|--------------|
|
||||
| Title (Desktop Grid) | Roboto, Arial, sans-serif | 16px | 500 | 22px | #0f0f0f | #f1f1f1 |
|
||||
| Title (Search) | Roboto, Arial, sans-serif | 18px | 400 | 26px | #0f0f0f | #f1f1f1 |
|
||||
| Title (Sidebar) | Roboto, Arial, sans-serif | 14px | 500 | 20px | #0f0f0f | #f1f1f1 |
|
||||
| Channel Name | Roboto, Arial, sans-serif | 12px | 400 | 18px | #606060 | #aaaaaa |
|
||||
| Metadata (views, time) | Roboto, Arial, sans-serif | 12px | 400 | 18px | #606060 | #aaaaaa |
|
||||
| Duration Badge | Roboto, Arial, sans-serif | 12px | 500 | normal | #ffffff | #ffffff |
|
||||
|
||||
### Thumbnail Dimensions
|
||||
|
||||
| View Mode | Width | Height | Aspect Ratio | Border Radius |
|
||||
|-----------|-------|--------|--------------|---------------|
|
||||
| Desktop Grid (Home) | 360px | 202px | 16:9 (1.778) | 12px |
|
||||
| Search Results | 360px | 202px | 16:9 (1.778) | 12px |
|
||||
| Sidebar (Related) | 168px | 94px | 16:9 (1.787) | 8px |
|
||||
| Mobile (Full Width) | 100% | auto | 16:9 | 0px (edge-to-edge) |
|
||||
|
||||
### Avatar Dimensions
|
||||
|
||||
| View Mode | Size | Shape |
|
||||
|-----------|------|-------|
|
||||
| Desktop Grid | 36x36px | Circle |
|
||||
| Search Results | 36x36px | Circle |
|
||||
| Sidebar | N/A (no avatar) | - |
|
||||
| Mobile | 36x36px | Circle |
|
||||
|
||||
### Duration Badge Styling
|
||||
|
||||
```css
|
||||
.duration-badge {
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
font-family: Roboto, Arial, sans-serif;
|
||||
padding: 3px 4px;
|
||||
border-radius: 4px;
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
right: 4px;
|
||||
}
|
||||
```
|
||||
|
||||
### Color Palette
|
||||
|
||||
#### Light Mode
|
||||
```css
|
||||
:root {
|
||||
--yt-bg: #ffffff;
|
||||
--yt-surface: #ffffff;
|
||||
--yt-title: #0f0f0f;
|
||||
--yt-meta: #606060;
|
||||
--yt-icon: #606060;
|
||||
--yt-border: #e5e5e5;
|
||||
--yt-hover: rgba(0, 0, 0, 0.05);
|
||||
--yt-chip-bg: #f2f2f2;
|
||||
--yt-chip-active-bg: #0f0f0f;
|
||||
--yt-chip-active-text: #ffffff;
|
||||
--yt-blue: #065fd4;
|
||||
--yt-red: #ff0000;
|
||||
}
|
||||
```
|
||||
|
||||
#### Dark Mode
|
||||
```css
|
||||
.dark {
|
||||
--yt-bg: #0f0f0f;
|
||||
--yt-surface: #0f0f0f;
|
||||
--yt-title: #f1f1f1;
|
||||
--yt-meta: #aaaaaa;
|
||||
--yt-icon: #aaaaaa;
|
||||
--yt-border: #3f3f3f;
|
||||
--yt-hover: rgba(255, 255, 255, 0.1);
|
||||
--yt-chip-bg: #272727;
|
||||
--yt-chip-active-bg: #f1f1f1;
|
||||
--yt-chip-active-text: #0f0f0f;
|
||||
--yt-blue: #3ea6ff;
|
||||
--yt-red: #ff0000;
|
||||
}
|
||||
```
|
||||
|
||||
### Spacing & Layout
|
||||
|
||||
| Property | Desktop Grid | Search | Sidebar |
|
||||
|----------|--------------|--------|---------|
|
||||
| Card Gap (horizontal) | 16px | N/A | N/A |
|
||||
| Card Gap (vertical) | 40px | 16px | 8px |
|
||||
| Thumbnail-to-metadata gap | 12px | 12px | 8px |
|
||||
| Avatar-to-text gap | 12px | 12px | N/A |
|
||||
| Title max lines | 2 | 2 | 2 |
|
||||
| Channel name max lines | 1 | 1 | 1 |
|
||||
|
||||
### Hover States (Desktop)
|
||||
|
||||
```css
|
||||
.video-card:hover .thumbnail {
|
||||
/* YouTube shows preview animation on hover after delay */
|
||||
transform: none; /* No scale transform */
|
||||
}
|
||||
|
||||
.video-card:hover .watch-later-button,
|
||||
.video-card:hover .add-to-queue-button {
|
||||
opacity: 1; /* Buttons appear on hover */
|
||||
}
|
||||
|
||||
.channel-name:hover {
|
||||
color: var(--yt-title); /* Slightly darker on hover */
|
||||
}
|
||||
```
|
||||
|
||||
### Responsive Breakpoints
|
||||
|
||||
| Breakpoint | Grid Columns | Thumbnail Width |
|
||||
|------------|--------------|-----------------|
|
||||
| > 2136px | 6 columns | ~356px |
|
||||
| 1712px - 2136px | 5 columns | ~342px |
|
||||
| 1288px - 1712px | 4 columns | ~320px |
|
||||
| 888px - 1288px | 3 columns | ~290px |
|
||||
| 512px - 888px | 2 columns | ~280px |
|
||||
| < 512px | 1 column (mobile) | 100% |
|
||||
|
||||
## Decisions
|
||||
|
||||
### 1. CSS Variable Naming
|
||||
**Decision**: Use `--yt-*` prefix for YouTube-specific variables
|
||||
**Rationale**: Already implemented in current codebase; keeps YouTube styles isolated from app design system
|
||||
**Alternatives**: Using Tailwind theme tokens directly - rejected because we need YouTube-specific colors separate from app theme
|
||||
|
||||
### 2. Component Structure
|
||||
**Decision**: Single `YouTubeVideoCard` component with `variant` prop for mode switching
|
||||
**Rationale**: Existing component already supports variants; minimizes code duplication
|
||||
**Alternatives**: Separate components per mode - rejected due to shared logic (formatting, truncation)
|
||||
|
||||
### 3. Visual Testing Strategy
|
||||
**Decision**: Playwright screenshot comparison with 98% match threshold
|
||||
**Rationale**: Allows for minor anti-aliasing differences while catching layout regressions
|
||||
**Alternatives**: Pixel-perfect 100% match - too brittle; structural testing only - doesn't catch visual issues
|
||||
|
||||
### 4. Reference Screenshot Updates
|
||||
**Decision**: Weekly automated capture via Playwright MCP
|
||||
**Rationale**: Per clarification; balances freshness with stability
|
||||
**Alternatives**: Manual updates - inconsistent; daily updates - too frequent, unstable baselines
|
||||
|
||||
### 5. Local Storage Schema
|
||||
**Decision**: Store serialized preview state with thumbnail as base64
|
||||
**Rationale**: Self-contained, no external file dependencies
|
||||
**Alternatives**: IndexedDB with blob storage - more complex, minimal benefit for single-user tool
|
||||
|
||||
## Reference Screenshots Captured
|
||||
|
||||
- `youtube-desktop-homepage-*.png` - Homepage grid layout
|
||||
- `youtube-search-fullhd-*.png` - Search results at 1920x1080
|
||||
- `youtube-video-with-sidebar-*.png` - Watch page with related videos
|
||||
- `youtube-watch-related-*.png` - Sidebar compact video cards
|
||||
- `youtube-trending-grid-*.png` - Trending page grid
|
||||
- `youtube-dark-mode-*.png` - Dark theme reference
|
||||
|
||||
All screenshots stored in: `specs/002-youtube-design-preview/reference/`
|
||||
Reference in New Issue
Block a user