Files
2026-01-29 21:05:41 -03:00

169 lines
5.5 KiB
Markdown

# 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/`