# YouTube Video Player

> YouTube video player for React and shadcn/ui with a custom thumbnail and play button that expands into an animated modal.

Source: https://www.cult-ui.com/docs/components/youtube-video-player

## Example

```tsx title="youtube-video-player-demo.tsx"
"use client"

import { YouTubePlayer } from "@/components/ui/youtube-video-player"

export default function YouTubeVideoPlayerDemo() {
  return (
    <div className="space-y-12 p-8">
      <div className="space-y-4">
        <h1 className="text-3xl font-bold">YouTube Video Player Examples</h1>
        <p className="text-muted-foreground">
          A collection of YouTube video player examples showcasing different
          configurations and styling options.
        </p>
      </div>

      {/* Custom Thumbnail */}
      <section className="space-y-4">
        <div>
          <h2 className="mb-2 text-2xl font-semibold">Custom Thumbnail</h2>
          <p className="text-muted-foreground">
            Player with a custom thumbnail image instead of the default YouTube
            thumbnail.
          </p>
        </div>
        <div className="max-w-2xl">
          <YouTubePlayer
            videoId="jNQXAC9IVRw"
            title="Me at the zoo - First YouTube Video"
            customThumbnail="https://images.unsplash.com/photo-1611162617474-5b21e879e113?w=800&h=450&fit=crop&crop=center"
          />
        </div>
      </section>

      {/* Custom Styling */}
      <section className="space-y-4">
        <div>
          <h2 className="mb-2 text-2xl font-semibold">Custom Styling</h2>
          <p className="text-muted-foreground">
            Player with custom styling classes for different elements.
          </p>
        </div>
        <div className="max-w-2xl">
          <YouTubePlayer
            videoId="kJQP7kiw5Fk"
            title="Despacito - Luis Fonsi ft. Daddy Yankee"
            containerClassName="border-2 border-primary rounded-2xl shadow-2xl"
            thumbnailImageClassName="opacity-90 saturate-150"
            playButtonClassName="bg-primary/20 border-border/20 hover:bg-primary/30"
            playIconClassName="text-secondary fill-secondary"
            titleClassName="text-secondary font-bold"
            controlsClassName="right-4 top-4"
            expandButtonClassName="bg-secondary/20 hover:bg-secondary/30 border-secondary text-secondary"
          />
        </div>
      </section>

      {/* Multiple Players Grid */}
      <section className="space-y-4">
        <div>
          <h2 className="mb-2 text-2xl font-semibold">Multiple Players</h2>
          <p className="text-muted-foreground">
            A grid of multiple video players with different content.
          </p>
        </div>
        <div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
          <YouTubePlayer
            videoId="9bZkp7q19f0"
            title="PSY - GANGNAM STYLE"
            className="w-full"
          />
          <YouTubePlayer
            videoId="fJ9rUzIMcZQ"
            title="Queen – Bohemian Rhapsody"
            className="w-full"
          />
          <YouTubePlayer
            videoId="L_jWHffIx5E"
            title="Smash Mouth - All Star"
            className="w-full"
          />
          <YouTubePlayer
            videoId="hTWKbfoikeg"
            title="Nirvana - Smells Like Teen Spirit"
            className="w-full"
          />
          <YouTubePlayer
            videoId="djV11Xbc914"
            title="a-ha - Take On Me"
            className="w-full"
          />
          <YouTubePlayer
            videoId="ZbZSe6N_BXs"
            title="Happy - Pharrell Williams"
            className="w-full"
          />
        </div>
      </section>

      {/* Different Aspect Ratios */}
      <section className="space-y-4">
        <div>
          <h2 className="mb-2 text-2xl font-semibold">Different Sizes</h2>
          <p className="text-muted-foreground">
            Players in different container sizes to show responsive behavior.
          </p>
        </div>
        <div className="space-y-8">
          {/* Small */}
          <div>
            <h3 className="mb-3 text-lg font-medium">Small (300px)</h3>
            <div className="w-[300px]">
              <YouTubePlayer
                videoId="2yJgwwDcgV8"
                title="Nyan Cat [original]"
              />
            </div>
          </div>

          {/* Medium */}
          <div>
            <h3 className="mb-3 text-lg font-medium">Medium (500px)</h3>
            <div className="w-[500px]">
              <YouTubePlayer videoId="oHg5SJYRHA0" title="RickRoll'D" />
            </div>
          </div>

          {/* Large */}
          <div>
            <h3 className="mb-3 text-lg font-medium">Large (800px)</h3>
            <div className="w-[800px]">
              <YouTubePlayer videoId="y6120QOlsfU" title="Darude - Sandstorm" />
            </div>
          </div>
        </div>
      </section>

      {/* URL Formats */}
      <section className="space-y-4">
        <div>
          <h2 className="mb-2 text-2xl font-semibold">Different URL Formats</h2>
          <p className="text-muted-foreground">
            The player can handle different YouTube URL formats automatically.
          </p>
        </div>
        <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
          {/* Regular video ID */}
          <div>
            <h3 className="mb-2 text-sm font-medium">
              Video ID: "dQw4w9WgXcQ"
            </h3>
            <YouTubePlayer videoId="dQw4w9WgXcQ" title="Using Video ID" />
          </div>

          {/* Full YouTube URL */}
          <div>
            <h3 className="mb-2 text-sm font-medium">
              Full URL: "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
            </h3>
            <YouTubePlayer
              videoId="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
              title="Using Full YouTube URL"
            />
          </div>

          {/* Short URL */}
          <div>
            <h3 className="mb-2 text-sm font-medium">
              Short URL: "https://youtu.be/dQw4w9WgXcQ"
            </h3>
            <YouTubePlayer
              videoId="https://youtu.be/dQw4w9WgXcQ"
              title="Using Short YouTube URL"
            />
          </div>
        </div>
      </section>

      {/* Feature Highlights */}
      <section className="space-y-4">
        <div>
          <h2 className="mb-2 text-2xl font-semibold">Features</h2>
          <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
            <div className="space-y-2">
              <h3 className="text-lg font-medium">✨ Key Features</h3>
              <ul className="text-muted-foreground space-y-1 text-sm">
                <li>• Expandable full-screen mode</li>
                <li>• Custom thumbnails support</li>
                <li>• Smooth animations with Framer Motion</li>
                <li>• Keyboard shortcuts (ESC to close)</li>
                <li>• Responsive design</li>
                <li>• Accessible controls</li>
                <li>• Multiple URL format support</li>
              </ul>
            </div>
            <div className="space-y-2">
              <h3 className="text-lg font-medium">🎨 Customization</h3>
              <ul className="text-muted-foreground space-y-1 text-sm">
                <li>• Fully customizable styling</li>
                <li>• Custom play button designs</li>
                <li>• Thumbnail overlay effects</li>
                <li>• Control button positioning</li>
                <li>• Container and backdrop styling</li>
                <li>• Title and text customization</li>
              </ul>
            </div>
          </div>
        </div>
      </section>
    </div>
  )
}
```

