diff --git a/scipost_django/commentaries/forms.py b/scipost_django/commentaries/forms.py
index af9c3ed573e0c8b60851ee306eb4d7ae1354d849..0271ad453385703d86bfc3a1f52d2dade8de236a 100644
--- a/scipost_django/commentaries/forms.py
+++ b/scipost_django/commentaries/forms.py
@@ -6,6 +6,10 @@ from django import forms
 from django.utils.safestring import mark_safe
 from django.template.loader import get_template
 
+from crispy_forms.helper import FormHelper
+from crispy_forms.layout import Layout, Div
+from crispy_bootstrap5.bootstrap5 import FloatingField
+
 from .models import Commentary
 from .constants import COMMENTARY_PUBLISHED, COMMENTARY_PREPRINT
 
@@ -315,7 +319,62 @@ class VetCommentaryForm(forms.Form):
 
 
 class CommentarySearchForm(forms.Form):
-    """Search for Commentary specified by user"""
+    author = forms.CharField(
+        max_length=100,
+        required=False,
+        label="On publication with author(s)"
+    )
+    title = forms.CharField(
+        max_length=100,
+        required=False,
+        label="On publication with title"
+    )
+    abstract = forms.CharField(
+        max_length=1000,
+        required=False,
+        label="On publication with abstract"
+    )
+
+    def __init__(self, *args, **kwargs):
+        self.acad_field_slug = kwargs.pop("acad_field_slug")
+        self.specialty_slug = kwargs.pop("specialty_slug")
+        super().__init__(*args, **kwargs)
+        self.helper = FormHelper()
+        self.helper.layout = Layout(
+            Div(
+                FloatingField("author"),
+                FloatingField("title"),
+                FloatingField("abstract"),
+            ),
+        )
+
+    def search_results(self):
+        """Return all Commentary objects according to search"""
+        commentaries = Commentary.objects.vetted()
+        if self.acad_field_slug and self.acad_field_slug != "all":
+            commentaries = commentaries.filter(acad_field__slug=self.acad_field_slug)
+            if self.specialty_slug and self.specialty_slug != "all":
+                commentaries = commentaries.filter(
+                    specialties__slug=self.specialty_slug
+                )
+        if hasattr(self, "cleaned_data"):
+            if "title" in self.cleaned_data:
+                commentaries = commentaries.filter(
+                    title__icontains=self.cleaned_data["title"],
+                )
+            if "abstract" in self.cleaned_data:
+                commentaries = commentaries.filter(
+                    pub_abstract__icontains=self.cleaned_data["abstract"],
+                )
+            if "author" in self.cleaned_data:
+                commentaries = commentaries.filter(
+                    author_list__icontains=self.cleaned_data["author"],
+                )
+        return commentaries.order_by("-pub_date")
+
+
+class CommentaryListSearchForm(forms.Form):
+    """Search for Commentary specified by user (for old CommentaryListView)"""
 
     author = forms.CharField(max_length=100, required=False, label="Author(s)")
     title = forms.CharField(max_length=100, required=False, label="Title")
