diff --git a/app/Entities/Clip/BaseClip.php b/app/Entities/Clip/BaseClip.php
index 402bddd0d48d87f5c4e18dc15973421107c855cb..77d4c0dae2454a52175b2be3e8f13b9989f58348 100644
--- a/app/Entities/Clip/BaseClip.php
+++ b/app/Entities/Clip/BaseClip.php
@@ -12,6 +12,7 @@ namespace App\Entities\Clip;
 
 use App\Entities\Episode;
 use App\Entities\Media\Audio;
+use App\Entities\Media\BaseMedia;
 use App\Entities\Media\Video;
 use App\Entities\Podcast;
 use App\Models\EpisodeModel;
@@ -44,6 +45,11 @@ use Modules\Auth\Entities\User;
  */
 class BaseClip extends Entity
 {
+    /**
+     * @var BaseMedia
+     */
+    protected $media = null;
+
     /**
      * @var array<string, string>
      */
@@ -122,12 +128,16 @@ class BaseClip extends Entity
         return $this;
     }
 
-    public function getMedia(): Audio | Video
+    /**
+     * @noRector ReturnTypeDeclarationRector
+     */
+    public function getMedia(): Audio | Video | null
     {
         if ($this->media_id !== null && $this->media === null) {
             $this->media = (new MediaModel($this->type))->getMediaById($this->media_id);
         }
 
+        // @phpstan-ignore-next-line
         return $this->media;
     }
 }
diff --git a/app/Entities/Clip/VideoClip.php b/app/Entities/Clip/VideoClip.php
index 0e5fa5a2861e9d760c70a31bfa9f9c0d1e0cfc98..0cbf9b9d27df4e371b28bb61db75b989e55f2de1 100644
--- a/app/Entities/Clip/VideoClip.php
+++ b/app/Entities/Clip/VideoClip.php
@@ -69,7 +69,8 @@ class VideoClip extends BaseClip
             return $this;
         }
 
-        $file = new File($filePath);
+        helper('media');
+        $file = new File(media_path($filePath));
 
         $video = new Video([
             'file_path' => $filePath,
diff --git a/app/Libraries/MediaClipper/VideoClipper.php b/app/Libraries/MediaClipper/VideoClipper.php
index 9614c6f1b4e5e1ee74b910e41e5911d8f7e89203..6fd9b541771b639ee16e7714e8eb35c36ef7c354 100644
--- a/app/Libraries/MediaClipper/VideoClipper.php
+++ b/app/Libraries/MediaClipper/VideoClipper.php
@@ -35,7 +35,9 @@ class VideoClipper
 
     public bool $error = false;
 
-    public string $videoClipOutput;
+    public string $videoClipFilePath;
+
+    protected string $videoClipOutput;
 
     protected float $duration;
 
@@ -95,6 +97,7 @@ class VideoClipper
         $this->subtitlesClipOutput = $podcastFolder . "/{$this->episode->slug}-subtitles-clip-{$this->start}-to-{$this->end}.srt";
         $this->videoClipBgOutput = $podcastFolder . "/{$this->episode->slug}-clip-bg-{$this->format}-{$this->theme}.png";
         $this->videoClipOutput = $podcastFolder . "/{$this->episode->slug}-clip-{$this->start}-to-{$this->end}-{$this->format}-{$this->theme}.mp4";
+        $this->videoClipFilePath = "podcasts/{$this->episode->podcast->handle}/{$this->episode->slug}-clip-{$this->start}-to-{$this->end}-{$this->format}-{$this->theme}.mp4";
     }
 
     public function soundbite(): void
@@ -152,6 +155,7 @@ class VideoClipper
             "color=0x{$this->colors['watermarkBg']}:{$this->dimensions['watermark']['width']}x{$this->dimensions['watermark']['height']}[over]",
             '[over][watermark]overlay=x=0:y=0:shortest=1[watermark_box]',
             "[outv][watermark_box]overlay=x={$this->dimensions['watermark']['x']}:y={$this->dimensions['watermark']['y']}:shortest=1[watermarked]",
+            '[watermarked]scale=w=-1:h=-1:out_color_matrix=bt709[outfinal]',
         ];
 
         $watermark = config('MediaClipper')
@@ -167,10 +171,10 @@ class VideoClipper
             "-f lavfi -i color=white:{$this->dimensions['width']}x{$this->dimensions['height']}",
             "-loop 1 -framerate 1 -i {$watermark}",
             '-filter_complex "' . implode(';', $filters) . '"',
-            '-map "[watermarked]"',
+            '-map "[outfinal]"',
             '-map 0:a',
             '-acodec copy',
-            '-vcodec libx264rgb',
+            '-vcodec libx264 -pix_fmt yuv420p',
             "{$this->videoClipOutput}",
         ];
 
diff --git a/app/Models/ClipModel.php b/app/Models/ClipModel.php
index 93cd2fb29a629a9805d403739210121a5a8cd2be..e61e6fc5f4dbd380d86b0c4d9a677243f2476517 100644
--- a/app/Models/ClipModel.php
+++ b/app/Models/ClipModel.php
@@ -114,6 +114,26 @@ class ClipModel extends Model
         return $found;
     }
 