YouTube Video Player is a React video component for shadcn/ui, animated with Motion. Use it for product demos, tutorials, or video testimonials on landing pages.

## Installation

### CLI

```bash
npx shadcn@latest add @cult-ui/youtube-video-player
```

### Manual

**Install the required dependencies:**

```bash
npm install framer-motion lucide-react
```

**Copy and paste the following code into your project.**

```tsx title="youtube-video-player.tsx"
"use client"

import { useEffect, useState } from "react"
import { Maximize2, Minimize2, Play } from "lucide-react"
import { AnimatePresence, motion } from "motion/react"

import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"

interface YouTubePlayerProps {
  videoId: string
  title?: string
  defaultExpanded?: boolean
  customThumbnail?: string

  // Container & Layout
  className?: string
  containerClassName?: string
  expandedClassName?: string

  // Thumbnail & Media
  thumbnailClassName?: string
  thumbnailImageClassName?: string

  // Play Button
  playButtonClassName?: string
  playIconClassName?: string

  // Title
  titleClassName?: string

  // Controls
  controlsClassName?: string
  expandButtonClassName?: string

  // Backdrop
  backdropClassName?: string

  // Player
  playerClassName?: string
}

export function YouTubePlayer({
  videoId,
  title,
  defaultExpanded = false,
  customThumbnail,

  // Styling props
  className,
  containerClassName,
  expandedClassName,
  thumbnailClassName,
  thumbnailImageClassName,
  playButtonClassName,
  playIconClassName,
  titleClassName,
  controlsClassName,
  expandButtonClassName,
  backdropClassName,
  playerClassName,
}: YouTubePlayerProps) {
  const [expanded, setExpanded] = useState(defaultExpanded)
  const [playing, setPlaying] = useState(false)
  const [isHovered, setIsHovered] = useState(false)

  // Extract video ID from full URL if needed
  const extractVideoId = (id: string) => {
    if (id.includes("youtube.com") || id.includes("youtu.be")) {
      try {
        const url = new URL(id)
        if (id.includes("youtube.com")) {
          return url.searchParams.get("v") || ""
        } else {
          return url.pathname.substring(1)
        }
      } catch (error) {
        console.error("Invalid YouTube URL:", error)
        return id
      }
    }
    return id
  }

  const actualVideoId = extractVideoId(videoId)

  const handlePlay = () => {
    setPlaying(true)
  }

  const toggleExpand = () => {
    setExpanded(!expanded)
  }

  // Handle Escape key to minimize when expanded
  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === "Escape" && expanded) {
        setExpanded(false)
      }
    }
    if (expanded) {
      document.addEventListener("keydown", handleKeyDown)
    }
    return () => {
      document.removeEventListener("keydown", handleKeyDown)
    }
  }, [expanded])

  const getThumbnailUrl = () => {
    if (customThumbnail) return customThumbnail
    return actualVideoId
      ? `https://i.ytimg.com/vi/${actualVideoId}/hqdefault.jpg`
      : ""
  }

  return (
    <>
      {/* Main container - always in the document flow */}
      <div
        className={cn(
          "relative",
          expanded ? "invisible" : "visible",
          className
        )}
      >
        <motion.div
          layoutId={`youtube-player-${videoId}`}
          className={cn(
            "bg-card text-card-foreground overflow-hidden rounded-xl border shadow-lg",
            containerClassName
          )}
        >
          <motion.div
            layoutId={`youtube-player-content-${videoId}`}
            className={cn("bg-muted relative aspect-video", playerClassName)}
          >
            {!playing && (
              <>
                <motion.div
                  layoutId={`youtube-player-thumbnail-container-${videoId}`}
                  className={cn(
                    "from-muted to-muted/80 absolute inset-0 bg-gradient-to-br",
                    thumbnailClassName
                  )}
                >
                  {getThumbnailUrl() && (
                    <motion.img
                      layoutId={`youtube-player-thumbnail-${videoId}`}
                      src={getThumbnailUrl()}
                      alt={title || "Video thumbnail"}
                      className={cn(
                        "absolute inset-0 h-full w-full object-cover opacity-70",
                        thumbnailImageClassName
                      )}
                    />
                  )}
                </motion.div>

                <motion.div
                  layoutId={`youtube-player-content-overlay-${videoId}`}
                  className="absolute inset-0 z-10 flex flex-col items-center justify-center"
                >
                  <Button
                    size="lg"
                    variant="secondary"
                    className={cn(
                      "border-border/20 bg-background/80 relative h-16 w-16 rounded-full border p-0 backdrop-blur-sm md:h-20 md:w-20",
                      "focus-visible:ring-ring focus-visible:ring-offset-background focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none",
                      playButtonClassName
                    )}
                    onClick={handlePlay}
                    aria-label="Play video"
                  >
                    <Play
                      className={cn(
                        "fill-primary text-primary h-6 w-6 translate-x-[2px] md:h-8 md:w-8",
                        playIconClassName
                      )}
                    />
                  </Button>

                  {title && (
                    <motion.h3
                      layoutId={`youtube-player-title-${videoId}`}
                      className={cn(
                        "text-secondary/90 mt-4 max-w-xs text-center text-sm font-medium md:max-w-md md:text-base",
                        titleClassName
                      )}
                    >
                      {title}
                    </motion.h3>
                  )}
                </motion.div>
              </>
            )}

            {playing && (
              <iframe
                src={`https://www.youtube.com/embed/${actualVideoId}?autoplay=1&rel=0&modestbranding=1&iv_load_policy=3&showinfo=0&controls=1`}
                title={title}
                allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
                allowFullScreen
                className="h-full w-full border-0"
              />
            )}

            {/* Controls Overlay */}
            <YouTubePlayerControls
              videoId={videoId}
              expanded={expanded}
              playing={playing}
              isHovered={isHovered}
              onToggleExpand={toggleExpand}
              controlsClassName={controlsClassName}
              expandButtonClassName={expandButtonClassName}
            />
          </motion.div>
        </motion.div>
      </div>

      {/* Expanded state - fixed position */}
      <AnimatePresence>
        {expanded && (
          <>
            <motion.div
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              exit={{ opacity: 0 }}
              transition={{ duration: 0.2 }}
              className={cn(
                "bg-background/80 fixed inset-0 z-40 backdrop-blur-sm",
                backdropClassName
              )}
              onClick={toggleExpand}
              aria-label="Close expanded video"
            />

            <div className="pointer-events-none fixed inset-0 z-50 flex items-center justify-center">
              <motion.div
                layoutId={`youtube-player-${videoId}`}
                className={cn(
                  "bg-card text-card-foreground pointer-events-auto overflow-hidden rounded-lg border shadow-xl",
                  "aspect-video max-h-[90vh] w-[90vw] max-w-[1200px]",
                  expandedClassName
                )}
              >
                <motion.div
                  layoutId={`youtube-player-content-${videoId}`}
                  className={cn(
                    "bg-muted relative aspect-video",
                    playerClassName
                  )}
                >
                  {!playing && (
                    <>
                      <motion.div
                        layoutId={`youtube-player-thumbnail-container-${videoId}`}
                        className={cn(
                          "from-muted to-muted/80 absolute inset-0 bg-gradient-to-br",
                          thumbnailClassName
                        )}
                      >
                        {getThumbnailUrl() && (
                          <motion.img
                            layoutId={`youtube-player-thumbnail-${videoId}`}
                            src={getThumbnailUrl()}
                            alt={title || "Video thumbnail"}
                            className={cn(
                              "absolute inset-0 h-full w-full object-cover opacity-70",
                              thumbnailImageClassName
                            )}
                          />
                        )}
                      </motion.div>

                      <motion.div
                        layoutId={`youtube-player-content-overlay-${videoId}`}
                        className="absolute inset-0 z-10 flex flex-col items-center justify-center"
                      >
                        <Button
                          size="lg"
                          variant="secondary"
                          className={cn(
                            "border-border/20 bg-background/80 relative h-16 w-16 rounded-full border p-0 backdrop-blur-sm md:h-20 md:w-20",
                            "focus-visible:ring-ring focus-visible:ring-offset-background focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none",
                            playButtonClassName
                          )}
                          onClick={handlePlay}
                          aria-label="Play video"
                        >
                          <Play
                            className={cn(
                              "fill-primary text-primary h-6 w-6 translate-x-[2px] md:h-8 md:w-8",
                              playIconClassName
                            )}
                          />
                        </Button>

                        {title && (
                          <motion.h3
                            layoutId={`youtube-player-title-${videoId}`}
                            className={cn(
                              "text-foreground/90 mt-4 max-w-xs text-center text-sm font-medium md:max-w-md md:text-base",
                              titleClassName
                            )}
                          >
                            {title}
                          </motion.h3>
                        )}
                      </motion.div>
                    </>
                  )}

                  {playing && (
                    <iframe
                      src={`https://www.youtube.com/embed/${actualVideoId}?autoplay=1&rel=0&modestbranding=1&iv_load_policy=3&showinfo=0&controls=1`}
                      title={title}
                      allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
                      allowFullScreen
                      className="h-full w-full border-0"
                    />
                  )}

                  {/* Controls Overlay */}
                  <YouTubePlayerControls
                    videoId={videoId}
                    expanded={expanded}
                    playing={playing}
                    isHovered={isHovered}
                    onToggleExpand={toggleExpand}
                    controlsClassName={controlsClassName}
                    expandButtonClassName={expandButtonClassName}
                  />
                </motion.div>
              </motion.div>
            </div>
          </>
        )}
      </AnimatePresence>
    </>
  )
}