diff --git a/scipost_django/commentaries/models.py b/scipost_django/commentaries/models.py
index 24455ae609d3ac18a42ce13e5743e32df89c3fe8..931e64107afa6c3a8cddee00a62fea0105082184 100644
--- a/scipost_django/commentaries/models.py
+++ b/scipost_django/commentaries/models.py
@@ -16,7 +16,7 @@ from .managers import CommentaryManager
 
 class Commentary(TimeStampedModel):
     """
-    A Commentary contains all the contents of a SciPost Commentary page for a given publication.
+    A Commentary page for a given publication.
     """
 
     requested_by = models.ForeignKey(
diff --git a/scipost_django/commentaries/templates/commentaries/_commentary_card_content.html b/scipost_django/commentaries/templates/commentaries/_commentary_card_content.html
index 61d51d71371627c2b9c13f2cd2d6017443880580..aabbaf788b1c93b8e6cecde6cdaf242a70af609f 100644
--- a/scipost_django/commentaries/templates/commentaries/_commentary_card_content.html
+++ b/scipost_django/commentaries/templates/commentaries/_commentary_card_content.html
@@ -1,4 +1,4 @@
-<div class="card-body px-0">
+<div class="card-body">
   <div class="li commentary">
     <h3 class="title"><a href="{{ commentary.get_absolute_url }}">{{ commentary.title }}</a></h3>
     <p class="authors">
diff --git a/scipost_django/commentaries/tests/test_views.py b/scipost_django/commentaries/tests/test_views.py
index a1177d7dbeead4b1b6b165105000f7c118c2afdc..0f095812d102d501e87eca845b97550a6f333986 100644
--- a/scipost_django/commentaries/tests/test_views.py
+++ b/scipost_django/commentaries/tests/test_views.py
@@ -15,7 +15,7 @@ from ..factories import (
     UnpublishedCommentaryFactory,
     UnvettedUnpublishedCommentaryFactory,
 )
-from ..forms import CommentarySearchForm, RequestPublishedArticleForm
+from ..forms import RequestPublishedArticleForm
 from ..models import Commentary
 from ..views import RequestPublishedArticle, prefill_using_DOI, RequestArxivPreprint
 from common.helpers.test import add_groups_and_permissions
diff --git a/scipost_django/commentaries/views.py b/scipost_django/commentaries/views.py
index 20702e4b0b9e06f8c436ac2caa9a265df62c8bcc..e9ac27b9fcb1494dac860ccc29389a8e31b96d25 100644
--- a/scipost_django/commentaries/views.py
+++ b/scipost_django/commentaries/views.py
@@ -22,7 +22,7 @@ from .forms import (
     ArxivQueryForm,
     VetCommentaryForm,
     RequestCommentaryForm,
-    CommentarySearchForm,
+    CommentaryListSearchForm,
     RequestPublishedArticleForm,
     RequestArxivPreprintForm,
     CommentSciPostPublication,
@@ -224,7 +224,7 @@ def modify_commentary_request(request, commentary_id):
 
 class CommentaryListView(PaginationMixin, ListView):
     model = Commentary
-    form = CommentarySearchForm
+    form = CommentaryListSearchForm
     paginate_by = 10
     context_object_name = "commentary_list"
 
diff --git a/scipost_django/comments/forms.py b/scipost_django/comments/forms.py
index 29a9eefca96b5fde1e573550468009c1f751c7ef..3419e2d3d087d36286f60dd388b3d2661feffc39 100644
--- a/scipost_django/comments/forms.py
+++ b/scipost_django/comments/forms.py
@@ -109,13 +109,13 @@ class CommentSearchForm(forms.Form):
 
     def search_results(self):
         comments = Comment.objects.vetted()
-        if self.acad_field_slug != "all":
+        if self.acad_field_slug and self.acad_field_slug != "all":
             comments = comments.filter(
                 Q(submissions__acad_field__slug=self.acad_field_slug)
                 | Q(reports__submission__acad_field__slug=self.acad_field_slug)
                 | Q(commentaries__acad_field__slug=self.acad_field_slug)
             )
-            if self.specialty_slug:
+            if self.specialty_slug and self.specialty_slug != "all":
                 comments = comments.filter(
                     Q(submissions__specialties__slug=self.specialty_slug)
                     | Q(reports__submission__specialties__slug=self.specialty_slug)
diff --git a/scipost_django/scipost/templates/scipost/navbar.html b/scipost_django/scipost/templates/scipost/navbar.html
index 743595cf9180c7a988b77c09e0bfff12ce8a0d33..c21604b373534a920bd20a379876ad48156d4068 100644
--- a/scipost_django/scipost/templates/scipost/navbar.html
+++ b/scipost_django/scipost/templates/scipost/navbar.html
@@ -87,6 +87,65 @@
 	    </a>
 	  {% endif %}
 	</li>
+
+	<li class="nav-item dropdown">
+          <a class="nav-link dropdown-toggle" href="#" id="MoreDropdown" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"  data-trigger="hover">More</a>
+          <ul class="dropdown-menu" aria-labelledby="MoreDropdown">
+	    <li>
+	      {% if request.path == '/portal' %}
+		<button class="nav-link{% if request.GET.tab == 'reports' %} active{% endif %}"
+			       id="reports-tab"
+			       data-bs-toggle="tab" data-bs-target="#reports"
+			       type="button" role="tab"
+			       aria-controls="reports" aria-selected="true">
+		  Reports
+		</button>
+	      {% else %}
+		<a href="{% url 'scipost:portal' %}?tab=reports">Reports</a>
+	      {% endif %}
+	    </li>
+            <li>
+	      {% if request.path == '/portal' %}
+		<button class="nav-link{% if request.GET.tab == 'comments' %} active{% endif %}"
+			       id="comments-tab"
+			       data-bs-toggle="tab" data-bs-target="#comments"
+			       type="button" role="tab"
+			       aria-controls="comments" aria-selected="true">
+		  Comments
+		</button>
+	      {% else %}
+		<a href="{% url 'scipost:portal' %}?tab=comments">Comments</a>
+	      {% endif %}
+            </li>
+            <li>
+	      {% if request.path == '/portal' %}
+		<button class="nav-link{% if request.GET.tab == 'commentaries' %} active{% endif %}"
+			id="commentaries-tab"
+			data-bs-toggle="tab" data-bs-target="#commentaries"
+			type="button" role="tab"
+			aria-controls="commentaries" aria-selected="true">
+		  Commentaries
+		</button>
+	      {% else %}
+		<a href="{% url 'scipost:portal' %}?tab=commentaries">Commentaries</a>
+	      {% endif %}
+            </li>
+            <li>
+	      {% if request.path == '/portal' %}
+		<button class="nav-link{% if request.GET.tab == 'theses' %} active{% endif %}"
+			id="theses-tab"
+			data-bs-toggle="tab" data-bs-target="#theses"
+			type="button" role="tab"
+			aria-controls="theses" aria-selected="true">
+		  Theses
+		</button>
+	      {% else %}
+		<a href="{% url 'scipost:portal' %}?tab=theses">Theses</a>
+	      {% endif %}
+            </li>
+          </ul>
+	</li>
+
 	<!--
 	     <li class="nav-item" role="presentation">
 	     {% if request.path == '/portal' %}
diff --git a/scipost_django/scipost/templates/scipost/portal/_hx_commentaries.html b/scipost_django/scipost/templates/scipost/portal/_hx_commentaries.html
new file mode 100644
index 0000000000000000000000000000000000000000..716bee0b717a56ec2b8e9d3d0b9f346d802c3059
--- /dev/null
+++ b/scipost_django/scipost/templates/scipost/portal/_hx_commentaries.html
@@ -0,0 +1,42 @@
+{% load crispy_forms_tags %}
+
+<div class="p-3 mb-3 bg-light scipost-bar border">
+  <h1 class="mb-3">SciPost Commentaries</h1>
+  <h2>
+    <a href="{% url 'commentaries:howto' %}">SciPost Commentaries how-to</a>
+  </h2>
+  <h2>
+    <a href="{% url 'commentaries:request_commentary' %}">Request a new Commentary Page</a>
+  </h2>
+</div>
+
+<div class="d-flex justify-content-between">
+  <button class="btn btn-outline-primary" data-bs-toggle="collapse" data-bs-target="#commentariesSearch" aria-expanded="false" aria-controls="commentariesSearch">
+    {% include 'bi/search.html' %}&emsp;Simple search / filter
+  </button>
+  <a class="btn btn-outline-primary ms-2" href="{% url 'scipost:search' %}">
+    {% include 'bi/binoculars-fill.html' %}... or use our advanced search API&emsp;{% include 'bi/arrow-right.html' %}
+  </a>
+</div>
+<div class="collapse" id="commentariesSearch">
+  <div class="card card-body">
+    <form
+	hx-post="{% url 'scipost:portal_hx_commentaries_page' %}?page=1"
+	hx-trigger="load, keyup delay:500ms, change"
+	hx-target="#commentaries-search-results"
+	hx-indicator="#indicator-commentaries-search"
+    >
+      <div id="commentaries-search-form">{% crispy commentaries_search_form %}</div>
+    </form>
+  </div>
+  <div id="indicator-commentaries-search" class="htmx-indicator p-2">
+    <button class="btn btn-warning" type="button" disabled>
+      <strong>Loading...</strong>
+      <div class="spinner-grow spinner-grow-sm ms-2" role="status" aria-hidden="true"></div>
+    </button>
+  </div>
+</div>
+
+<h2 class="highlight mb-0">Commentaries{% if session_acad_field %} in {{ session_acad_field }}: {% if session_specialty %}{{ session_specialty }}{% else %}(all specialties){% endif %}{% else %} (all fields){% endif %}</h2>
+
+<ul id="commentaries-search-results" class="list-unstyled pool-list mt-2"></ul>
diff --git a/scipost_django/scipost/templates/scipost/portal/_hx_commentaries_page.html b/scipost_django/scipost/templates/scipost/portal/_hx_commentaries_page.html
new file mode 100644
index 0000000000000000000000000000000000000000..1dd4a71a8dadf7a69a8fa5628518e2ef47850afb
--- /dev/null
+++ b/scipost_django/scipost/templates/scipost/portal/_hx_commentaries_page.html
@@ -0,0 +1,28 @@
+{% for commentary in page_obj %}
+  <li class="list-group-item py-2">
+    {% include 'commentaries/_commentary_card_content.html' with commentary=commentary %}
+  </li>
+{% empty %}
+  <li class="list-group-item py-2">
+    None found
+  </li>
+{% endfor %}
+{% if page_obj.has_next %}
+  <li id="next-commentaries-{{ page_obj.number }}">
+    <button class="btn btn-primary m-2" type="button"
+	    hx-post="{% url 'scipost:portal_hx_commentaries_page' %}?page={{ page_obj.next_page_number }}"
+	    hx-include="#commentaries-search-form"
+	    hx-target="#next-commentaries-{{ page_obj.number }}"
+	    hx-swap="outerHTML"
+	    hx-indicator="#indicator-commentaries-page-{{ page_obj.number }}"
+    >
+      Load page {{ page_obj.next_page_number }} (out of {{ page_obj.paginator.num_pages }})
+    </button>
+    <span id="indicator-commentaries-page-{{ page_obj.number }}" class="htmx-indicator p-2">
+      <button class="btn btn-warning" type="button" disabled>
+	<strong>Loading page {{ page_obj.next_page_number }} out of {{ page_obj.paginator.num_pages }}</strong>
+	<div class="spinner-grow spinner-grow-sm ms-2" role="status" aria-hidden="true"></div>
+      </button>
+    </span>
+  </li>
+{% endif %}
diff --git a/scipost_django/scipost/templates/scipost/portal/_hx_comments.html b/scipost_django/scipost/templates/scipost/portal/_hx_comments.html
index 1875b2b368c20fc8677262fa1fe72cf5c389aad7..87f2163c2c9cab082ec88649e118c775b5ef2f28 100644
--- a/scipost_django/scipost/templates/scipost/portal/_hx_comments.html
+++ b/scipost_django/scipost/templates/scipost/portal/_hx_comments.html
@@ -27,6 +27,6 @@
   </div>
 </div>
 
-<h2 class="highlight mb-0">Comments on objects in {{ session_acad_field }}: {% if session_specialty %}{{ session_specialty }}{% else %}(all specialties){% endif %}</h2>
+<h2 class="highlight mb-0">Comments on objects{% if session_acad_field %} in {{ session_acad_field }}: {% if session_specialty %}{{ session_specialty }}{% else %}(all specialties){% endif %}{% else %} (all fields){% endif %}</h2>
 
 <ul id="comments-search-results" class="list-unstyled pool-list mt-2"></ul>
diff --git a/scipost_django/scipost/templates/scipost/portal/_hx_reports.html b/scipost_django/scipost/templates/scipost/portal/_hx_reports.html
index d4eba9664e9818e8f02dd3b553e3fcbc69fbac81..c12a3f7fa467ede001f66a448616da24bbc7c670 100644
--- a/scipost_django/scipost/templates/scipost/portal/_hx_reports.html
+++ b/scipost_django/scipost/templates/scipost/portal/_hx_reports.html
@@ -11,10 +11,10 @@
 <div class="collapse" id="reportsSearch">
   <div class="card card-body">
     <form
-      hx-post="{% url 'scipost:portal_hx_reports_page' %}?page=1"
-	       hx-trigger="load, keyup delay:500ms, change"
-	       hx-target="#reports-search-results"
-	       hx-indicator="#indicator-reports-search"
+	hx-post="{% url 'scipost:portal_hx_reports_page' %}?page=1"
+	hx-trigger="load, keyup delay:500ms, change"
+	hx-target="#reports-search-results"
+	hx-indicator="#indicator-reports-search"
     >
       <div id="reports-search-form">{% crispy reports_search_form %}</div>
     </form>
@@ -27,6 +27,6 @@
   </div>
 </div>
 
-<h2 class="highlight mb-0">Reports on Submissions in {{ session_acad_field }}: {% if session_specialty %}{{ session_specialty }}{% else %}(all specialties){% endif %}</h2>
+<h2 class="highlight mb-0">Reports on Submissions{% if session_acad_field %} in {{ session_acad_field }}: {% if session_specialty %}{{ session_specialty }}{% else %}(all specialties){% endif %}{% else %} (all fields){% endif %}</h2>
 
 <ul id="reports-search-results" class="list-unstyled pool-list mt-2"></ul>
diff --git a/scipost_django/scipost/templates/scipost/portal/_hx_submissions_base.html b/scipost_django/scipost/templates/scipost/portal/_hx_submissions_base.html
index 6332e1c885126ed3561870e31f8637ca8c15e908..b97791602e9b533784439ac37c4beafadbd207ee 100644
--- a/scipost_django/scipost/templates/scipost/portal/_hx_submissions_base.html
+++ b/scipost_django/scipost/templates/scipost/portal/_hx_submissions_base.html
@@ -39,8 +39,9 @@
       </h2>
     </div>
     <div class="card-body">
-      <h3>Please consider contributing a Report so we can minimize delays in editorial processing.</h3>
-      <p>To do so, please navigate to the Submission's page and click on the <strong>Contribute a Report</strong> link {% if not user.is_authenticated %}(login required){% endif %}
+      <h3><strong>Please consider contributing one</strong> (even if not explicitly invited to do so)!</h3>
+      <h3>Authors will be grateful, and our editorial processing will remain free of undue delays.</h3>
+      <p>To contribute a Report, please navigate to the Submission's page and click on the <strong>Contribute a Report</strong> link {% if not user.is_authenticated %}(login required){% endif %}
     </div>
   </div>
 
diff --git a/scipost_django/scipost/templates/scipost/portal/_hx_theses.html b/scipost_django/scipost/templates/scipost/portal/_hx_theses.html
new file mode 100644
index 0000000000000000000000000000000000000000..f3d2a35457b950e40f0a35a5a6bcd5a2d0a777f2
--- /dev/null
+++ b/scipost_django/scipost/templates/scipost/portal/_hx_theses.html
@@ -0,0 +1,37 @@
+{% load crispy_forms_tags %}
+
+<div class="p-3 mb-3 bg-light scipost-bar border">
+  <h1 class="mb-3">SciPost Theses</h1>
+  <h2><a href="{% url 'theses:request_thesislink' %}">Request a new Thesis Link</a></h2>
+</div>
+
+<div class="d-flex justify-content-between">
+  <button class="btn btn-outline-primary" data-bs-toggle="collapse" data-bs-target="#thesesSearch" aria-expanded="false" aria-controls="thesesSearch">
+    {% include 'bi/search.html' %}&emsp;Simple search / filter
+  </button>
+  <a class="btn btn-outline-primary ms-2" href="{% url 'scipost:search' %}">
+    {% include 'bi/binoculars-fill.html' %}... or use our advanced search API&emsp;{% include 'bi/arrow-right.html' %}
+  </a>
+</div>
+<div class="collapse" id="thesesSearch">
+  <div class="card card-body">
+    <form
+      hx-post="{% url 'scipost:portal_hx_theses_page' %}?page=1"
+	       hx-trigger="load, keyup delay:500ms, change"
+	       hx-target="#theses-search-results"
+	       hx-indicator="#indicator-theses-search"
+    >
+      <div id="theses-search-form">{% crispy theses_search_form %}</div>
+    </form>
+  </div>
+  <div id="indicator-theses-search" class="htmx-indicator p-2">
+    <button class="btn btn-warning" type="button" disabled>
+      <strong>Loading...</strong>
+      <div class="spinner-grow spinner-grow-sm ms-2" role="status" aria-hidden="true"></div>
+    </button>
+  </div>
+</div>
+
+<h2 class="highlight mb-0">Thesis links{% if session_acad_field %} in {{ session_acad_field }}: {% if session_specialty %}{{ session_specialty }}{% else %}(all specialties){% endif %}{% else %} (all fields){% endif %}</h2>
+
+<ul id="theses-search-results" class="list-unstyled pool-list mt-2"></ul>
diff --git a/scipost_django/scipost/templates/scipost/portal/_hx_theses_page.html b/scipost_django/scipost/templates/scipost/portal/_hx_theses_page.html
new file mode 100644
index 0000000000000000000000000000000000000000..d48e488ab06a04b8dd822ec81c8fd4a3ccc7be52
--- /dev/null
+++ b/scipost_django/scipost/templates/scipost/portal/_hx_theses_page.html
@@ -0,0 +1,28 @@
+{% for thesislink in page_obj %}
+  <li class="list-group-item py-2">
+    {% include 'theses/_thesislink_card_content.html' with thesislink=thesislink %}
+  </li>
+{% empty %}
+  <li class="list-group-item py-2">
+    None found
+  </li>
+{% endfor %}
+{% if page_obj.has_next %}
+  <li id="next-theses-{{ page_obj.number }}">
+    <button class="btn btn-primary m-2" type="button"
+	    hx-post="{% url 'scipost:portal_hx_theses_page' %}?page={{ page_obj.next_page_number }}"
+	    hx-include="#theses-search-form"
+	    hx-target="#next-theses-{{ page_obj.number }}"
+	    hx-swap="outerHTML"
+	    hx-indicator="#indicator-theses-page-{{ page_obj.number }}"
+    >
+      Load page {{ page_obj.next_page_number }} (out of {{ page_obj.paginator.num_pages }})
+    </button>
+    <span id="indicator-theses-page-{{ page_obj.number }}" class="htmx-indicator p-2">
+      <button class="btn btn-warning" type="button" disabled>
+	<strong>Loading page {{ page_obj.next_page_number }} out of {{ page_obj.paginator.num_pages }}</strong>
+	<div class="spinner-grow spinner-grow-sm ms-2" role="status" aria-hidden="true"></div>
+      </button>
+    </span>
+  </li>
+{% endif %}
diff --git a/scipost_django/scipost/templates/scipost/portal/portal.html b/scipost_django/scipost/templates/scipost/portal/portal.html
index 2b2929cd412838206ca0a2b41e57f2dd9f1adc56..eb642eecbc627e3d060bfdb4a4e445995561e8ea 100644
--- a/scipost_django/scipost/templates/scipost/portal/portal.html
+++ b/scipost_django/scipost/templates/scipost/portal/portal.html
@@ -90,6 +90,26 @@
       </div>
     </div>
 
+    <div class="tab-pane portal-tab fade{% if request.GET.tab == 'commentaries' %} show active{% endif %}"
+	 id="commentaries"
+	 role="tabpanel" aria-labelledby="commentaries-tab">
+      <div hx-get="{% url 'scipost:portal_hx_commentaries' %}"
+	   hx-trigger="{% if request.GET.tab == 'commentaries' %}load, {% endif %}click delay:200ms from:#commentaries-tab, session-acad-field-set from:body, session-specialty-set from:body"
+	   hx-push-url="{% url 'scipost:portal' %}?tab=commentaries"
+      >
+      </div>
+    </div>
+
+    <div class="tab-pane portal-tab fade{% if request.GET.tab == 'theses' %} show active{% endif %}"
+	 id="theses"
+	 role="tabpanel" aria-labelledby="theses-tab">
+      <div hx-get="{% url 'scipost:portal_hx_theses' %}"
+	   hx-trigger="{% if request.GET.tab == 'theses' %}load, {% endif %}click delay:200ms from:#theses-tab, session-acad-field-set from:body, session-specialty-set from:body"
+	   hx-push-url="{% url 'scipost:portal' %}?tab=theses"
+      >
+      </div>
+    </div>
+
   </div>
 
 {% endblock %}
diff --git a/scipost_django/scipost/tests/test_views.py b/scipost_django/scipost/tests/test_views.py
index 81d83ed49db5117c2389a8881e059d32dabfb228..2e5f2b550217f530174eb48d45e6e84e625e36c3 100644
--- a/scipost_django/scipost/tests/test_views.py
+++ b/scipost_django/scipost/tests/test_views.py
@@ -13,7 +13,6 @@ from commentaries.factories import (
     CommentaryFactory,
     UnpublishedCommentaryFactory,
 )
-from commentaries.forms import CommentarySearchForm
 from commentaries.models import Commentary
 
 from ..factories import ContributorFactory
diff --git a/scipost_django/scipost/urls.py b/scipost_django/scipost/urls.py
index 419ff30dbb73eee24391485cb0702231ab17b3a1..7b334162560002fd7f7c821c4dd877a1f91beb79 100644
--- a/scipost_django/scipost/urls.py
+++ b/scipost_django/scipost/urls.py
@@ -124,6 +124,22 @@ urlpatterns = [
         views.portal_hx_comments_page,
         name="portal_hx_comments_page",
     ),
+    path(
+        "portal/_hx_commentaries",
+        views.portal_hx_commentaries,
+        name="portal_hx_commentaries"
+    ),
+    path(
+        "portal/_hx_commentaries_page",
+        views.portal_hx_commentaries_page,
+        name="portal_hx_commentaries_page",
+    ),
+    path("portal/_hx_theses", views.portal_hx_theses, name="portal_hx_theses"),
+    path(
+        "portal/_hx_theses_page",
+        views.portal_hx_theses_page,
+        name="portal_hx_theses_page",
+    ),
     path("_hx_news", views._hx_news, name="_hx_news"),
     path(
         "_hx_participates_in",
diff --git a/scipost_django/scipost/views.py b/scipost_django/scipost/views.py
index 6a9f82732ca364a88b1a222670e420968be54bcc..1be2891a30506ce45f63dcd04bc4b1d4752e6ba3 100644
--- a/scipost_django/scipost/views.py
+++ b/scipost_django/scipost/views.py
@@ -68,6 +68,7 @@ from .utils import EMAIL_FOOTER, SCIPOST_SUMMARY_FOOTER, SCIPOST_SUMMARY_FOOTER_
 
 from colleges.permissions import fellowship_or_admin_required
 from commentaries.models import Commentary
+from commentaries.forms import CommentarySearchForm
 from comments.models import Comment
 from comments.forms import CommentSearchForm
 from invitations.constants import STATUS_REGISTERED
@@ -83,6 +84,7 @@ from profiles.models import Profile
 from submissions.models import Submission, RefereeInvitation, Report, EICRecommendation
 from submissions.forms import SubmissionSearchForm, ReportSearchForm
 from theses.models import ThesisLink
+from theses.forms import ThesisSearchForm
 
 
 ###########
@@ -344,7 +346,7 @@ def portal_hx_reports_page(request):
         reports = Report.objects.accepted()
     if session_acad_field_slug and session_acad_field_slug != "all":
         reports = reports.filter(submission__acad_field__slug=session_acad_field_slug)
-        if session_specialty_slug:
+        if session_specialty_slug and session_specialty_slug != "all":
             reports = reports.filter(
                 submission__specialties__slug=session_specialty_slug
             )
@@ -382,7 +384,7 @@ def portal_hx_comments_page(request):
             | Q(reports__submission__acad_field__slug=session_acad_field_slug)
             | Q(commentaries__acad_field__slug=session_acad_field_slug)
         )
-        if session_specialty_slug:
+        if session_specialty_slug and session_specialty_slug != "all":
             comments = comments.filter(
                 Q(submissions__specialties__slug=session_specialty_slug)
                 | Q(reports__submission__specialties__slug=session_specialty_slug)
@@ -395,6 +397,58 @@ def portal_hx_comments_page(request):
     return render(request, "scipost/portal/_hx_comments_page.html", context)
 
 
+def portal_hx_commentaries(request):
+    form = CommentarySearchForm(
+        acad_field_slug=request.session.get("session_acad_field_slug", None),
+        specialty_slug=request.session.get("session_specialty_slug", None),
+    )
+    context = {"commentaries_search_form": form}
+    return render(request, "scipost/portal/_hx_commentaries.html", context)
+
+
+def portal_hx_commentaries_page(request):
+    session_acad_field_slug = request.session.get("session_acad_field_slug", None)
+    session_specialty_slug = request.session.get("session_specialty_slug", None)
+    form = CommentarySearchForm(
+        request.POST or None,
+        acad_field_slug=session_acad_field_slug,
+        specialty_slug=session_specialty_slug,
+    )
+    form.is_valid() # trigger validation to get filtering
+    commentaries = form.search_results()
+    paginator = Paginator(commentaries, 10)
+    page_nr = request.GET.get("page")
+    page_obj = paginator.get_page(page_nr)
+    context = {"page_obj": page_obj}
+    return render(request, "scipost/portal/_hx_commentaries_page.html", context)
+
+
+def portal_hx_theses(request):
+    form = ThesisSearchForm(
+        acad_field_slug=request.session.get("session_acad_field_slug", None),
+        specialty_slug=request.session.get("session_specialty_slug", None),
+    )
+    context = {"theses_search_form": form}
+    return render(request, "scipost/portal/_hx_theses.html", context)
+
+
+def portal_hx_theses_page(request):
+    session_acad_field_slug = request.session.get("session_acad_field_slug", None)
+    session_specialty_slug = request.session.get("session_specialty_slug", None)
+    form = ThesisSearchForm(
+        request.POST or None,
+        acad_field_slug=session_acad_field_slug,
+        specialty_slug=session_specialty_slug,
+    )
+    form.is_valid() # trigger validation to get filtering
+    theses = form.search_results()
+    paginator = Paginator(theses, 10)
+    page_nr = request.GET.get("page")
+    page_obj = paginator.get_page(page_nr)
+    context = {"page_obj": page_obj}
+    return render(request, "scipost/portal/_hx_theses_page.html", context)
+
+
 def _hx_news(request):
     if NewsItem.objects.homepage().exists():
         latest_newsitem_id = NewsItem.objects.homepage().order_by("-date").first().id
diff --git a/scipost_django/submissions/forms.py b/scipost_django/submissions/forms.py
index b3b1ee705a76626c6efc3d2dd0002de9a976748d..9a33606db47178ba7f23c0d3ee8184a22cdc66d6 100644
--- a/scipost_django/submissions/forms.py
+++ b/scipost_django/submissions/forms.py
@@ -143,7 +143,7 @@ class SubmissionSearchForm(forms.Form):
         Return all Submission objects fitting search criteria.
         """
         submissions = Submission.objects.public_newest().unpublished()
-        if self.acad_field_slug != "all":
+        if self.acad_field_slug and self.acad_field_slug != "all":
             submissions = submissions.filter(acad_field__slug=self.acad_field_slug)
             if self.specialty_slug and self.specialty_slug != "all":
                 submissions = submissions.filter(specialties__slug=self.specialty_slug)
@@ -412,9 +412,9 @@ class ReportSearchForm(forms.Form):
 
     def search_results(self):
         reports = Report.objects.accepted()
-        if self.acad_field_slug != "all":
+        if self.acad_field_slug and self.acad_field_slug != "all":
             reports = reports.filter(submission__acad_field__slug=self.acad_field_slug)
-            if self.specialty_slug:
+            if self.specialty_slug and self.specialty_slug != "all":
                 reports = reports.filter(
                     submission__specialties__slug=self.specialty_slug
                 )
diff --git a/scipost_django/theses/forms.py b/scipost_django/theses/forms.py
index 1120deb0cf59e3d2d004f114e77b5215f962e923..70ef57f20d4928cf63532100015210b1bfa44062 100644
--- a/scipost_django/theses/forms.py
+++ b/scipost_django/theses/forms.py
@@ -7,6 +7,10 @@ from django.contrib.sites.models import Site
 from django.core.mail import EmailMessage
 from django.template.loader import render_to_string
 
+from crispy_forms.helper import FormHelper
+from crispy_forms.layout import Layout, Div
+from crispy_bootstrap5.bootstrap5 import FloatingField
+
 from scipost.models import Contributor
 from scipost.utils import build_absolute_uri_using_site
 
@@ -138,3 +142,55 @@ class ThesisLinkSearchForm(forms.Form):
         max_length=1000, required=False, label="Abstract"
     )
     supervisor = forms.CharField(max_length=100, required=False, label="Supervisor")
+
+
+class ThesisSearchForm(forms.Form):
+    author = forms.CharField(max_length=100, required=False, label="Author")
+    title = forms.CharField(max_length=100, label="Title", required=False)
+    abstract = forms.CharField(
+        max_length=1000, required=False, label="Abstract"
+    )
+    supervisor = forms.CharField(max_length=100, required=False, label="Supervisor")
+
+    def __init__(self, *args, **kwargs):
+        self.acad_field_slug = kwargs.pop("acad_field_slug")
+        self.specialty_slug = kwargs.pop("specialty_slug")
+        super().__init__(*args, **kwargs)
+        self.helper = FormHelper()
+        self.helper.layout = Layout(
+            Div(
+                FloatingField("author"),
+                FloatingField("title"),
+                FloatingField("abstract"),
+                FloatingField("supervisor"),
+            ),
+        )
+
+    def search_results(self):
+        """Return all ThesisLink objects fitting search"""
+        theses = ThesisLink.objects.vetted()
+        if self.acad_field_slug and self.acad_field_slug != "all":
+            theses = theses.filter(acad_field__slug=self.acad_field_slug)
+            if self.specialty_slug and self.specialty_slug != "all":
+                theses = theses.filter(
+                    specialties__slug=self.specialty_slug
+                )
+        if hasattr(self, "cleaned_data"):
+            if "title" in self.cleaned_data:
+                theses = theses.filter(
+                    title__icontains=self.cleaned_data["title"],
+                )
+                len(theses)
+            if "abstract" in self.cleaned_data:
+                theses = theses.filter(
+                    abstract__icontains=self.cleaned_data["abstract"],
+                )
+            if "author" in self.cleaned_data:
+                theses = theses.filter(
+                    author__icontains=self.cleaned_data["author"],
+                )
+            if "supervisor" in self.cleaned_data:
+                theses = theses.filter(
+                    supervisor__icontains=self.cleaned_data["supervisor"],
+                )
+        return theses.order_by("-defense_date")
diff --git a/scipost_django/theses/templates/theses/_thesislink_card_content.html b/scipost_django/theses/templates/theses/_thesislink_card_content.html
index 7d37452df408b9d84ef5fcff22b79988ad86cf5b..e1520ae23838dcedbb91762c9ff848def148c8ec 100644
--- a/scipost_django/theses/templates/theses/_thesislink_card_content.html
+++ b/scipost_django/theses/templates/theses/_thesislink_card_content.html
@@ -1,4 +1,4 @@
-<div class="card-body px-0">
+<div class="card-body">
   <div class="li thesis">
     <h3 class="specialties">{{ thesislink.acad_field }}</h3>
     <ul class="list-inline">