5.5 KiB
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
.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
: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
.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)
.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 layoutyoutube-search-fullhd-*.png- Search results at 1920x1080youtube-video-with-sidebar-*.png- Watch page with related videosyoutube-watch-related-*.png- Sidebar compact video cardsyoutube-trending-grid-*.png- Trending page gridyoutube-dark-mode-*.png- Dark theme reference
All screenshots stored in: specs/002-youtube-design-preview/reference/