// Controls Component
interface YouTubePlayerControlsProps {
  videoId: string
  expanded: boolean
  playing: boolean
  isHovered: boolean
  onToggleExpand: () => void
  controlsClassName?: string
  expandButtonClassName?: string
}

function YouTubePlayerControls({
  videoId,
  expanded,
  playing,
  isHovered,
  onToggleExpand,
  controlsClassName,
  expandButtonClassName,
}: YouTubePlayerControlsProps) {
  const shouldShow = !playing || isHovered || expanded

  return (
    <AnimatePresence>
      {shouldShow && (
        <motion.div
          layoutId={`youtube-player-controls-${videoId}`}
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          transition={{ duration: 0.2 }}
          className={cn("absolute top-2 right-2 z-20", controlsClassName)}
        >
          <motion.div whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }}>
            <Button
              variant="secondary"
              size="icon"
              onClick={onToggleExpand}
              className={cn(
                "bg-background/40 hover:bg-background/60 focus-visible:ring-ring/50 h-8 w-8 rounded-full backdrop-blur-sm md:h-9 md:w-9",
                expandButtonClassName
              )}
              aria-label={expanded ? "Minimize video" : "Maximize video"}
            >
              <motion.div
                animate={{ rotate: expanded ? 180 : 0 }}
                transition={{ type: "spring", stiffness: 300, damping: 20 }}
              >
                {expanded ? (
                  <Minimize2 className="h-4 w-4 md:h-5 md:w-5" />
                ) : (
                  <Maximize2 className="h-4 w-4 md:h-5 md:w-5" />
                )}
              </motion.div>
            </Button>
          </motion.div>
        </motion.div>
      )}
    </AnimatePresence>
  )
}

