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