+    public function getVideoClipById(int $videoClipId): ?VideoClip
+    {
+        $cacheName = "video-clip#{$videoClipId}";
+        if (! ($found = cache($cacheName))) {
+            $clip = $this->find($videoClipId);
+
+            if ($clip === null) {
+                return null;
+            }
+
+            // @phpstan-ignore-next-line
+            $found = new VideoClip($clip->toArray());
+
+            cache()
+                ->save($cacheName, $found, DECADE);
+        }
+
+        return $found;
+    }
+
     /**
      * Gets all video clips for an episode
      *
diff --git a/app/Views/Components/Alert.php b/app/Views/Components/Alert.php
index 7f6b9cbfad519a3947983f3de23b761026570959..41cf3bc51faf9122637914fa9e8bc9f651d0a5f2 100644
--- a/app/Views/Components/Alert.php
+++ b/app/Views/Components/Alert.php
@@ -21,7 +21,7 @@ class Alert extends Component
     {
         $variantClasses = [
             'default' => 'text-gray-800 bg-gray-100 border-gray-300',
-            'success' => 'text-pine-900 bg-pine-100 border-castopod-300',
+            'success' => 'text-pine-900 bg-pine-100 border-pine-300',
             'danger' => 'text-red-900 bg-red-100 border-red-300',
             'warning' => 'text-yellow-900 bg-yellow-100 border-yellow-300',
         ];
diff --git a/app/Views/Components/Pill.php b/app/Views/Components/Pill.php
index ead392253538a70685a0935254cda64354d19b24..b5927e658e62f6f9c5e07984eaad36375b5eeaec 100644
--- a/app/Views/Components/Pill.php
+++ b/app/Views/Components/Pill.php
@@ -22,7 +22,7 @@ class Pill extends Component
         $variantClasses = [
             'default' => 'text-gray-800 bg-gray-100 border-gray-300',
             'primary' => 'text-accent-contrast bg-accent-base border-accent-base',
-            'success' => 'text-pine-900 bg-pine-100 border-castopod-300',
+            'success' => 'text-pine-900 bg-pine-100 border-pine-300',
             'danger' => 'text-red-900 bg-red-100 border-red-300',
             'warning' => 'text-yellow-900 bg-yellow-100 border-yellow-300',
         ];
@@ -30,7 +30,7 @@ class Pill extends Component
         $icon = $this->icon ? icon($this->icon) : '';
 
         return <<<HTML
-            <span class="inline-flex items-center gap-x-1 px-1 font-semibold border rounded {$variantClasses[$this->variant]}">{$icon}{$this->slot}</span>
+            <span class="inline-flex items-center gap-x-1 px-1 font-semibold text-sm border rounded {$variantClasses[$this->variant]}">{$icon}{$this->slot}</span>
         HTML;
     }
 }
diff --git a/modules/Admin/Config/Routes.php b/modules/Admin/Config/Routes.php
index 66bb739b8071be924a2583181ac82fd773124489..b32a81748d399143c6f7869ac71013e62e62d292 100644
--- a/modules/Admin/Config/Routes.php
+++ b/modules/Admin/Config/Routes.php
@@ -379,6 +379,14 @@ $routes->group(
                                 'filter' => 'permission:podcast_episodes-edit',
                             ],
                         );
+                        $routes->get(
+                            'video-clips/(:num)',
+                            'VideoClipsController::view/$1/$2/$3',
+                            [
+                                'as' => 'video-clip',
+                                'filter' => 'permission:podcast_episodes-edit',
+                            ],
+                        );
                         $routes->get(
                             'embed',
                             'EpisodeController::embed/$1/$2',
diff --git a/modules/Admin/Controllers/SchedulerController.php b/modules/Admin/Controllers/SchedulerController.php
index 7ff4d0d3a90419976ad29d27a1bb89cff07daf9a..043451798558493c0ac2e4e59b80615c9702cb2b 100644
--- a/modules/Admin/Controllers/SchedulerController.php
+++ b/modules/Admin/Controllers/SchedulerController.php
@@ -53,7 +53,7 @@ class SchedulerController extends Controller
 
             if ($exitCode === 0) {
                 // success, video was generated
-                $scheduledClip->setMedia($clipper->videoClipOutput);
+                $scheduledClip->setMedia($clipper->videoClipFilePath);
                 (new ClipModel())->update($scheduledClip->id, [
                     'media_id' => $scheduledClip->media_id,
                     'status' => 'passed',
diff --git a/modules/Admin/Controllers/VideoClipsController.php b/modules/Admin/Controllers/VideoClipsController.php
index 4c70f72cfe2c4b2b68a22a0762eb73f1950ea160..f75849bdea7a232a20e4aac9703df99ffcd4cbe2 100644
--- a/modules/Admin/Controllers/VideoClipsController.php
+++ b/modules/Admin/Controllers/VideoClipsController.php
@@ -87,6 +87,24 @@ class VideoClipsController extends BaseController
         return view('episode/video_clips_list', $data);
     }
 
+    public function view($videoClipId): string
+    {
+        $videoClip = (new ClipModel())->getVideoClipById((int) $videoClipId);
+
+        $data = [
+            'podcast' => $this->podcast,
+            'episode' => $this->episode,
+            'videoClip' => $videoClip,
+        ];
+
+        replace_breadcrumb_params([
+            0 => $this->podcast->title,
+            1 => $this->episode->title,
+            2 => $videoClip->label,
+        ]);
+        return view('episode/video_clip', $data);
+    }
+
     public function generate(): string
     {
         helper('form');
diff --git a/themes/cp_admin/episode/video_clip.php b/themes/cp_admin/episode/video_clip.php
new file mode 100644
index 0000000000000000000000000000000000000000..dad7a8ce7569cd9cd32cec79c94aaab85b004f1c
--- /dev/null
+++ b/themes/cp_admin/episode/video_clip.php
@@ -0,0 +1,31 @@
+<?= $this->extend('_layout') ?>
+
+<?= $this->section('title') ?>
+<?= lang('Episode.video_clips.title', [
+    'videoClipLabel' => $videoClip->label,
+]) ?>
+<?= $this->endSection() ?>
+
+<?= $this->section('pageTitle') ?>
+<?= lang('Episode.video_clips.title', [
+    'videoClipLabel' => $videoClip->label,
+]) ?>
+<?= $this->endSection() ?>
+
+<?= $this->section('content') ?>
+
+<?php if ($videoClip->media): ?>
+    <video controls class="bg-black h-80 aspect-video">
+    <source src="<?= $videoClip->media->file_url ?>" type="<?= $videoClip->media->file_mimetype ?>">
+    Your browser does not support the video tag.
+    </video>
+<?php endif; ?>
+
+<?php if ($videoClip->logs): ?>
+<details class="w-full mt-8 overflow-hidden text-white bg-black border rounded shadow-sm">
+    <summary class="px-4 py-2 font-semibold text-black bg-white"><?= lang('VideoClip.logs') ?></summary>
+    <pre class="p-4 text-sm whitespace-pre-wrap"><?= $videoClip->logs ?></pre>
+</details>
+<?php endif; ?>
+
+<?= $this->endSection() ?>
diff --git a/themes/cp_admin/episode/video_clips_list.php b/themes/cp_admin/episode/video_clips_list.php
index 75a98bb513bd1777d7f2da1ad66fc5748ff665cd..71a5d0f65d782678c34059b6959a4b4b8d280e1f 100644
--- a/themes/cp_admin/episode/video_clips_list.php
+++ b/themes/cp_admin/episode/video_clips_list.php
@@ -39,17 +39,17 @@
             'header' => lang('VideoClip.list.label'),
             'cell' => function ($videoClip): string {
                 $formatClass = [
-                    'landscape' => 'aspect-video h-4',
-                    'portrait' => 'aspect-[9/16] w-4',
-                    'squared' => 'aspect-square h-6',
+                    'landscape' => 'aspect-video',
+                    'portrait' => 'aspect-[9/16]',
+                    'squared' => 'aspect-square',
                 ];
-                return '<a href="#" class="inline-flex items-center w-full hover:underline gap-x-2"><span class="block w-3 h-3 rounded-full" data-tooltip="bottom" title="' . $videoClip->theme['name'] . '" style="background-color:hsl(' . $videoClip->theme['preview'] . ')"></span><span class="flex items-center justify-center text-white bg-gray-400 rounded-sm ' . $formatClass[$videoClip->format] . '" data-tooltip="bottom" title="' . $videoClip->format . '"><Icon glyph="play"/></span>' . $videoClip->label . '</a>';
+                return '<a href="' . route_to('video-clip', $videoClip->podcast_id, $videoClip->episode_id, $videoClip->id) . '" class="inline-flex items-center font-semibold hover:underline gap-x-2 focus:ring-accent"><div class="relative"><span class="absolute block w-3 h-3 rounded-full -bottom-1 -left-1" data-tooltip="bottom" title="' . $videoClip->theme['name'] . '" style="background-color:hsl(' . $videoClip->theme['preview'] . ')"></span><div class="flex items-center justify-center h-6 overflow-hidden bg-black rounded-sm aspect-video" data-tooltip="bottom" title="' . $videoClip->format . '"><span class="flex items-center justify-center h-full text-white bg-gray-400 ' . $formatClass[$videoClip->format] . '"><Icon glyph="play"/></span></div></div>' . $videoClip->label . '</a>';
             },
         ],
         [
             'header' => lang('VideoClip.list.clip_id'),
             'cell' => function ($videoClip): string {
-                return '#' . $videoClip->id . ' by ' . $videoClip->user->username;
+                return '<a href="' . route_to('video-clip', $videoClip->podcast_id, $videoClip->episode_id, $videoClip->id) . '" class="font-semibold hover:underline focus:ring-accent">#' . $videoClip->id . '</a><span class="ml-1 text-sm">by ' . $videoClip->user->username . '</span>';
             },
         ],
         [