// Export sub-components for advanced customization
export { YouTubePlayerControls }
```

**Update the import paths to match your project setup.**

## Usage

```tsx
export default function Example() {
  return (
    <YouTubePlayer
      videoId="dQw4w9WgXcQ"
      title="Never Gonna Give You Up - Rick Astley"
    />
  );
}
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| videoId | `string` | - | YouTube video ID or full URL |
| title | `string` | - | Video title displayed on thumbnail |
| defaultExpanded | `boolean` | `false` | Start in expanded modal view |
| customThumbnail | `string` | - | Custom thumbnail image URL |
| className | `string` | - | Additional CSS classes for container |
| containerClassName | `string` | - | CSS classes for video container |
| expandedClassName | `string` | - | CSS classes for expanded modal view |
| thumbnailClassName | `string` | - | CSS classes for thumbnail container |
| thumbnailImageClassName | `string` | - | CSS classes for thumbnail image |
| playButtonClassName | `string` | - | CSS classes for play button |
| playIconClassName | `string` | - | CSS classes for play icon |
| titleClassName | `string` | - | CSS classes for video title |
| controlsClassName | `string` | - | CSS classes for controls container |
| expandButtonClassName | `string` | - | CSS classes for expand/minimize button |
| backdropClassName | `string` | - | CSS classes for modal backdrop |
| playerClassName | `string` | - | CSS classes for player container |

