diff --git a/app/Config/Routes.php b/app/Config/Routes.php
index 88d4be2e1e0434c20b31846c5f72ac2573f5e743..e59d33895f542ad5102cdaf289d785b892f0b9a4 100644
--- a/app/Config/Routes.php
+++ b/app/Config/Routes.php
@@ -771,12 +771,24 @@ $routes->group('@(:podcastHandle)', function ($routes): void {
                 'controller-method' => 'EpisodeController::comments/$1/$2',
             ],
         ]);
-        $routes->get('comments/(:uuid)', 'EpisodeController::comment/$1/$2/$3', [
+        $routes->get('comments/(:uuid)', 'EpisodeCommentController::view/$1/$2/$3', [
             'as' => 'comment',
+            'application/activity+json' => [
+                'controller-method' => 'EpisodeController::commentObject/$1/$2',
+            ],
+            'application/podcast-activity+json' => [
+                'controller-method' => 'EpisodeController::commentObject/$1/$2',
+            ],
+            'application/ld+json; profile="https://www.w3.org/ns/activitystreams' => [
+                'controller-method' => 'EpisodeController::commentObject/$1/$2',
+            ],
         ]);
-        $routes->get('comments/(:uuid)/replies', 'EpisodeController::commentReplies/$1/$2/$3', [
+        $routes->get('comments/(:uuid)/replies', 'EpisodeCommentController::replies/$1/$2/$3', [
             'as' => 'comment-replies',
         ]);
+        $routes->post('comments/(:uuid)/like', 'EpisodeCommentController::attemptLike/$1/$2/$3', [
+            'as' => 'comment-attempt-like',
+        ]);
         $routes->get('oembed.json', 'EpisodeController::oembedJSON/$1/$2', [
             'as' => 'episode-oembed-json',
         ]);
diff --git a/app/Controllers/Admin/EpisodeController.php b/app/Controllers/Admin/EpisodeController.php
index fea2490da04c44f62c9ce49afbf49961845244ca..665c8007c530b1774325c116d4b59af2d5735441 100644
--- a/app/Controllers/Admin/EpisodeController.php
+++ b/app/Controllers/Admin/EpisodeController.php
@@ -10,13 +10,13 @@ declare(strict_types=1);
 
 namespace App\Controllers\Admin;
 
-use App\Entities\Comment;
 use App\Entities\Episode;
+use App\Entities\EpisodeComment;
 use App\Entities\Image;
 use App\Entities\Location;
 use App\Entities\Podcast;
 use App\Entities\Post;
-use App\Models\CommentModel;
+use App\Models\EpisodeCommentModel;
 use App\Models\EpisodeModel;
 use App\Models\PodcastModel;
 use App\Models\PostModel;
@@ -800,7 +800,7 @@ class EpisodeController extends BaseController
 
         $message = $this->request->getPost('message');
 
-        $newComment = new Comment([
+        $newComment = new EpisodeComment([
             'actor_id' => interact_as_actor_id(),
             'episode_id' => $this->episode->id,
             'message' => $message,
@@ -808,7 +808,7 @@ class EpisodeController extends BaseController
             'created_by' => user_id(),
         ]);
 
-        $commentModel = new CommentModel();
+        $commentModel = new EpisodeCommentModel();
         if (
             ! $commentModel->addComment($newComment, true)
         ) {
diff --git a/app/Controllers/EpisodeCommentController.php b/app/Controllers/EpisodeCommentController.php
new file mode 100644
index 0000000000000000000000000000000000000000..4f503d39e1bf68df993df23a7d81e71765c5783e
--- /dev/null
+++ b/app/Controllers/EpisodeCommentController.php
@@ -0,0 +1,173 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Podlibre
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+namespace App\Controllers;
+
+use ActivityPub\Entities\Actor;
+use ActivityPub\Objects\OrderedCollectionObject;
+use ActivityPub\Objects\OrderedCollectionPage;
+use Analytics\AnalyticsTrait;
+use App\Controllers\Admin\BaseController;
+use App\Entities\Episode;
+use App\Entities\EpisodeComment;
+use App\Entities\Podcast;
+use App\Libraries\CommentObject;
+use App\Models\EpisodeCommentModel;
+use App\Models\EpisodeModel;
+use App\Models\PodcastModel;
+use CodeIgniter\Exceptions\PageNotFoundException;
+use CodeIgniter\HTTP\RedirectResponse;
+use CodeIgniter\HTTP\Response;
+
+class EpisodeCommentController extends BaseController
+{
+    use AnalyticsTrait;
+
+    protected Podcast $podcast;
+
+    protected Actor $actor;
+
+    protected Episode $episode;
+
+    protected EpisodeComment $comment;
+
+    public function _remap(string $method, string ...$params): mixed
+    {
+        if (count($params) < 3) {
+            throw PageNotFoundException::forPageNotFound();
+        }
+
+        if (
+            ($podcast = (new PodcastModel())->getPodcastByHandle($params[0])) === null
+        ) {
+            throw PageNotFoundException::forPageNotFound();
+        }
+
+        $this->podcast = $podcast;
+        $this->actor = $podcast->actor;
+
+        if (
+            ($episode = (new EpisodeModel())->getEpisodeBySlug($params[0], $params[1])) === null
+            ) {
+            throw PageNotFoundException::forPageNotFound();
+        }
+
+        $this->episode = $episode;
+
+        if (
+            ($comment = (new EpisodeCommentModel())->getCommentById($params[2])) === null
+        ) {
+            throw PageNotFoundException::forPageNotFound();
+        }
+
+        $this->comment = $comment;
+
+        unset($params[2]);
+        unset($params[1]);
+        unset($params[0]);
+
+        return $this->{$method}(...$params);
+    }
+
+    public function view(): string
+    {
+        // Prevent analytics hit when authenticated
+        if (! can_user_interact()) {
+            $this->registerPodcastWebpageHit($this->podcast->id);
+        }
+
+        $cacheName = implode(
+            '_',
+            array_filter([
+                'page',
+                "comment#{$this->comment->id}",
+                service('request')
+                    ->getLocale(),
+                can_user_interact() ? '_authenticated' : null,
+            ]),
+        );
+
+        if (! ($cachedView = cache($cacheName))) {
+            $data = [
+                'podcast' => $this->podcast,
+                'actor' => $this->actor,
+                'episode' => $this->episode,
+                'comment' => $this->comment,
+            ];
+
+            // if user is logged in then send to the authenticated activity view
+            if (can_user_interact()) {
+                helper('form');
+                return view('podcast/comment_authenticated', $data);
+            }
+            return view('podcast/comment', $data, [
+                'cache' => DECADE,
+                'cache_name' => $cacheName,
+            ]);
+        }
+
+        return $cachedView;
+    }
+
+    /**
+     * @noRector ReturnTypeDeclarationRector
+     */
+    public function commentObject(): Response
+    {
+        $commentObject = new CommentObject($this->comment);
+
+        return $this->response
+            ->setContentType('application/json')
+            ->setBody($commentObject->toJSON());
+    }
+
+    public function replies(): Response
+    {
+        /**
+         * get comment replies
+         */
+        $commentReplies = model('CommentModel', false)
+            ->where('in_reply_to_id', service('uuid')->fromString($this->comment->id)->getBytes())
+            ->orderBy('created_at', 'ASC');
+
+        $pageNumber = (int) $this->request->getGet('page');
+
+        if ($pageNumber < 1) {
+            $commentReplies->paginate(12);
+            $pager = $commentReplies->pager;
+            $collection = new OrderedCollectionObject(null, $pager);
+        } else {
+            $paginatedReplies = $commentReplies->paginate(12, 'default', $pageNumber);
+            $pager = $commentReplies->pager;
+
+            $orderedItems = [];
+            if ($paginatedReplies !== null) {
+                foreach ($paginatedReplies as $reply) {
+                    $replyObject = new CommentObject($reply);
+                    $orderedItems[] = $replyObject;
+                }
+            }
+
+            $collection = new OrderedCollectionPage($pager, $orderedItems);
+        }
+
+        return $this->response
+            ->setContentType('application/activity+json')
+            ->setBody($collection->toJSON());
+    }
+
+    public function attemptLike(): RedirectResponse
+    {
+        model('LikeModel')
+            ->toggleLike(interact_as_actor(), $this->comment);
+
+        return redirect()->back();
+    }
+}
diff --git a/app/Controllers/EpisodeController.php b/app/Controllers/EpisodeController.php
index 4e44af57446d372f7b67008af797fa746add336f..c721fb6fb78a3ec153de40e005c68ab73a4f970e 100644
--- a/app/Controllers/EpisodeController.php
+++ b/app/Controllers/EpisodeController.php
@@ -15,10 +15,8 @@ use ActivityPub\Objects\OrderedCollectionPage;
 use Analytics\AnalyticsTrait;
 use App\Entities\Episode;
 use App\Entities\Podcast;
-use App\Libraries\CommentObject;
 use App\Libraries\NoteObject;
 use App\Libraries\PodcastEpisode;
-use App\Models\CommentModel;
 use App\Models\EpisodeModel;
 use App\Models\PodcastModel;
 use CodeIgniter\Database\BaseBuilder;
@@ -256,57 +254,4 @@ class EpisodeController extends BaseController
             ->setHeader('Access-Control-Allow-Origin', '*')
             ->setBody($collection->toJSON());
     }
-
-    /**
-     * @noRector ReturnTypeDeclarationRector
-     */
-    public function comment(string $commentId): Response
-    {
-        if (
-            ($comment = (new CommentModel())->getCommentById($commentId)) === null
-        ) {
-            throw PageNotFoundException::forPageNotFound();
-        }
-
-        $commentObject = new CommentObject($comment);
-
-        return $this->response
-            ->setContentType('application/json')
-            ->setBody($commentObject->toJSON());
-    }
-
-    public function commentReplies(string $commentId): Response
-    {
-        /**
-         * get comment replies
-         */
-        $commentReplies = model('CommentModel', false)
-            ->where('in_reply_to_id', service('uuid')->fromString($commentId)->getBytes())
-            ->orderBy('created_at', 'ASC');
-
-        $pageNumber = (int) $this->request->getGet('page');
-
-        if ($pageNumber < 1) {
-            $commentReplies->paginate(12);
-            $pager = $commentReplies->pager;
-            $collection = new OrderedCollectionObject(null, $pager);
-        } else {
-            $paginatedReplies = $commentReplies->paginate(12, 'default', $pageNumber);
-            $pager = $commentReplies->pager;
-
-            $orderedItems = [];
-            if ($paginatedReplies !== null) {
-                foreach ($paginatedReplies as $reply) {
-                    $replyObject = new CommentObject($reply);
-                    $orderedItems[] = $replyObject;
-                }
-            }
-
-            $collection = new OrderedCollectionPage($pager, $orderedItems);
-        }
-
-        return $this->response
-            ->setContentType('application/activity+json')
-            ->setBody($collection->toJSON());
-    }
 }
diff --git a/app/Database/Migrations/2021-08-12-150000_add_comments.php b/app/Database/Migrations/2021-08-12-150000_add_episode_comments.php
similarity index 79%
rename from app/Database/Migrations/2021-08-12-150000_add_comments.php
rename to app/Database/Migrations/2021-08-12-150000_add_episode_comments.php
index 612d9f63439f251b276ea4a65f374ba9a87f42c0..1524d45679f32bcd84e4149387e6fc861d6bc3e8 100644
--- a/app/Database/Migrations/2021-08-12-150000_add_comments.php
+++ b/app/Database/Migrations/2021-08-12-150000_add_episode_comments.php
@@ -3,9 +3,9 @@
 declare(strict_types=1);
 
 /**
- * Class AddComments creates comments table in database
+ * Class AddEpisodeComments creates episode_comments table in database
  *
- * @copyright  2020 Podlibre
+ * @copyright  2021 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
@@ -14,7 +14,7 @@ namespace App\Database\Migrations;
 
 use CodeIgniter\Database\Migration;
 
-class AddComments extends Migration
+class AddEpisodeComments extends Migration
 {
     public function up(): void
     {
@@ -42,22 +42,16 @@ class AddComments extends Migration
             ],
             'message' => [
                 'type' => 'VARCHAR',
-                'constraint' => 500,
-                'null' => true,
+                'constraint' => 5000,
             ],
             'message_html' => [
                 'type' => 'VARCHAR',
-                'constraint' => 600,
-                'null' => true,
+                'constraint' => 6000,
             ],
             'likes_count' => [
                 'type' => 'INT',
                 'unsigned' => true,
             ],
-            'dislikes_count' => [
-                'type' => 'INT',
-                'unsigned' => true,
-            ],
             'replies_count' => [
                 'type' => 'INT',
                 'unsigned' => true,
@@ -75,11 +69,11 @@ class AddComments extends Migration
         $this->forge->addForeignKey('episode_id', 'episodes', 'id', '', 'CASCADE');
         $this->forge->addForeignKey('actor_id', 'activitypub_actors', 'id', '', 'CASCADE');
         $this->forge->addForeignKey('created_by', 'users', 'id');
-        $this->forge->createTable('comments');
+        $this->forge->createTable('episode_comments');
     }
 
     public function down(): void
     {
-        $this->forge->dropTable('comments');
+        $this->forge->dropTable('episode_comments');
     }
 }
diff --git a/app/Database/Migrations/2021-08-12-160000_add_likes.php b/app/Database/Migrations/2021-08-12-160000_add_likes.php
new file mode 100644
index 0000000000000000000000000000000000000000..a32dc75ef831e4698590d4dc03f0364b120c0725
--- /dev/null
+++ b/app/Database/Migrations/2021-08-12-160000_add_likes.php
@@ -0,0 +1,42 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * Class AddLikes Creates likes table in database
+ *
+ * @copyright  2021 Podlibre
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+namespace ActivityPub\Database\Migrations;
+
+use CodeIgniter\Database\Migration;
+
+class AddLikes extends Migration
+{
+    public function up(): void
+    {
+        $this->forge->addField([
+            'actor_id' => [
+                'type' => 'INT',
+                'unsigned' => true,
+            ],
+            'comment_id' => [
+                'type' => 'BINARY',
+                'constraint' => 16,
+            ],
+        ]);
+        $this->forge->addField('`created_at` timestamp NOT NULL DEFAULT current_timestamp()');
+        $this->forge->addPrimaryKey(['actor_id', 'comment_id']);
+        $this->forge->addForeignKey('actor_id', 'activitypub_actors', 'id', '', 'CASCADE');
+        $this->forge->addForeignKey('comment_id', 'episode_comments', 'id', '', 'CASCADE');
+        $this->forge->createTable('likes');
+    }
+
+    public function down(): void
+    {
+        $this->forge->dropTable('likes');
+    }
+}
diff --git a/app/Entities/Episode.php b/app/Entities/Episode.php
index 7b976a2ec4982d42967cb100ac5fb8a68aa437f7..c01219dd8d6aeac9ccafc7b1390c3a4034d233ac 100644
--- a/app/Entities/Episode.php
+++ b/app/Entities/Episode.php
@@ -11,7 +11,7 @@ declare(strict_types=1);
 namespace App\Entities;
 
 use App\Libraries\SimpleRSSElement;
-use App\Models\CommentModel;
+use App\Models\EpisodeCommentModel;
 use App\Models\PersonModel;
 use App\Models\PodcastModel;
 use App\Models\PostModel;
@@ -122,7 +122,7 @@ class Episode extends Entity
     protected ?array $posts = null;
 
     /**
-     * @var Comment[]|null
+     * @var EpisodeComment[]|null
      */
     protected ?array $comments = null;
 
@@ -402,7 +402,7 @@ class Episode extends Entity
     }
 
     /**
-     * @return Comment[]
+     * @return EpisodeComment[]
      */
     public function getComments(): array
     {
@@ -411,7 +411,7 @@ class Episode extends Entity
         }
 
         if ($this->comments === null) {
-            $this->comments = (new CommentModel())->getEpisodeComments($this->id);
+            $this->comments = (new EpisodeCommentModel())->getEpisodeComments($this->id);
         }
 
         return $this->comments;
diff --git a/app/Entities/Comment.php b/app/Entities/EpisodeComment.php
similarity index 77%
rename from app/Entities/Comment.php
rename to app/Entities/EpisodeComment.php
index 6235802f8fed5b6cce13b6ac9b1dc90424cdbb79..db2622c1f7d17e5c98495072b7ebbae2921af30a 100644
--- a/app/Entities/Comment.php
+++ b/app/Entities/EpisodeComment.php
@@ -10,6 +10,7 @@ declare(strict_types=1);
 
 namespace App\Entities;
 
+use App\Models\EpisodeCommentModel;
 use App\Models\EpisodeModel;
 use CodeIgniter\I18n\Time;
 use Michalsn\Uuid\UuidEntity;
@@ -23,22 +24,28 @@ use RuntimeException;
  * @property int $actor_id
  * @property Actor|null $actor
  * @property string $in_reply_to_id
- * @property Comment|null $reply_to_comment
+ * @property EpisodeComment|null $reply_to_comment
  * @property string $message
  * @property string $message_html
  * @property int $likes_count
- * @property int $dislikes_count
  * @property int $replies_count
  * @property Time $created_at
  * @property int $created_by
+ *
+ * @property EpisodeComment[] $replies
  */
-class Comment extends UuidEntity
+class EpisodeComment extends UuidEntity
 {
     protected ?Episode $episode = null;
 
     protected ?Actor $actor = null;
 
-    protected ?Comment $reply_to_comment = null;
+    protected ?EpisodeComment $reply_to_comment = null;
+
+    /**
+     * @var EpisodeComment[]|null
+     */
+    protected ?array $replies = null;
 
     /**
      * @var string[]
@@ -57,7 +64,6 @@ class Comment extends UuidEntity
         'message' => 'string',
         'message_html' => 'string',
         'likes_count' => 'integer',
-        'dislikes_count' => 'integer',
         'replies_count' => 'integer',
         'created_by' => 'integer',
         'is_from_post' => 'boolean',
@@ -96,6 +102,22 @@ class Comment extends UuidEntity
         return $this->actor;
     }
 
+    /**
+     * @return EpisodeComment[]
+     */
+    public function getReplies(): array
+    {
+        if ($this->id === null) {
+            throw new RuntimeException('Comment must be created before getting replies.');
+        }
+
+        if ($this->replies === null) {
+            $this->replies = (new EpisodeCommentModel())->getCommentReplies($this->id);
+        }
+
+        return $this->replies;
+    }
+
     public function setMessage(string $message): static
     {
         helper('activitypub');
diff --git a/app/Entities/Like.php b/app/Entities/Like.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab9f3893f77af168dda05563c111d7f572fc98b2
--- /dev/null
+++ b/app/Entities/Like.php
@@ -0,0 +1,33 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2021 Podlibre
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+namespace App\Entities;
+
+use Michalsn\Uuid\UuidEntity;
+
+/**
+ * @property int $actor_id
+ * @property string $comment_id
+ */
+class Like extends UuidEntity
+{
+    /**
+     * @var string[]
+     */
+    protected $uuids = ['comment_id'];
+
+    /**
+     * @var array<string, string>
+     */
+    protected $casts = [
+        'actor_id' => 'integer',
+        'comment_id' => 'string',
+    ];
+}
diff --git a/app/Language/en/Comment.php b/app/Language/en/Comment.php
index 7073865a09c5f8f42c901e02af2f802141be29f9..d3677dc7d2ca3e75bd8ed2ccbd508c4403f7eafe 100644
--- a/app/Language/en/Comment.php
+++ b/app/Language/en/Comment.php
@@ -16,11 +16,8 @@ return [
         'submit_reply' => 'Reply',
     ],
     'like' => 'Like',
-    'dislike' => 'Dislike',
-    'replies' => '{numberOfReplies, plural,
-        one {# reply}
-        other {# replies}
-    }',
+    'reply' => 'Reply',
+    'view_replies' => 'View replies ({numberOfReplies})',
     'block_actor' => 'Block user @{actorUsername}',
     'block_domain' => 'Block domain @{actorDomain}',
     'delete' => 'Delete comment',
diff --git a/app/Language/fr/Comment.php b/app/Language/fr/Comment.php
new file mode 100644
index 0000000000000000000000000000000000000000..ce5fab4f288b4dea5a39337862a31e278632d4d1
--- /dev/null
+++ b/app/Language/fr/Comment.php
@@ -0,0 +1,27 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Podlibre
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'form' => [
+        'episode_message_placeholder' => 'Saisissez un commentaire...',
+        'reply_to_placeholder' => 'Répondre à @{actorUsername}',
+        'submit' => 'Envoyer !',
+        'submit_reply' => 'Répondre',
+    ],
+    'like' => 'J’aime',
+    'reply' => 'Répondre',
+    'replies' => '{numberOfReplies, plural,
+        one {# réponse}
+        other {# réponses}
+    }',
+    'block_actor' => 'Bloquer l’utilisateur @{actorUsername}',
+    'block_domain' => 'Bloquer le domaine @{actorDomain}',
+    'delete' => 'Supprimer le commentaire',
+];
diff --git a/app/Language/fr/Post.php b/app/Language/fr/Post.php
index a12bdd6f25608cd1f330a1399882ea787e4af13d..2981a4be9a34fd3b9311c4d2e3b69c03f777213f 100644
--- a/app/Language/fr/Post.php
+++ b/app/Language/fr/Post.php
@@ -19,7 +19,7 @@ return [
             'Écrivez votre message pour l’épisode...',
         'episode_url_placeholder' => 'URL de l’épisode',
         'reply_to_placeholder' => 'Répondre à @{actorUsername}',
-        'submit' => 'Envoyer!',
+        'submit' => 'Envoyer !',
         'submit_reply' => 'Répondre',
     ],
     'favourites' => '{numberOfFavourites, plural,
diff --git a/app/Libraries/ActivityPub/Models/FavouriteModel.php b/app/Libraries/ActivityPub/Models/FavouriteModel.php
index 3e22785bce1cf697331970e0f822eae71c457632..c0c4e9f1c251dac0828ab9e80d68b03d6add7575 100644
--- a/app/Libraries/ActivityPub/Models/FavouriteModel.php
+++ b/app/Libraries/ActivityPub/Models/FavouriteModel.php
@@ -100,14 +100,12 @@ class FavouriteModel extends UuidModel
             ->where('id', service('uuid') ->fromString($post->id) ->getBytes())
             ->decrement('favourites_count');
 
-        $this->db
-            ->table('activitypub_favourites')
-            ->where([
-                'actor_id' => $actor->id,
-                'post_id' => service('uuid')
-                    ->fromString($post->id)
-                    ->getBytes(),
-            ])
+        $this->where([
+            'actor_id' => $actor->id,
+            'post_id' => service('uuid')
+                ->fromString($post->id)
+                ->getBytes(),
+        ])
             ->delete();
 
         if ($registerActivity) {
@@ -161,7 +159,7 @@ class FavouriteModel extends UuidModel
     }
 
     /**
-     * Adds or removes favourite from database and increments count
+     * Adds or removes favourite from database
      */
     public function toggleFavourite(Actor $actor, Post $post): void
     {
diff --git a/app/Libraries/CommentObject.php b/app/Libraries/CommentObject.php
index d127bcc2d3662da3d3919af7c2076be5a24b1daa..0cbd39629dae5c1da0f019b8d02505b0eede8629 100644
--- a/app/Libraries/CommentObject.php
+++ b/app/Libraries/CommentObject.php
@@ -11,7 +11,7 @@ declare(strict_types=1);
 namespace App\Libraries;
 
 use ActivityPub\Core\ObjectType;
-use App\Entities\Comment;
+use App\Entities\EpisodeComment;
 
 class CommentObject extends ObjectType
 {
@@ -23,7 +23,7 @@ class CommentObject extends ObjectType
 
     protected string $replies;
 
-    public function __construct(Comment $comment)
+    public function __construct(EpisodeComment $comment)
     {
         $this->id = $comment->uri;
 
diff --git a/app/Models/CommentModel.php b/app/Models/EpisodeCommentModel.php
similarity index 81%
rename from app/Models/CommentModel.php
rename to app/Models/EpisodeCommentModel.php
index ba7215faf04079470277c2e586fb1ac523f13693..794dab0e6d3ab6875a0556d2958ca538efae7e4a 100644
--- a/app/Models/CommentModel.php
+++ b/app/Models/EpisodeCommentModel.php
@@ -11,22 +11,22 @@ declare(strict_types=1);
 namespace App\Models;
 
 use ActivityPub\Activities\CreateActivity;
-use App\Entities\Comment;
+use App\Entities\EpisodeComment;
 use App\Libraries\CommentObject;
 use CodeIgniter\Database\BaseBuilder;
 use Michalsn\Uuid\UuidModel;
 
-class CommentModel extends UuidModel
+class EpisodeCommentModel extends UuidModel
 {
     /**
      * @var string
      */
-    protected $returnType = Comment::class;
+    protected $returnType = EpisodeComment::class;
 
     /**
      * @var string
      */
-    protected $table = 'comments';
+    protected $table = 'episode_comments';
 
     /**
      * @var string[]
@@ -45,7 +45,6 @@ class CommentModel extends UuidModel
         'message',
         'message_html',
         'likes_count',
-        'dislikes_count',
         'replies_count',
         'created_at',
         'created_by',
@@ -56,7 +55,7 @@ class CommentModel extends UuidModel
      */
     protected $beforeInsert = ['setCommentId'];
 
-    public function getCommentById(string $commentId): ?Comment
+    public function getCommentById(string $commentId): ?EpisodeComment
     {
         $cacheName = "comment#{$commentId}";
         if (! ($found = cache($cacheName))) {
@@ -69,7 +68,7 @@ class CommentModel extends UuidModel
         return $found;
     }
 
-    public function addComment(Comment $comment, bool $registerActivity = false): string | false
+    public function addComment(EpisodeComment $comment, bool $registerActivity = false): string | false
     {
         $this->db->transStart();
         // increment Episode's comments_count
@@ -122,7 +121,9 @@ class CommentModel extends UuidModel
     /**
      * Retrieves all published posts for a given episode ordered by publication date
      *
-     * @return Comment[]
+     * @return EpisodeComment[]
+     *
+     * @noRector ReturnTypeDeclarationRector
      */
     public function getEpisodeComments(int $episodeId): array
     {
@@ -133,7 +134,7 @@ class CommentModel extends UuidModel
 
         $episodePostsReplies = $this->db->table('activitypub_posts')
             ->select(
-                'id, uri, episode_id, actor_id, in_reply_to_id, message, message_html, favourites_count as likes_count, 0 as dislikes_count, replies_count, published_at as created_at, created_by, 1 as is_from_post'
+                'id, uri, episode_id, actor_id, in_reply_to_id, message, message_html, favourites_count as likes_count, replies_count, published_at as created_at, created_by, 1 as is_from_post'
             )
             ->whereIn('in_reply_to_id', function (BaseBuilder $builder) use (&$episodeId): BaseBuilder {
                 return $builder->select('id')
@@ -147,18 +148,25 @@ class CommentModel extends UuidModel
             $episodeComments . ' UNION ' . $episodePostsReplies . ' ORDER BY created_at ASC'
         );
 
-        return $allEpisodeComments->getCustomResultObject($this->returnType);
+        // FIXME:?
+        // @phpstan-ignore-next-line
+        return $this->convertUuidFieldsToStrings(
+            $allEpisodeComments->getCustomResultObject($this->tempReturnType),
+            $this->tempReturnType
+        );
     }
 
     /**
      * Retrieves all replies for a given comment
      *
-     * @return Comment[]
+     * @return EpisodeComment[]
      */
-    public function getCommentReplies(int $episodeId, string $commentId): array
+    public function getCommentReplies(string $commentId): array
     {
         // TODO: get all replies for a given comment
-        return $this->findAll();
+        return $this->where('in_reply_to_id', $this->uuid->fromString($commentId)->getBytes())
+            ->orderBy('created_at', 'ASC')
+            ->findAll();
     }
 
     /**
diff --git a/app/Models/LikeModel.php b/app/Models/LikeModel.php
new file mode 100644
index 0000000000000000000000000000000000000000..01d49d1bd725474e1f055eb4f5110758ce1da6bd
--- /dev/null
+++ b/app/Models/LikeModel.php
@@ -0,0 +1,165 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2021 Podlibre
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+namespace App\Models;
+
+use ActivityPub\Activities\LikeActivity;
+use ActivityPub\Activities\UndoActivity;
+use ActivityPub\Entities\Actor;
+use App\Entities\EpisodeComment;
+use App\Entities\Like;
+use Michalsn\Uuid\UuidModel;
+
+class LikeModel extends UuidModel
+{
+    /**
+     * @var string
+     */
+    protected $table = 'likes';
+
+    /**
+     * @var string[]
+     */
+    protected $uuidFields = ['comment_id'];
+
+    /**
+     * @var string[]
+     */
+    protected $allowedFields = ['actor_id', 'comment_id'];
+
+    /**
+     * @var string
+     */
+    protected $returnType = Like::class;
+
+    /**
+     * @var bool
+     */
+    protected $useTimestamps = true;
+
+    protected $updatedField;
+
+    public function addLike(Actor $actor, EpisodeComment $comment, bool $registerActivity = true): void
+    {
+        $this->db->transStart();
+
+        $this->insert([
+            'actor_id' => $actor->id,
+            'comment_id' => $comment->id,
+        ]);
+
+        (new EpisodeCommentModel())
+            ->where('id', service('uuid')->fromString($comment->id)->getBytes())
+            ->increment('likes_count');
+
+        if ($registerActivity) {
+            $likeActivity = new LikeActivity();
+            $likeActivity->set('actor', $actor->uri)
+                ->set('object', $comment->uri);
+
+            $activityId = model('ActivityModel')
+                ->newActivity(
+                    'Like',
+                    $actor->id,
+                    null,
+                    null,
+                    $likeActivity->toJSON(),
+                    $comment->created_at,
+                    'queued',
+                );
+
+            $likeActivity->set('id', url_to('activity', $actor->username, $activityId));
+
+            model('ActivityModel')
+                ->update($activityId, [
+                    'payload' => $likeActivity->toJSON(),
+                ]);
+        }
+
+        $this->db->transComplete();
+    }
+
+    public function removeLike(Actor $actor, EpisodeComment $comment, bool $registerActivity = true): void
+    {
+        $this->db->transStart();
+
+        (new EpisodeCommentModel())
+            ->where('id', service('uuid') ->fromString($comment->id) ->getBytes())
+            ->decrement('likes_count');
+
+        $this->where([
+            'actor_id' => $actor->id,
+            'comment_id' => service('uuid')
+                ->fromString($comment->id)
+                ->getBytes(),
+        ])
+            ->delete();
+
+        if ($registerActivity) {
+            $undoActivity = new UndoActivity();
+            // FIXME: get like activity associated with the deleted like
+            $activity = model('ActivityModel')
+                ->where([
+                    'type' => 'Like',
+                    'actor_id' => $actor->id,
+                ])
+                ->first();
+
+            $likeActivity = new LikeActivity();
+            $likeActivity
+                ->set('id', url_to('activity', $actor->username, $activity->id))
+                ->set('actor', $actor->uri)
+                ->set('object', $comment->uri);
+
+            $undoActivity
+                ->set('actor', $actor->uri)
+                ->set('object', $likeActivity);
+
+            $activityId = model('ActivityModel')
+                ->newActivity(
+                    'Undo',
+                    $actor->id,
+                    null,
+                    null,
+                    $undoActivity->toJSON(),
+                    $comment->created_at,
+                    'queued',
+                );
+
+            $undoActivity->set('id', url_to('activity', $actor->username, $activityId));
+
+            model('ActivityModel')
+                ->update($activityId, [
+                    'payload' => $undoActivity->toJSON(),
+                ]);
+        }
+
+        $this->db->transComplete();
+    }
+
+    /**
+     * Adds or removes likes from database
+     */
+    public function toggleLike(Actor $actor, EpisodeComment $comment): void
+    {
+        if (
+            $this->where([
+                'actor_id' => $actor->id,
+                'comment_id' => service('uuid')
+                    ->fromString($comment->id)
+                    ->getBytes(),
+            ])->first()
+        ) {
+            $this->removeLike($actor, $comment);
+        } else {
+            $this->addLike($actor, $comment);
+        }
+    }
+}
diff --git a/app/Resources/icons/thumb-down.svg b/app/Resources/icons/thumb-down.svg
deleted file mode 100644
index ff06be8ab1660324571b416b23b8c93a808ecd73..0000000000000000000000000000000000000000
--- a/app/Resources/icons/thumb-down.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
-    <g>
-        <path fill="none" d="M0 0h24v24H0z"/>
-        <path d="M22 15h-3V3h3a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1zm-5.293 1.293l-6.4 6.4a.5.5 0 0 1-.654.047L8.8 22.1a1.5 1.5 0 0 1-.553-1.57L9.4 16H3a2 2 0 0 1-2-2v-2.104a2 2 0 0 1 .15-.762L4.246 3.62A1 1 0 0 1 5.17 3H16a1 1 0 0 1 1 1v11.586a1 1 0 0 1-.293.707z"/>
-    </g>
-</svg>
diff --git a/app/Resources/icons/thumb-up.svg b/app/Resources/icons/thumb-up.svg
deleted file mode 100644
index f0d667027247a582b36b6cd825ad79e6d053d04d..0000000000000000000000000000000000000000
--- a/app/Resources/icons/thumb-up.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
-    <g>
-        <path fill="none" d="M0 0h24v24H0z"/>
-        <path d="M2 9h3v12H2a1 1 0 0 1-1-1V10a1 1 0 0 1 1-1zm5.293-1.293l6.4-6.4a.5.5 0 0 1 .654-.047l.853.64a1.5 1.5 0 0 1 .553 1.57L14.6 8H21a2 2 0 0 1 2 2v2.104a2 2 0 0 1-.15.762l-3.095 7.515a1 1 0 0 1-.925.619H8a1 1 0 0 1-1-1V8.414a1 1 0 0 1 .293-.707z"/>
-    </g>
-</svg>
diff --git a/app/Views/podcast/_partials/comment.php b/app/Views/podcast/_partials/comment.php
index 587df06942531685ba09fde1cd304c4b066fc2de..89ae77007117933dc66567aab740faaf23be509e 100644
--- a/app/Views/podcast/_partials/comment.php
+++ b/app/Views/podcast/_partials/comment.php
@@ -1,7 +1,7 @@
 <article class="relative z-10 flex w-full px-4 py-2 rounded-2xl">
     <img src="<?= $comment->actor->avatar_image_url ?>" alt="<?= $comment->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
     <div class="flex-1">
-        <header class="w-full mb-2">
+        <header class="w-full mb-2 text-sm">
             <a href="<?= $comment->actor
                 ->uri ?>" class="flex items-baseline hover:underline" <?= $comment->actor->is_local
                 ? ''
@@ -17,27 +17,10 @@
             </a>
         </header>
         <div class="mb-2 post-content"><?= $comment->message_html ?></div>
-        <div class="inline-flex gap-x-4">
-            <?= anchor_popup(
-                route_to('comment-remote-action', $podcast->handle, $episode->slug, $comment->id, 'like'),
-                icon('thumb-up', 'text-lg mr-1 text-gray-400 group-hover:text-gray-600') . 0,
-                [
-                    'class' => 'inline-flex items-center hover:underline group',
-                    'width' => 420,
-                    'height' => 620,
-                    'title' => lang('Comment.like'),
-                ],
-            ) ?>
-            <?= anchor_popup(
-                route_to('comment-remote-action', $podcast->handle, $episode->slug, $comment->id, 'dislike'),
-                icon('thumb-down', 'text-lg text-gray-400 group-hover:text-gray-600'),
-                [
-                    'class' => 'inline-flex items-center hover:underline group',
-                    'width' => 420,
-                    'height' => 620,
-                    'title' => lang('Comment.dislike'),
-                ],
-            ) ?>
-        </div>
+        <?php if ($comment->is_from_post): ?>
+            <?= $this->include('podcast/_partials/comment_actions_from_post') ?>
+        <?php else: ?>
+                <?= $this->include('podcast/_partials/comment_actions') ?>
+        <?php endif; ?>
     </div>
 </article>
diff --git a/app/Views/podcast/_partials/comment_actions.php b/app/Views/podcast/_partials/comment_actions.php
new file mode 100644
index 0000000000000000000000000000000000000000..cb92fda5b90e4bb8ec867d762f780aa009328498
--- /dev/null
+++ b/app/Views/podcast/_partials/comment_actions.php
@@ -0,0 +1,24 @@
+<footer>
+    <form action="<?= route_to('comment-attempt-like', interact_as_actor()->username, $episode->slug, $comment->id) ?>" method="POST" class="flex items-center gap-x-4">
+        <button type="submit" name="action" value="favourite" class="inline-flex items-center hover:underline group" title="<?= lang(
+            'Comment.like',
+            [
+                'numberOfLikes' => $comment->likes_count,
+            ],
+        ) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400 group-hover:text-red-600') . $comment->likes_count ?></button>
+        <?= button(
+            lang('Comment.reply'),
+            route_to('comment', $podcast->handle, $episode->slug, $comment->id),
+            [
+                'size' => 'small',
+            ],
+        ) ?>
+    </form>
+    <?php if($comment->replies_count): ?>
+        <?= anchor(
+            route_to('comment', $podcast->handle, $episode->slug, $comment->id),
+            icon('caret-down', 'text-xl mr-1') . lang('Comment.view_replies', ['numberOfReplies' => $comment->replies_count]),
+            ['class' => 'inline-flex items-center text-xs hover:underline']
+        ) ?>
+    <?php endif; ?>
+</footer>
\ No newline at end of file
diff --git a/app/Views/podcast/_partials/comment_actions_from_post.php b/app/Views/podcast/_partials/comment_actions_from_post.php
new file mode 100644
index 0000000000000000000000000000000000000000..de10aa3b6f9de1c03b73861ddc254b217a5f4933
--- /dev/null
+++ b/app/Views/podcast/_partials/comment_actions_from_post.php
@@ -0,0 +1,24 @@
+<footer>
+    <form action="<?= route_to('post-attempt-action', interact_as_actor()->username, $comment->id) ?>" method="POST" class="flex items-center gap-x-4">
+        <button type="submit" name="action" value="favourite" class="inline-flex items-center hover:underline group" title="<?= lang(
+            'Comment.like',
+            [
+                'numberOfLikes' => $comment->likes_count,
+            ],
+        ) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400 group-hover:text-red-600') . $comment->likes_count ?></button>
+        <?= button(
+            lang('Comment.reply'),
+            route_to('post', $podcast->handle, $comment->id),
+            [
+                'size' => 'small',
+            ],
+        ) ?>
+    </form>
+    <?php if($comment->replies_count): ?>
+        <?= anchor(
+            route_to('post', $podcast->handle, $comment->id),
+            icon('caret-down', 'text-xl mr-1') . lang('Comment.view_replies', ['numberOfReplies' => $comment->replies_count]),
+            ['class' => 'inline-flex items-center text-xs hover:underline']
+        ) ?>
+    <?php endif; ?>
+</footer>
\ No newline at end of file
diff --git a/app/Views/podcast/_partials/comment_authenticated.php b/app/Views/podcast/_partials/comment_authenticated.php
new file mode 100644
index 0000000000000000000000000000000000000000..75055677f368f61d3b1231d62652a17e7693783f
--- /dev/null
+++ b/app/Views/podcast/_partials/comment_authenticated.php
@@ -0,0 +1,27 @@
+<article class="relative z-10 w-full bg-white shadow-md rounded-2xl">
+    <header class="flex px-6 py-4">
+        <img src="<?= $comment->actor
+            ->avatar_image_url ?>" alt="<?= $comment->actor->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
+        <div class="flex flex-col min-w-0">
+            <a href="<?= $comment->actor
+                ->uri ?>" class="flex items-baseline hover:underline" <?= $comment
+    ->actor->is_local
+    ? ''
+    : 'target="_blank" rel="noopener noreferrer"' ?>>
+                <span class="mr-2 font-semibold truncate"><?= $comment->actor
+                    ->display_name ?></span>
+                <span class="text-sm text-gray-500 truncate">@<?= $comment->actor
+                    ->username .
+                    ($comment->actor->is_local
+                        ? ''
+                        : '@' . $comment->actor->domain) ?></span>
+            </a>
+            <a href="<?= route_to('comment', $podcast->handle, $episode->slug, $comment->id) ?>"
+            class="text-xs text-gray-500">
+                <?= relative_time($comment->created_at) ?>
+            </a>
+        </div>
+    </header>
+    <div class="px-6 mb-4 post-content"><?= $comment->message_html ?></div>
+    <?= $this->include('podcast/_partials/comment_actions') ?>
+</article>
diff --git a/app/Views/podcast/_partials/comment_with_replies.php b/app/Views/podcast/_partials/comment_with_replies.php
new file mode 100644
index 0000000000000000000000000000000000000000..fcd817d771ce3a642a3d8c7b7e34a70f85bfa483
--- /dev/null
+++ b/app/Views/podcast/_partials/comment_with_replies.php
@@ -0,0 +1,22 @@
+<?= $this->include('podcast/_partials/comment') ?>
+<div class="-mt-2 overflow-hidden border-b border-l border-r comment-replies rounded-b-xl">
+
+<div class="px-6 pt-8 pb-4 bg-gray-50">
+<?= anchor_popup(
+    route_to('comment-remote-action', $podcast->handle, $comment->id, 'reply'),
+    lang('comment.reply_to', ['actorUsername' => $comment->actor->username]),
+    [
+        'class' =>
+            'text-center justify-center font-semibold rounded-full shadow relative z-10 px-4 py-2 w-full bg-rose-600 text-white inline-flex items-center hover:bg-rose-700',
+        'width' => 420,
+        'height' => 620,
+    ],
+) ?>
+</div>
+
+
+<?php foreach ($comment->replies as $reply): ?>
+    <?= view('podcast/_partials/comment', ['comment' => $reply]) ?>
+<?php endforeach; ?>
+
+</div>
diff --git a/app/Views/podcast/_partials/comment_with_replies_authenticated.php b/app/Views/podcast/_partials/comment_with_replies_authenticated.php
new file mode 100644
index 0000000000000000000000000000000000000000..c74c07d4ef788f126c486d02793cfc18b141f8ff
--- /dev/null
+++ b/app/Views/podcast/_partials/comment_with_replies_authenticated.php
@@ -0,0 +1,47 @@
+<?= $this->include('podcast/_partials/comment_authenticated') ?>
+<div class="-mt-2 overflow-hidden border-b border-l border-r post-replies rounded-b-xl">
+<?= form_open(
+    route_to('comment-attempt-action', interact_as_actor()->username, $episode->slug, $comment->id),
+    [
+        'class' => 'bg-gray-50 flex px-6 pt-8 pb-4',
+    ],
+) ?>
+<img src="<?= interact_as_actor()
+    ->avatar_image_url ?>" alt="<?= interact_as_actor()
+    ->display_name ?>" class="w-12 h-12 mr-4 rounded-full ring-gray-50 ring-2" />
+<div class="flex flex-col flex-1">
+<?= form_textarea(
+    [
+        'id' => 'message',
+        'name' => 'message',
+        'class' => 'form-textarea mb-4 w-full',
+        'required' => 'required',
+        'placeholder' => lang('Comment.form.reply_to_placeholder', [
+            'actorUsername' => $comment->actor->username,
+        ]),
+    ],
+    old('message', '', false),
+    [
+        'rows' => 1,
+    ],
+) ?>
+<?= button(
+    lang('Comment.form.submit_reply'),
+    '',
+    ['variant' => 'primary', 'size' => 'small'],
+    [
+        'type' => 'submit',
+        'class' => 'self-end',
+        'name' => 'action',
+        'value' => 'reply',
+    ],
+) ?>
+</div>
+<?= form_close() ?>
+
+<?php foreach ($comment->replies as $reply): ?>
+    <?= view('podcast/_partials/comment_authenticated', [
+        'comment' => $reply,
+    ]) ?>
+<?php endforeach; ?>
+</div>
diff --git a/app/Views/podcast/_partials/post.php b/app/Views/podcast/_partials/post.php
index 7ca262668c9135d3736cd14fcfd8d9cf8fdee0cd..0b04004c938b19fb43af521a8e20fe5f2e393799 100644
--- a/app/Views/podcast/_partials/post.php
+++ b/app/Views/podcast/_partials/post.php
@@ -1,7 +1,7 @@
 <article class="relative z-10 w-full bg-white shadow rounded-2xl">
     <header class="flex px-6 py-4">
         <img src="<?= $post->actor
-            ->avatar_image_url ?>" alt="<?= $post->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
+            ->avatar_image_url ?>" alt="<?= $post->actor->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
         <div class="flex flex-col min-w-0">
             <a href="<?= $post->actor
                 ->uri ?>" class="flex items-baseline hover:underline" <?= $post
diff --git a/app/Views/podcast/_partials/post_authenticated.php b/app/Views/podcast/_partials/post_authenticated.php
index 1ec49dedef1710da6feafb1240908283bbc484e0..bb4ac6b4a02fc3a8debff5c3ca81fbadb5c68d2d 100644
--- a/app/Views/podcast/_partials/post_authenticated.php
+++ b/app/Views/podcast/_partials/post_authenticated.php
@@ -1,7 +1,7 @@
 <article class="relative z-10 w-full bg-white shadow-md rounded-2xl">
     <header class="flex px-6 py-4">
         <img src="<?= $post->actor
-            ->avatar_image_url ?>" alt="<?= $post->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
+            ->avatar_image_url ?>" alt="<?= $post->actor->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
         <div class="flex flex-col min-w-0">
             <a href="<?= $post->actor
                 ->uri ?>" class="flex items-baseline hover:underline" <?= $post
diff --git a/app/Views/podcast/comment.php b/app/Views/podcast/comment.php
new file mode 100644
index 0000000000000000000000000000000000000000..9e604078cd64ee6dc04ad75d94177443eca26ae1
--- /dev/null
+++ b/app/Views/podcast/comment.php
@@ -0,0 +1,38 @@
+<?= $this->extend('podcast/_layout') ?>
+
+<?= $this->section('meta-tags') ?>
+    <title><?= lang('Comment.title', [
+        'actorDisplayName' => $comment->actor->display_name,
+    ]) ?></title>
+    <meta name="description" content="<?= $comment->message ?>"/>
+    <meta property="og:title" content="<?= lang('Comment.title', [
+        'actorDisplayName' => $comment->actor->display_name,
+    ]) ?>"/>
+    <meta property="og:locale" content="<?= service(
+        'request',
+    )->getLocale() ?>" />
+    <meta property="og:site_name" content="<?= $comment->actor->display_name ?>" />
+    <meta property="og:url" content="<?= current_url() ?>" />
+    <meta property="og:image" content="<?= $comment->actor->avatar_image_url ?>" />
+    <meta property="og:description" content="<?= $comment->message ?>" />
+<?= $this->endSection() ?>
+
+<?= $this->section('content') ?>
+<div class="max-w-2xl px-6 mx-auto">
+    <nav class="py-3">
+        <a href="<?= route_to('episode', $podcast->handle, $episode->slug) ?>"
+        class="inline-flex items-center px-4 py-2 text-sm"><?= icon(
+            'arrow-left',
+            'mr-2 text-lg',
+        ) .
+            lang('Comment.back_to_episode', [
+                'actor' => $comment->actor->display_name,
+            ]) ?></a>
+    </nav>
+    <div class="pb-12">
+        <?= $this->include('podcast/_partials/comment_with_replies') ?>
+    </div>
+</div>
+
+<?= $this->endSection()
+?>
diff --git a/app/Views/podcast/comment_authenticated.php b/app/Views/podcast/comment_authenticated.php
new file mode 100644
index 0000000000000000000000000000000000000000..89965611c2e09aa0c78f44a3402c47e0513077ab
--- /dev/null
+++ b/app/Views/podcast/comment_authenticated.php
@@ -0,0 +1,40 @@
+<?= $this->extend('podcast/_layout_authenticated') ?>
+
+<?= $this->section('meta-tags') ?>
+    <title><?= lang('Comment.title', [
+        'actorDisplayName' => $comment->actor->display_name,
+    ]) ?></title>
+    <meta name="description" content="<?= $comment->message ?>"/>
+    <meta property="og:title" content="<?= lang('Comment.title', [
+        'actorDisplayName' => $comment->actor->display_name,
+    ]) ?>"/>
+    <meta property="og:locale" content="<?= service(
+        'request',
+    )->getLocale() ?>" />
+    <meta property="og:site_name" content="<?= $comment->actor->display_name ?>" />
+    <meta property="og:url" content="<?= current_url() ?>" />
+    <meta property="og:image" content="<?= $comment->actor->avatar_image_url ?>" />
+    <meta property="og:description" content="<?= $comment->message ?>" />
+<?= $this->endSection() ?>
+
+<?= $this->section('content') ?>
+<div class="max-w-2xl px-6 mx-auto">
+    <nav class="py-3">
+        <a href="<?= route_to('episode', $podcast->handle, $episode->slug) ?>"
+        class="inline-flex items-center px-4 py-2 text-sm"><?= icon(
+            'arrow-left',
+            'mr-2 text-lg',
+        ) .
+            lang('Comment.back_to_episode', [
+                'actor' => $comment->actor->display_name,
+            ]) ?></a>
+    </nav>
+    <div class="pb-12">
+        <?= $this->include(
+            'podcast/_partials/comment_with_replies_authenticated',
+        ) ?>
+    </div>
+</div>
+
+<?= $this->endSection()
+?>
diff --git a/app/Views/podcast/episode_authenticated.php b/app/Views/podcast/episode_authenticated.php
index b62bb0ada6a91ab98b060f0e9dfd7d2a275a2cf9..59e9b69b2441ab9ac8d0230837293860bf8caece 100644
--- a/app/Views/podcast/episode_authenticated.php
+++ b/app/Views/podcast/episode_authenticated.php
@@ -85,7 +85,7 @@
         <div class="tab-panels">
             <section id="comments" class="space-y-6 tab-panel">
             <?= form_open(route_to('comment-attempt-create', $podcast->id, $episode->id), [
-                    'class' => 'flex p-4 bg-white shadow rounded-xl',
+                    'class' => 'flex p-4',
                 ]) ?>
                 <?= csrf_field() ?>
 
@@ -118,7 +118,6 @@
                     ) ?>
                 </div>
                 <?= form_close() ?>
-                <hr class="my-4 border border-pine-100">
                 <?php foreach ($episode->comments as $comment): ?>
                     <?= view('podcast/_partials/comment', ['comment' => $comment]) ?>
                 <?php endforeach; ?>