{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "lesson-video-player",
  "title": "Lesson Video Player",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/lesson-video-player/LessonVideoPlayer.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  ArrowRight,\n  Bookmark,\n  BookmarkCheck,\n  Check,\n  CheckCircle2,\n  ChevronRight,\n  Clock,\n  Download,\n  FileCode2,\n  FileText,\n  Layers,\n  Lightbulb,\n  Maximize2,\n  MessageSquare,\n  MessageSquareQuote,\n  Minimize2,\n  Pause,\n  Play,\n  Plus,\n  RotateCcw,\n  RotateCw,\n  Search,\n  Subtitles,\n  ThumbsUp,\n  Trash2,\n  Volume1,\n  Volume2,\n  VolumeX,\n} from 'lucide-react'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Input } from '@/components/ui/input'\nimport { Progress } from '@/components/ui/progress'\nimport { Separator } from '@/components/ui/separator'\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'\nimport { Textarea } from '@/components/ui/textarea'\n\nexport interface TranscriptItem {\n  id: string\n  start: number\n  end: number\n  speaker: string\n  text: string\n}\n\nexport interface NoteItem {\n  id: string\n  timestamp: number\n  text: string\n  createdAt: string\n}\n\nexport interface QuestionItem {\n  id: string\n  timestamp: number\n  author: string\n  avatar: string\n  question: string\n  upvotes: number\n  hasUpvoted?: boolean\n  answer?: {\n    author: string\n    role: string\n    text: string\n    isInstructor?: boolean\n  }\n}\n\nconst initialTranscript: TranscriptItem[] = [\n  {\n    id: 't-1',\n    start: 0,\n    end: 75,\n    speaker: 'Sarah Connor',\n    text: 'Welcome back! In this lesson, we are tackling one of the trickiest parts of design systems: building resilient dark-mode token palettes using the OKLCH color space.',\n  },\n  {\n    id: 't-2',\n    start: 75,\n    end: 220,\n    speaker: 'Sarah Connor',\n    text: 'Why do traditional HSL and sRGB color models fall short? Because perceptual brightness is non-uniform — pure blue at 50% lightness looks vastly darker to the human eye than pure yellow at 50% lightness.',\n  },\n  {\n    id: 't-3',\n    start: 220,\n    end: 384,\n    speaker: 'Sarah Connor',\n    text: 'OKLCH solves this by decoupling perceived lightness (L) from chroma (C) and hue (H). When you step lightness down by 10%, the perceived luminance decreases identically regardless of hue angle.',\n  },\n  {\n    id: 't-4',\n    start: 384,\n    end: 555,\n    speaker: 'Sarah Connor',\n    text: 'When calculating contrast in OKLCH, lightness is perceptually uniform across hues, which prevents dark-mode contrast crushing. Notice our formula on the slide.',\n  },\n  {\n    id: 't-5',\n    start: 555,\n    end: 750,\n    speaker: 'Sarah Connor',\n    text: 'Next, let us discuss wide-gamut Display P3 displays. While P3 provides 25% richer saturation, we must ensure automatic fallback clamping for legacy sRGB monitors.',\n  },\n  {\n    id: 't-6',\n    start: 750,\n    end: 945,\n    speaker: 'Sarah Connor',\n    text: 'In dark mode, human retinas are more sensitive to intense chroma saturation on dark surfaces. A solid heuristic is to reduce chroma by 15% to 20% on OLED dark backgrounds.',\n  },\n  {\n    id: 't-7',\n    start: 945,\n    end: 1120,\n    speaker: 'Sarah Connor',\n    text: 'To wrap up, download the starter configuration below. In the next lesson, we will wire these token variables directly into our Tailwind CSS v4 @theme inline directives.',\n  },\n]\n\nconst initialNotes: NoteItem[] = [\n  {\n    id: 'n-1',\n    timestamp: 102, // 01:42\n    text: 'Pure blue vs pure yellow in HSL: huge luminance mismatch. OKLCH fixes this at the root.',\n    createdAt: '2 hours ago',\n  },\n  {\n    id: 'n-2',\n    timestamp: 252, // 04:12\n    text: 'Review color-mix in oklab formulas — can generate surface elevation tints with a single token!',\n    createdAt: '1 hour ago',\n  },\n  {\n    id: 'n-3',\n    timestamp: 384, // 06:24\n    text: 'Lightness rule: Keep L >= 0.70 for primary brand text on dark surfaces to guarantee APCA Lc 60 minimum.',\n    createdAt: 'Just now',\n  },\n]\n\nconst initialQuestions: QuestionItem[] = [\n  {\n    id: 'q-1',\n    timestamp: 225, // 03:45\n    author: 'David K.',\n    avatar: 'DK',\n    question: 'Is browser support for OKLCH color-mix and raw oklch() ready for enterprise SaaS applications?',\n    upvotes: 18,\n    hasUpvoted: false,\n    answer: {\n      author: 'Sarah Connor',\n      role: 'Instructor',\n      isInstructor: true,\n      text: 'Yes! OKLCH has 98%+ global browser support across all evergreen browsers. Tailwind CSS v4 uses it as the default token format natively.',\n    },\n  },\n  {\n    id: 'q-2',\n    timestamp: 380, // 06:20\n    author: 'Elena R.',\n    avatar: 'ER',\n    question: 'How do you prevent high chroma vibration on dark OLED zinc-950 surfaces?',\n    upvotes: 12,\n    hasUpvoted: false,\n    answer: {\n      author: 'Sarah Connor',\n      role: 'Instructor',\n      isInstructor: true,\n      text: 'Scale down chroma by multiplying C * 0.82 on dark tokens, while boosting lightness by +0.08 to preserve legibility without glare.',\n    },\n  },\n]\n\nconst speedOptions = [0.75, 1.0, 1.25, 1.5, 1.75, 2.0]\n\nfunction formatTime(seconds: number): string {\n  const m = Math.floor(seconds / 60)\n  const s = Math.floor(seconds % 60)\n  return `${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`\n}\n\nexport function LessonVideoPlayer() {\n  // Video Playback State\n  const [isPlaying, setIsPlaying] = React.useState(false)\n  const [currentTime, setCurrentTime] = React.useState(384) // 06:24\n  const [totalDuration] = React.useState(1120) // 18:40\n  const [bufferedPercent] = React.useState(78)\n  const [volume] = React.useState(85)\n  const [isMuted, setIsMuted] = React.useState(false)\n  const [playbackSpeed, setPlaybackSpeed] = React.useState(1.25)\n  const [showCaptions, setShowCaptions] = React.useState(true)\n  const [isFullscreen, setIsFullscreen] = React.useState(false)\n  const [activeTab, setActiveTab] = React.useState('transcript')\n  const [transcriptSearch, setTranscriptSearch] = React.useState('')\n  const [isCompleted, setIsCompleted] = React.useState(false)\n  const [isBookmarked, setIsBookmarked] = React.useState(false)\n  const [copiedAsset, setCopiedAsset] = React.useState<string | null>(null)\n\n  // Notes and Q&A state\n  const [notesList, setNotesList] = React.useState<NoteItem[]>(initialNotes)\n  const [newNoteText, setNewNoteText] = React.useState('')\n  const [questionsList, setQuestionsList] = React.useState<QuestionItem[]>(initialQuestions)\n  const [newQuestionText, setNewQuestionText] = React.useState('')\n\n  // Video interval timer\n  React.useEffect(() => {\n    let interval: NodeJS.Timeout | null = null\n    if (isPlaying) {\n      interval = setInterval(() => {\n        setCurrentTime((prev) => {\n          if (prev < totalDuration) {\n            return prev + 1\n          }\n          setIsPlaying(false)\n          return prev\n        })\n      }, 1000 / playbackSpeed)\n    }\n    return () => {\n      if (interval) clearInterval(interval)\n    }\n  }, [isPlaying, playbackSpeed, totalDuration])\n\n  const formattedCurrentTime = formatTime(currentTime)\n  const formattedTotalTime = formatTime(totalDuration)\n  const progressPercent = (currentTime / totalDuration) * 100\n\n  const seekTo = (seconds: number) => {\n    setCurrentTime(Math.max(0, Math.min(seconds, totalDuration)))\n  }\n\n  const handleSeekClick = (event: React.MouseEvent<HTMLDivElement>) => {\n    const rect = event.currentTarget.getBoundingClientRect()\n    const clickX = event.clientX - rect.left\n    const ratio = Math.max(0, Math.min(1, clickX / rect.width))\n    seekTo(Math.round(ratio * totalDuration))\n  }\n\n  const skipSeconds = (delta: number) => {\n    seekTo(currentTime + delta)\n  }\n\n  const cycleSpeed = () => {\n    const currentIndex = speedOptions.indexOf(playbackSpeed)\n    const nextIndex = (currentIndex + 1) % speedOptions.length\n    setPlaybackSpeed(speedOptions[nextIndex])\n  }\n\n  const toggleMute = () => {\n    setIsMuted((prev) => !prev)\n  }\n\n  const activeTranscriptItem =\n    initialTranscript.find((item) => currentTime >= item.start && currentTime < item.end) || initialTranscript[0]\n\n  const filteredTranscript = initialTranscript.filter((item) => {\n    const query = transcriptSearch.trim().toLowerCase()\n    if (!query) return true\n    return item.text.toLowerCase().includes(query) || item.speaker.toLowerCase().includes(query)\n  })\n\n  const handleAddNote = () => {\n    const text = newNoteText.trim()\n    if (!text) return\n    setNotesList([\n      {\n        id: `note-${Date.now()}`,\n        timestamp: currentTime,\n        text,\n        createdAt: 'Just now',\n      },\n      ...notesList,\n    ])\n    setNewNoteText('')\n  }\n\n  const handleDeleteNote = (id: string) => {\n    setNotesList((prev) => prev.filter((n) => n.id !== id))\n  }\n\n  const handleAddQuestion = () => {\n    const text = newQuestionText.trim()\n    if (!text) return\n    setQuestionsList([\n      {\n        id: `q-${Date.now()}`,\n        timestamp: currentTime,\n        author: 'You (Student)',\n        avatar: 'ME',\n        question: text,\n        upvotes: 1,\n        hasUpvoted: true,\n      },\n      ...questionsList,\n    ])\n    setNewQuestionText('')\n  }\n\n  const toggleUpvote = (id: string) => {\n    setQuestionsList((prev) =>\n      prev.map((q) => {\n        if (q.id === id) {\n          const hasUpvoted = !q.hasUpvoted\n          return {\n            ...q,\n            hasUpvoted,\n            upvotes: hasUpvoted ? q.upvotes + 1 : q.upvotes - 1,\n          }\n        }\n        return q\n      }),\n    )\n  }\n\n  const handleCopyAsset = (name: string) => {\n    setCopiedAsset(name)\n    setTimeout(() => {\n      setCopiedAsset(null)\n    }, 2000)\n  }\n\n  return (\n    <div data-slot=\"lesson-video-player\" className=\"bg-background text-foreground w-full space-y-5\">\n      {/* Top Lesson Navigation & Course Header Bar */}\n      <header className=\"bg-card rounded-xl border p-4 shadow-xs sm:px-6 sm:py-4\">\n        <div className=\"flex flex-col gap-3 md:flex-row md:items-center md:justify-between\">\n          {/* Left: Course Context & Lesson Title */}\n          <div className=\"space-y-1.5\">\n            <div className=\"flex flex-wrap items-center gap-2 text-xs\">\n              <span className=\"text-muted-foreground font-medium\">Design Systems with Tailwind CSS v4</span>\n              <ChevronRight className=\"text-muted-foreground size-3.5\" />\n              <Badge variant=\"outline\" className=\"gap-1 text-xs font-semibold\">\n                <Layers className=\"text-primary size-3\" />\n                <span>Module 1: Design Tokens Architecture</span>\n              </Badge>\n              <span className=\"text-muted-foreground hidden font-medium sm:inline\">Lesson 4 of 12</span>\n            </div>\n\n            <h1 className=\"text-foreground text-lg font-bold tracking-tight sm:text-xl\">\n              Lesson 4: Building Resilient OKLCH Dark-Mode Token Palettes\n            </h1>\n          </div>\n\n          {/* Right: Progress Indicator & Navigation Buttons */}\n          <div className=\"flex flex-wrap items-center gap-2.5\">\n            {/* Course Progress Pill */}\n            <div className=\"bg-muted/40 hidden items-center gap-2 rounded-lg border px-3 py-1.5 sm:flex\">\n              <div className=\"space-y-1 text-right\">\n                <div className=\"text-muted-foreground text-xs font-medium\">Module Progress</div>\n                <div className=\"font-mono text-xs font-bold tabular-nums\">4/12 (33%)</div>\n              </div>\n              <div className=\"w-12\">\n                <Progress value={33} className=\"h-1.5\" />\n              </div>\n            </div>\n\n            {/* Bookmark Button */}\n            <Button\n              variant=\"outline\"\n              size=\"icon\"\n              className=\"size-8.5\"\n              aria-label={isBookmarked ? 'Remove bookmark' : 'Bookmark lesson'}\n              onClick={() => setIsBookmarked(!isBookmarked)}\n            >\n              {isBookmarked ? (\n                <BookmarkCheck className=\"text-primary size-4\" />\n              ) : (\n                <Bookmark className=\"text-muted-foreground size-4\" />\n              )}\n            </Button>\n\n            {/* Complete Lesson Button */}\n            <Button\n              variant={isCompleted ? 'default' : 'outline'}\n              size=\"sm\"\n              className=\"h-8.5 gap-1.5 text-xs font-semibold shadow-xs\"\n              onClick={() => setIsCompleted(!isCompleted)}\n            >\n              {isCompleted ? <CheckCircle2 className=\"size-3.5\" /> : <Check className=\"size-3.5\" />}\n              <span>{isCompleted ? 'Completed' : 'Mark Complete'}</span>\n            </Button>\n\n            {/* Next Lesson Button */}\n            <Button variant=\"default\" size=\"sm\" className=\"h-8.5 gap-1.5 text-xs font-semibold shadow-xs\">\n              <span>Next Lesson</span>\n              <ArrowRight className=\"size-3.5\" />\n            </Button>\n          </div>\n        </div>\n      </header>\n\n      {/* 2-Column Classroom Layout */}\n      <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-12\">\n        {/* Left Column: Video Player Canvas + Takeaways & Downloads (8 cols) */}\n        <section className=\"space-y-5 lg:col-span-8\">\n          {/* Video Screen Container (Dark Video Canvas) */}\n          <div className=\"group relative flex min-h-[260px] w-full flex-col justify-between overflow-hidden rounded-xl border border-zinc-800 bg-zinc-950 text-white shadow-lg select-none\">\n            {/* Top Video Overlay Info Bar */}\n            <div className=\"z-20 flex items-center justify-between p-3.5 sm:p-4\">\n              <div className=\"flex items-center gap-2\">\n                <Badge\n                  variant=\"outline\"\n                  className=\"border-zinc-700 bg-zinc-900/80 px-2 py-0.5 font-mono text-xs font-medium text-zinc-300 backdrop-blur-md\"\n                >\n                  1080p 60fps HD\n                </Badge>\n                <Badge\n                  variant=\"outline\"\n                  className=\"border-primary/40 bg-primary/20 text-primary-foreground px-2 py-0.5 text-xs font-semibold backdrop-blur-md\"\n                >\n                  Lesson 4 / 12\n                </Badge>\n              </div>\n\n              {/* Instructor Watermark */}\n              <div className=\"flex items-center gap-2 rounded-full border border-zinc-800 bg-zinc-900/80 px-3 py-1 text-xs text-zinc-300 backdrop-blur-md\">\n                <span className=\"bg-success size-2 rounded-full\" />\n                <span className=\"font-medium\">Sarah Connor</span>\n                <span className=\"text-muted-foreground\">·</span>\n                <span className=\"text-muted-foreground\">Principal Design Engineer</span>\n              </div>\n            </div>\n\n            {/* Video Presentation Slide & Diagram Visual */}\n            <div className=\"relative my-auto flex flex-col items-center justify-center px-6 py-4 text-center\">\n              {/* Simulated Code & Color Token Slide Matrix */}\n              <div className=\"relative w-full max-w-xl space-y-3 rounded-lg border border-zinc-800/80 bg-zinc-900/85 p-4 text-left shadow-sm backdrop-blur-md\">\n                <div className=\"flex items-center justify-between border-b border-zinc-800 pb-2\">\n                  <div className=\"flex items-center gap-2\">\n                    <div className=\"flex gap-1.5\">\n                      <span className=\"bg-destructive/80 size-2.5 rounded-full\" />\n                      <span className=\"bg-warning/80 size-2.5 rounded-full\" />\n                      <span className=\"bg-success/80 size-2.5 rounded-full\" />\n                    </div>\n                    <span className=\"text-muted-foreground font-mono text-xs\">\n                      tokens.config.css — OKLCH Palette Engine\n                    </span>\n                  </div>\n                  <Badge variant=\"outline\" className=\"border-success/40 bg-success/10 text-success font-mono text-xs\">\n                    APCA Lc 74 (AAA)\n                  </Badge>\n                </div>\n\n                {/* Code Syntax Sample */}\n                <pre className=\"overflow-x-auto font-mono text-xs leading-relaxed text-zinc-300\">\n                  <code>\n                    <span className=\"text-muted-foreground\">/* OKLCH Perceptual Uniformity Matrix */</span>\n                    {'\\n'}\n                    <span className=\"text-chart-1\">@theme inline</span> {'{\\n'}{' '}\n                    <span className=\"text-info\">--color-primary</span>:{' '}\n                    <span className=\"text-warning\">oklch(0.62 0.19 259.8)</span>;{' '}\n                    <span className=\"text-muted-foreground\">/* Brand Base */</span>\n                    {'\\n'} <span className=\"text-info\">--color-surface-dark</span>:{' '}\n                    <span className=\"text-warning\">oklch(0.18 0.02 260.0)</span>;{' '}\n                    <span className=\"text-muted-foreground\">/* OLED Safe */</span>\n                    {'\\n'}\n                    {'}'}\n                  </code>\n                </pre>\n\n                {/* Color Palette Swatch Strip */}\n                <div className=\"flex items-center gap-2 pt-1\">\n                  <span className=\"text-muted-foreground text-xs font-medium\">Lightness Ramp:</span>\n                  <div className=\"flex flex-1 items-center gap-1.5\">\n                    <div className=\"h-5 flex-1 rounded bg-[oklch(0.95_0.04_259.8)] shadow-xs\" title=\"95% L\" />\n                    <div className=\"h-5 flex-1 rounded bg-[oklch(0.80_0.10_259.8)] shadow-xs\" title=\"80% L\" />\n                    <div\n                      className=\"h-5 flex-1 rounded bg-[oklch(0.62_0.19_259.8)] shadow-xs ring-1 ring-white/60\"\n                      title=\"62% L (Base)\"\n                    />\n                    <div className=\"h-5 flex-1 rounded bg-[oklch(0.40_0.15_259.8)] shadow-xs\" title=\"40% L\" />\n                    <div className=\"h-5 flex-1 rounded bg-[oklch(0.18_0.02_259.8)] shadow-xs\" title=\"18% L (Dark)\" />\n                  </div>\n                </div>\n              </div>\n\n              {/* Big Center Play / Pause Floating Button */}\n              <button\n                type=\"button\"\n                className=\"bg-primary text-primary-foreground hover:bg-primary/90 focus-visible:ring-ring absolute inset-0 m-auto flex size-14 cursor-pointer items-center justify-center rounded-full shadow-lg transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n                aria-label={isPlaying ? 'Pause video' : 'Play video'}\n                onClick={() => setIsPlaying(!isPlaying)}\n              >\n                {isPlaying ? (\n                  <Pause className=\"size-6 fill-current\" />\n                ) : (\n                  <Play className=\"ml-0.5 size-6 fill-current\" />\n                )}\n              </button>\n            </div>\n\n            {/* Captions Subtitles Overlay Box */}\n            {showCaptions && activeTranscriptItem && (\n              <div className=\"z-20 mx-auto mb-1 max-w-xl rounded-lg border border-white/10 bg-black/80 px-4 py-1.5 text-center text-xs font-medium text-zinc-200 shadow-md backdrop-blur-md sm:text-sm\">\n                <span className=\"text-muted-foreground\">[{formatTime(activeTranscriptItem.start)}]</span>{' '}\n                {activeTranscriptItem.text}\n              </div>\n            )}\n\n            {/* Custom Player Controls Bar (Bottom Overlay) */}\n            <div className=\"z-20 space-y-2 bg-gradient-to-t from-black/95 via-black/85 to-transparent p-3 sm:px-4 sm:pt-4 sm:pb-3.5\">\n              {/* Scrubber Timeline Bar */}\n              <div\n                className=\"group/bar relative flex h-4 w-full cursor-pointer items-center\"\n                role=\"slider\"\n                aria-label=\"Video Timeline Scrubber\"\n                aria-valuenow={currentTime}\n                aria-valuemin={0}\n                aria-valuemax={totalDuration}\n                onClick={handleSeekClick}\n              >\n                {/* Background Full Track */}\n                <div className=\"relative h-1.5 w-full overflow-hidden rounded-full bg-zinc-800 transition-[height] group-hover/bar:h-2.5\">\n                  {/* Buffer Progress */}\n                  <div\n                    className=\"absolute top-0 bottom-0 left-0 bg-zinc-700 transition-colors\"\n                    style={{ width: `${bufferedPercent}%` }}\n                  />\n                  {/* Played Progress */}\n                  <div\n                    className=\"bg-primary absolute top-0 bottom-0 left-0 transition-colors\"\n                    style={{ width: `${progressPercent}%` }}\n                  />\n                </div>\n\n                {/* Scrubber Dot Handle */}\n                <div\n                  className=\"bg-primary absolute size-3.5 -translate-x-1/2 rounded-full shadow-md ring-2 ring-white transition-transform group-hover/bar:scale-125\"\n                  style={{ left: `${progressPercent}%` }}\n                />\n              </div>\n\n              {/* Controls Row: Play, Skip, Timestamps, Speed, Audio, Screen */}\n              <div className=\"flex items-center justify-between gap-2 pt-0.5\">\n                {/* Left Controls */}\n                <div className=\"flex items-center gap-1 sm:gap-2\">\n                  {/* Play / Pause */}\n                  <Button\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    className=\"size-8 text-white hover:bg-white/15\"\n                    aria-label={isPlaying ? 'Pause' : 'Play'}\n                    onClick={() => setIsPlaying(!isPlaying)}\n                  >\n                    {isPlaying ? (\n                      <Pause className=\"size-4.5 fill-current\" />\n                    ) : (\n                      <Play className=\"size-4.5 fill-current\" />\n                    )}\n                  </Button>\n\n                  {/* 15s Rewind */}\n                  <Button\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    className=\"size-8 text-zinc-300 hover:bg-white/15 hover:text-white\"\n                    aria-label=\"Rewind 15 seconds\"\n                    onClick={() => skipSeconds(-15)}\n                  >\n                    <RotateCcw className=\"size-4\" />\n                  </Button>\n\n                  {/* 15s Fast Forward */}\n                  <Button\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    className=\"size-8 text-zinc-300 hover:bg-white/15 hover:text-white\"\n                    aria-label=\"Fast forward 15 seconds\"\n                    onClick={() => skipSeconds(15)}\n                  >\n                    <RotateCw className=\"size-4\" />\n                  </Button>\n\n                  {/* Volume Toggle */}\n                  <Button\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    className=\"size-8 text-zinc-300 hover:bg-white/15 hover:text-white\"\n                    aria-label={isMuted ? 'Unmute' : 'Mute'}\n                    onClick={toggleMute}\n                  >\n                    {isMuted || volume === 0 ? (\n                      <VolumeX className=\"text-destructive size-4\" />\n                    ) : volume < 50 ? (\n                      <Volume1 className=\"size-4\" />\n                    ) : (\n                      <Volume2 className=\"size-4\" />\n                    )}\n                  </Button>\n\n                  {/* Timestamp Display */}\n                  <div className=\"flex items-center gap-1 font-mono text-xs font-semibold text-zinc-300 tabular-nums sm:ml-1\">\n                    <span className=\"text-white\">{formattedCurrentTime}</span>\n                    <span className=\"text-muted-foreground\">/</span>\n                    <span className=\"text-muted-foreground\">{formattedTotalTime}</span>\n                  </div>\n                </div>\n\n                {/* Right Controls */}\n                <div className=\"flex items-center gap-1 sm:gap-2\">\n                  {/* Speed Selector Button */}\n                  <Button\n                    variant=\"ghost\"\n                    size=\"sm\"\n                    className=\"h-7 px-2 font-mono text-xs font-bold text-zinc-300 hover:bg-white/15 hover:text-white\"\n                    aria-label=\"Cycle Playback Speed\"\n                    onClick={cycleSpeed}\n                  >\n                    {playbackSpeed}x\n                  </Button>\n\n                  {/* Captions Subtitles Toggle */}\n                  <Button\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    className={`size-8 ${\n                      showCaptions\n                        ? 'text-primary hover:bg-white/15'\n                        : 'text-muted-foreground hover:bg-white/15 hover:text-white'\n                    }`}\n                    aria-label={showCaptions ? 'Hide Subtitles' : 'Show Subtitles'}\n                    onClick={() => setShowCaptions(!showCaptions)}\n                  >\n                    <Subtitles className=\"size-4\" />\n                  </Button>\n\n                  {/* Fullscreen Toggle */}\n                  <Button\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    className=\"size-8 text-zinc-300 hover:bg-white/15 hover:text-white\"\n                    aria-label={isFullscreen ? 'Exit Fullscreen' : 'Enter Fullscreen'}\n                    onClick={() => setIsFullscreen(!isFullscreen)}\n                  >\n                    {isFullscreen ? <Minimize2 className=\"size-4\" /> : <Maximize2 className=\"size-4\" />}\n                  </Button>\n                </div>\n              </div>\n            </div>\n          </div>\n\n          {/* Lesson Key Takeaways & Downloadable Assets Row */}\n          <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n            {/* Key Takeaways Card */}\n            <Card className=\"shadow-xs\">\n              <CardHeader className=\"pb-2.5\">\n                <div className=\"flex items-center justify-between\">\n                  <CardTitle className=\"text-foreground flex items-center gap-1.5 text-xs font-bold tracking-tight uppercase\">\n                    <Lightbulb className=\"text-primary size-3.5\" />\n                    Key Takeaways\n                  </CardTitle>\n                  <Badge variant=\"outline\" className=\"font-mono text-xs\">\n                    OKLCH v4\n                  </Badge>\n                </div>\n                <CardDescription className=\"text-xs\">\n                  Essential architectural concepts taught in this lecture\n                </CardDescription>\n              </CardHeader>\n              <CardContent className=\"space-y-2.5 text-xs\">\n                <div className=\"bg-muted/30 flex items-start gap-2.5 rounded-lg border p-2.5\">\n                  <div className=\"bg-primary/10 text-primary mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full text-xs font-bold\">\n                    1\n                  </div>\n                  <div>\n                    <span className=\"text-foreground font-semibold\">Perceptual Uniformity:</span>\n                    <p className=\"text-muted-foreground mt-0.5 leading-relaxed\">\n                      OKLCH lightness remains constant across all hues, maintaining predictable contrast ratios across\n                      both dark and light palettes.\n                    </p>\n                  </div>\n                </div>\n\n                <div className=\"bg-muted/30 flex items-start gap-2.5 rounded-lg border p-2.5\">\n                  <div className=\"bg-primary/10 text-primary mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full text-xs font-bold\">\n                    2\n                  </div>\n                  <div>\n                    <span className=\"text-foreground font-semibold\">Display P3 Gamut Clamping:</span>\n                    <p className=\"text-muted-foreground mt-0.5 leading-relaxed\">\n                      Leverage vibrant P3 color gamuts on supported displays while automatically fallback-clamping for\n                      sRGB displays.\n                    </p>\n                  </div>\n                </div>\n\n                <div className=\"bg-muted/30 flex items-start gap-2.5 rounded-lg border p-2.5\">\n                  <div className=\"bg-primary/10 text-primary mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full text-xs font-bold\">\n                    3\n                  </div>\n                  <div>\n                    <span className=\"text-foreground font-semibold\">Chroma Scaling in Dark Mode:</span>\n                    <p className=\"text-muted-foreground mt-0.5 leading-relaxed\">\n                      Scale down chroma by 15-20% on deep dark backgrounds to prevent ocular fatigue and visual\n                      vibration.\n                    </p>\n                  </div>\n                </div>\n              </CardContent>\n            </Card>\n\n            {/* Downloadable Source Code & Assets Card */}\n            <Card className=\"shadow-xs\">\n              <CardHeader className=\"pb-2.5\">\n                <div className=\"flex items-center justify-between\">\n                  <CardTitle className=\"text-foreground flex items-center gap-1.5 text-xs font-bold tracking-tight uppercase\">\n                    <FileCode2 className=\"text-primary size-3.5\" />\n                    Lesson Assets & Code\n                  </CardTitle>\n                  <Badge variant=\"secondary\" className=\"text-xs\">\n                    3 Files\n                  </Badge>\n                </div>\n                <CardDescription className=\"text-xs\">Starter boilerplate and token configuration files</CardDescription>\n              </CardHeader>\n              <CardContent className=\"space-y-2 text-xs\">\n                {/* Asset 1 */}\n                <div className=\"bg-muted/30 hover:bg-muted/50 flex items-center justify-between rounded-lg border p-2.5 transition-colors\">\n                  <div className=\"flex min-w-0 items-center gap-2.5\">\n                    <div className=\"bg-primary/10 text-primary flex size-8 shrink-0 items-center justify-center rounded-md font-mono text-xs font-bold\">\n                      TS\n                    </div>\n                    <div className=\"min-w-0\">\n                      <p className=\"text-foreground truncate text-xs font-semibold\">tokens.config.ts</p>\n                      <p className=\"text-muted-foreground font-mono text-xs\">14.2 KB · Tailwind v4 Theme</p>\n                    </div>\n                  </div>\n                  <Button\n                    aria-label=\"Download attachment\"\n                    variant=\"outline\"\n                    size=\"sm\"\n                    className=\"h-7 gap-1 px-2 text-xs\"\n                    onClick={() => handleCopyAsset('tokens.config.ts')}\n                  >\n                    {copiedAsset === 'tokens.config.ts' ? (\n                      <Check className=\"text-success size-3\" />\n                    ) : (\n                      <Download className=\"size-3\" />\n                    )}\n                    <span>{copiedAsset === 'tokens.config.ts' ? 'Saved' : 'Download'}</span>\n                  </Button>\n                </div>\n\n                {/* Asset 2 */}\n                <div className=\"bg-muted/30 hover:bg-muted/50 flex items-center justify-between rounded-lg border p-2.5 transition-colors\">\n                  <div className=\"flex min-w-0 items-center gap-2.5\">\n                    <div className=\"bg-chart-2/10 text-chart-2 flex size-8 shrink-0 items-center justify-center rounded-md font-mono text-xs font-bold\">\n                      FIG\n                    </div>\n                    <div className=\"min-w-0\">\n                      <p className=\"text-foreground truncate text-xs font-semibold\">palette-matrix.fig</p>\n                      <p className=\"text-muted-foreground font-mono text-xs\">4.8 MB · Token Library</p>\n                    </div>\n                  </div>\n                  <Button\n                    aria-label=\"Download attachment\"\n                    variant=\"outline\"\n                    size=\"sm\"\n                    className=\"h-7 gap-1 px-2 text-xs\"\n                    onClick={() => handleCopyAsset('palette-matrix.fig')}\n                  >\n                    {copiedAsset === 'palette-matrix.fig' ? (\n                      <Check className=\"text-success size-3\" />\n                    ) : (\n                      <Download className=\"size-3\" />\n                    )}\n                    <span>{copiedAsset === 'palette-matrix.fig' ? 'Saved' : 'Download'}</span>\n                  </Button>\n                </div>\n\n                {/* Asset 3 */}\n                <div className=\"bg-muted/30 hover:bg-muted/50 flex items-center justify-between rounded-lg border p-2.5 transition-colors\">\n                  <div className=\"flex min-w-0 items-center gap-2.5\">\n                    <div className=\"bg-destructive/10 text-destructive flex size-8 shrink-0 items-center justify-center rounded-md font-mono text-xs font-bold\">\n                      PDF\n                    </div>\n                    <div className=\"min-w-0\">\n                      <p className=\"text-foreground truncate text-xs font-semibold\">apca-contrast-guide.pdf</p>\n                      <p className=\"text-muted-foreground font-mono text-xs\">1.1 MB · Cheat Sheet</p>\n                    </div>\n                  </div>\n                  <Button\n                    aria-label=\"Download attachment\"\n                    variant=\"outline\"\n                    size=\"sm\"\n                    className=\"h-7 gap-1 px-2 text-xs\"\n                    onClick={() => handleCopyAsset('apca-contrast-guide.pdf')}\n                  >\n                    {copiedAsset === 'apca-contrast-guide.pdf' ? (\n                      <Check className=\"text-success size-3\" />\n                    ) : (\n                      <Download className=\"size-3\" />\n                    )}\n                    <span>{copiedAsset === 'apca-contrast-guide.pdf' ? 'Saved' : 'Download'}</span>\n                  </Button>\n                </div>\n              </CardContent>\n            </Card>\n          </div>\n        </section>\n\n        {/* Right Column: Interactive Transcript & Notes Workspace (4 cols) */}\n        <aside className=\"flex flex-col lg:col-span-4\">\n          <Card className=\"flex h-full flex-col overflow-hidden shadow-xs\">\n            <Tabs value={activeTab} onValueChange={setActiveTab} className=\"flex h-full flex-col\">\n              {/* Tabs Navigation Header */}\n              <div className=\"bg-muted/30 border-b p-2.5\">\n                <TabsList className=\"grid h-8.5 w-full grid-cols-3\">\n                  <TabsTrigger value=\"transcript\" className=\"gap-1 text-xs font-medium\">\n                    <FileText className=\"size-3\" />\n                    <span>Transcript</span>\n                  </TabsTrigger>\n                  <TabsTrigger value=\"notes\" className=\"gap-1 text-xs font-medium\">\n                    <BookmarkCheck className=\"size-3\" />\n                    <span>Notes</span>\n                    <Badge variant=\"secondary\" className=\"ml-0.5 px-1 py-0 text-xs\">\n                      {notesList.length}\n                    </Badge>\n                  </TabsTrigger>\n                  <TabsTrigger value=\"qa\" className=\"gap-1 text-xs font-medium\">\n                    <MessageSquareQuote className=\"size-3\" />\n                    <span>Q&A</span>\n                    <Badge variant=\"secondary\" className=\"ml-0.5 px-1 py-0 text-xs\">\n                      {questionsList.length}\n                    </Badge>\n                  </TabsTrigger>\n                </TabsList>\n              </div>\n\n              {/* TAB 1: Interactive Transcript */}\n              <TabsContent value=\"transcript\" className=\"m-0 flex flex-1 flex-col focus-visible:outline-none\">\n                {/* Search Transcript Filter */}\n                <div className=\"border-b p-3\">\n                  <div className=\"relative\">\n                    <Search className=\"text-muted-foreground absolute top-2.5 left-2.5 size-3.5\" />\n                    <Input\n                      value={transcriptSearch}\n                      onChange={(e) => setTranscriptSearch(e.target.value)}\n                      placeholder=\"Search lecture transcript...\"\n                      className=\"h-8 pl-8 text-xs\"\n                    />\n                  </div>\n                </div>\n\n                {/* Transcript Segments List */}\n                <div className=\"max-h-[580px] flex-1 space-y-2.5 overflow-y-auto p-3.5\">\n                  {filteredTranscript.map((item) => {\n                    const isActive = currentTime >= item.start && currentTime < item.end\n                    return (\n                      <div\n                        key={item.id}\n                        className={`group cursor-pointer rounded-lg border p-3 text-xs transition-colors duration-200 ${\n                          isActive\n                            ? 'border-primary/50 bg-primary/10 ring-primary/20 shadow-xs ring-1'\n                            : 'border-border/70 bg-card hover:bg-muted/40'\n                        }`}\n                        onClick={() => seekTo(item.start)}\n                      >\n                        <div className=\"mb-1.5 flex items-center justify-between\">\n                          <div className=\"flex items-center gap-1.5\">\n                            <Button\n                              variant=\"secondary\"\n                              size=\"sm\"\n                              className=\"h-6 gap-1 rounded-md px-1.5 font-mono text-xs font-bold tabular-nums\"\n                              onClick={(e) => {\n                                e.stopPropagation()\n                                seekTo(item.start)\n                              }}\n                            >\n                              <Play className=\"size-2.5 fill-current\" />\n                              <span>{formatTime(item.start)}</span>\n                            </Button>\n                            <span className=\"text-muted-foreground text-xs font-medium\">{item.speaker}</span>\n                          </div>\n\n                          {isActive && (\n                            <Badge variant=\"default\" className=\"gap-1 px-1.5 py-0 text-xs font-semibold\">\n                              <span className=\"size-1.5 animate-pulse rounded-full bg-white\" />\n                              <span>Playing</span>\n                            </Badge>\n                          )}\n                        </div>\n\n                        <p\n                          className={`leading-relaxed ${\n                            isActive\n                              ? 'text-foreground font-medium'\n                              : 'text-muted-foreground group-hover:text-foreground'\n                          }`}\n                        >\n                          {item.text}\n                        </p>\n                      </div>\n                    )\n                  })}\n                </div>\n\n                {/* Transcript Footer Notice */}\n                <div className=\"bg-muted/30 text-muted-foreground border-t p-2.5 text-center text-xs\">\n                  Click any line to jump to that timestamp in the lecture.\n                </div>\n              </TabsContent>\n\n              {/* TAB 2: Timestamped Notes Workspace */}\n              <TabsContent value=\"notes\" className=\"m-0 flex flex-1 flex-col focus-visible:outline-none\">\n                {/* Note Composer */}\n                <div className=\"bg-muted/20 space-y-2 border-b p-3\">\n                  <div className=\"flex items-center justify-between\">\n                    <label className=\"text-foreground flex items-center gap-1.5 text-xs font-bold tracking-tight\">\n                      <Clock className=\"text-primary size-3.5\" />\n                      <span>Add Note at {formattedCurrentTime}</span>\n                    </label>\n                    <span className=\"text-muted-foreground font-mono text-xs\">Captures current playback time</span>\n                  </div>\n\n                  <Textarea\n                    value={newNoteText}\n                    onValueChange={(v) => setNewNoteText(v)}\n                    rows={2}\n                    className=\"resize-y text-xs leading-relaxed\"\n                    placeholder={`Write your thoughts or takeaway at ${formattedCurrentTime}...`}\n                    onKeyDown={(e) => {\n                      if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {\n                        handleAddNote()\n                      }\n                    }}\n                  />\n\n                  <div className=\"flex items-center justify-between\">\n                    <span className=\"text-muted-foreground text-xs\">Press ⌘+Enter to save</span>\n                    <Button\n                      size=\"sm\"\n                      className=\"h-7.5 gap-1 px-3 text-xs font-semibold\"\n                      disabled={!newNoteText.trim()}\n                      onClick={handleAddNote}\n                    >\n                      <Plus className=\"size-3.5\" />\n                      <span>Save Note</span>\n                    </Button>\n                  </div>\n                </div>\n\n                {/* Saved Notes List */}\n                <div className=\"max-h-[500px] flex-1 space-y-2.5 overflow-y-auto p-3.5\">\n                  {notesList.map((note) => (\n                    <div\n                      key={note.id}\n                      className=\"group bg-card hover:border-border rounded-lg border p-3 text-xs shadow-xs transition-colors\"\n                    >\n                      <div className=\"mb-1.5 flex items-center justify-between\">\n                        <Button\n                          variant=\"outline\"\n                          size=\"sm\"\n                          className=\"text-primary h-5 gap-1 rounded px-1.5 font-mono text-xs font-bold tabular-nums\"\n                          onClick={() => seekTo(note.timestamp)}\n                        >\n                          <Play className=\"size-2.5 fill-current\" />\n                          <span>{formatTime(note.timestamp)}</span>\n                        </Button>\n\n                        <div className=\"flex items-center gap-1\">\n                          <span className=\"text-muted-foreground text-xs\">{note.createdAt}</span>\n                          <Button\n                            variant=\"ghost\"\n                            size=\"icon\"\n                            className=\"text-muted-foreground hover:text-destructive size-5 opacity-0 group-hover:opacity-100\"\n                            aria-label=\"Delete note\"\n                            onClick={() => handleDeleteNote(note.id)}\n                          >\n                            <Trash2 className=\"size-3\" />\n                          </Button>\n                        </div>\n                      </div>\n\n                      <p className=\"text-foreground leading-relaxed\">{note.text}</p>\n                    </div>\n                  ))}\n\n                  {notesList.length === 0 && (\n                    <div className=\"text-muted-foreground py-8 text-center text-xs\">\n                      No personal notes yet. Add your first note above!\n                    </div>\n                  )}\n                </div>\n              </TabsContent>\n\n              {/* TAB 3: Q&A Community Discussion */}\n              <TabsContent value=\"qa\" className=\"m-0 flex flex-1 flex-col focus-visible:outline-none\">\n                {/* Question Composer */}\n                <div className=\"bg-muted/20 space-y-2 border-b p-3\">\n                  <div className=\"flex items-center justify-between\">\n                    <label className=\"text-foreground flex items-center gap-1.5 text-xs font-bold tracking-tight\">\n                      <MessageSquare className=\"text-primary size-3.5\" />\n                      <span>Ask Instructor at {formattedCurrentTime}</span>\n                    </label>\n                    <span className=\"text-muted-foreground font-mono text-xs\">Tagged to this video time</span>\n                  </div>\n\n                  <Input\n                    value={newQuestionText}\n                    onChange={(e) => setNewQuestionText(e.target.value)}\n                    placeholder=\"Ask a question about this topic...\"\n                    className=\"h-8 text-xs\"\n                    onKeyDown={(e) => {\n                      if (e.key === 'Enter') {\n                        handleAddQuestion()\n                      }\n                    }}\n                  />\n\n                  <div className=\"flex items-center justify-end\">\n                    <Button\n                      size=\"sm\"\n                      className=\"h-7 gap-1 px-3 text-xs font-semibold\"\n                      disabled={!newQuestionText.trim()}\n                      onClick={handleAddQuestion}\n                    >\n                      <span>Post Question</span>\n                    </Button>\n                  </div>\n                </div>\n\n                {/* Questions Thread List */}\n                <div className=\"max-h-[500px] flex-1 space-y-3 overflow-y-auto p-3.5\">\n                  {questionsList.map((q) => (\n                    <div key={q.id} className=\"bg-card space-y-2.5 rounded-lg border p-3 text-xs shadow-xs\">\n                      {/* Question Header */}\n                      <div className=\"flex items-center justify-between\">\n                        <div className=\"flex items-center gap-2\">\n                          <div className=\"bg-primary/10 text-primary flex size-6 items-center justify-center rounded-full text-xs font-bold\">\n                            {q.avatar}\n                          </div>\n                          <div>\n                            <span className=\"text-foreground font-semibold\">{q.author}</span>\n                            <Button\n                              variant=\"link\"\n                              size=\"sm\"\n                              className=\"text-muted-foreground ml-1.5 h-auto p-0 font-mono text-xs\"\n                              onClick={() => seekTo(q.timestamp)}\n                            >\n                              [{formatTime(q.timestamp)}]\n                            </Button>\n                          </div>\n                        </div>\n\n                        {/* Upvote Button */}\n                        <Button\n                          variant={q.hasUpvoted ? 'default' : 'outline'}\n                          size=\"sm\"\n                          className=\"h-6 gap-1 px-1.5 text-xs\"\n                          onClick={() => toggleUpvote(q.id)}\n                        >\n                          <ThumbsUp className=\"size-2.5\" />\n                          <span className=\"font-mono tabular-nums\">{q.upvotes}</span>\n                        </Button>\n                      </div>\n\n                      {/* Question Text */}\n                      <p className=\"text-foreground leading-relaxed\">{q.question}</p>\n\n                      {/* Instructor Answer if available */}\n                      {q.answer && (\n                        <div className=\"bg-muted/40 border-primary/20 space-y-1 rounded-md border p-2.5\">\n                          <div className=\"flex items-center gap-1.5\">\n                            <span className=\"text-foreground text-xs font-semibold\">{q.answer.author}</span>\n                            <Badge variant=\"default\" className=\"bg-success px-1 py-0 text-xs font-normal\">\n                              Instructor Verified\n                            </Badge>\n                          </div>\n                          <p className=\"text-muted-foreground text-xs leading-relaxed\">{q.answer.text}</p>\n                        </div>\n                      )}\n                    </div>\n                  ))}\n                </div>\n              </TabsContent>\n            </Tabs>\n          </Card>\n        </aside>\n      </div>\n    </div>\n  )\n}\n\nexport default LessonVideoPlayer\n",
      "type": "registry:block",
      "target": "~/components/blocks/LessonVideoPlayer.tsx"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/input.json",
    "https://uipkge.dev/r/react/progress.json",
    "https://uipkge.dev/r/react/separator.json",
    "https://uipkge.dev/r/react/tabs.json",
    "https://uipkge.dev/r/react/textarea.json"
  ],
  "description": "Online lecture video player with playback speed selector, interactive timestamped transcript, and note-taking drawer.",
  "categories": [
    "education",
    "app",
    "media"
  ]
}