## Examples

### Basic Player

```tsx
<YouTubePlayer
  videoId="dQw4w9WgXcQ"
  title="Never Gonna Give You Up - Rick Astley"
/>
```

### With Custom Thumbnail

```tsx
<YouTubePlayer
  videoId="jNQXAC9IVRw"
  title="Me at the zoo - First YouTube Video"
  customThumbnail="https://images.unsplash.com/photo-1611162617474-5b21e879e113?w=800&h=450&fit=crop&crop=center"
/>
```

### Default Expanded

```tsx
<YouTubePlayer
  videoId="ScMzIvxBSi4"
  title="The Evolution of Dance"
  defaultExpanded={true}
/>
```

### Custom Styling

```tsx
<YouTubePlayer
  videoId="kJQP7kiw5Fk"
  title="Despacito - Luis Fonsi ft. Daddy Yankee"
  containerClassName="border-2 border-primary rounded-2xl shadow-2xl"
  thumbnailImageClassName="opacity-90 saturate-150"
  playButtonClassName="bg-primary/20 border-primary hover:bg-primary/30"
  playIconClassName="text-primary fill-primary"
  titleClassName="text-primary font-bold"
  controlsClassName="right-4 top-4"
  expandButtonClassName="bg-primary/20 hover:bg-primary/30 border-primary"
/>
```

### Multiple Players Grid

```tsx
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
  <YouTubePlayer
    videoId="9bZkp7q19f0"
    title="PSY - GANGNAM STYLE"
    className="w-full"
  />
  <YouTubePlayer
    videoId="fJ9rUzIMcZQ"
    title="Queen – Bohemian Rhapsody"
    className="w-full"
  />
  <YouTubePlayer
    videoId="L_jWHffIx5E"
    title="Smash Mouth - All Star"
    className="w-full"
  />
</div>
```

