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

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