## URL Format Support

The component automatically handles different YouTube URL formats:

```tsx
// Video ID
<YouTubePlayer videoId="dQw4w9WgXcQ" />

// Full YouTube URL
<YouTubePlayer videoId="https://www.youtube.com/watch?v=dQw4w9WgXcQ" />

// Short URL
<YouTubePlayer videoId="https://youtu.be/dQw4w9WgXcQ" />
```

## Advanced Usage

### With All Customization Options

```tsx
export default function AdvancedPlayer() {
  return (
    <div className="max-w-4xl mx-auto p-8">
      <YouTubePlayer
        videoId="dQw4w9WgXcQ"
        title="Custom Styled Player"
        customThumbnail="/custom-thumbnail.jpg"
        defaultExpanded={false}
        // Container styling
        className="mb-8"
        containerClassName="border-2 border-gradient rounded-xl overflow-hidden shadow-lg"
        expandedClassName="border-none shadow-2xl"
        // Thumbnail styling
        thumbnailClassName="bg-gradient-to-br from-blue-500/20 to-purple-500/20"
        thumbnailImageClassName="opacity-80 transition-opacity hover:opacity-100"
        // Play button styling
        playButtonClassName="bg-white/90 hover:bg-white border-2 border-blue-500 shadow-lg"
        playIconClassName="text-blue-500 fill-blue-500"
        // Title styling
        titleClassName="text-white font-bold text-lg drop-shadow-lg"
        // Controls styling
        controlsClassName="right-3 top-3"
        expandButtonClassName="bg-black/50 hover:bg-black/70 border border-white/20"
        // Modal styling
        backdropClassName="bg-black/60 backdrop-blur-md"
        playerClassName="bg-black rounded-lg"
      />
    </div>
  );
}
```

## Component Architecture

The YouTube Player consists of two main sub-components:

### YouTubePlayer (Main Component)

The primary component that handles the video player logic, state management, and rendering. It includes:

- Thumbnail display with custom image support
- Play button with customizable styling
- Expandable modal functionality
- URL parsing for different YouTube formats
- Keyboard shortcuts (ESC to close modal)

### YouTubePlayerControls

A separate component for the expand/minimize controls that can be used independently:

```tsx
<YouTubePlayerControls
  videoId="unique-id"
  expanded={false}
  playing={false}
  isHovered={true}
  onToggleExpand={() => {}}
  controlsClassName="custom-controls"
  expandButtonClassName="custom-expand-btn"
/>
```

## Features

### Core Features

- **Expandable Modal**: Full-screen modal view with smooth animations
- **Custom Thumbnails**: Support for custom thumbnail images
- **URL Flexibility**: Handles video IDs, full URLs, and short URLs
- **Responsive Design**: Works seamlessly across all device sizes
- **Keyboard Navigation**: ESC key closes expanded view

### User Experience

- **Smooth Animations**: Powered by Framer Motion for fluid transitions
- **Hover Effects**: Interactive controls that appear on hover
- **Loading States**: Graceful handling of video loading
- **Accessibility**: ARIA labels and keyboard support

### Customization

- **Extensive Styling**: 12+ className props for complete customization
- **Flexible Layout**: Works in grids, cards, and custom containers
- **Theme Integration**: Follows your design system colors and spacing
- **Component Composition**: Sub-components can be used independently

## Accessibility

The YouTube Player includes comprehensive accessibility features:

- **ARIA Labels**: Proper labeling for screen readers
- **Keyboard Navigation**: Full keyboard support including ESC to close
- **Focus Management**: Proper focus handling in modal states
- **Semantic HTML**: Uses appropriate HTML elements and structure
- **High Contrast**: Respects system preferences for reduced motion

## Browser Support

- Modern browsers with ES2018+ support
- Requires JavaScript enabled for video playback
- Falls back gracefully when YouTube embed is blocked
- Mobile-first responsive design

## Performance

- **Lazy Loading**: Videos only load when play button is clicked
- **Optimized Animations**: GPU-accelerated transforms with Framer Motion
- **Efficient Re-renders**: Minimal state updates and memoization
- **Lightweight Bundle**: Only includes necessary dependencies
