diff --git a/district/blocks.py b/district/blocks.py
index 4de02c597be0f9709a32546685f52dbb87c92563..f17fee7a69f0b661191a65be9926a1099e8b4d58 100644
--- a/district/blocks.py
+++ b/district/blocks.py
@@ -123,11 +123,11 @@ class CardLinkBlock(CardLinkBlockMixin):
     class Meta:
         template = "district/blocks/card_link_block.html"
         icon = "link"
-        label = "Karta odkazu"
+        label = "Karta s odkazem"
 
 
 class CardLinkWithHeadlineBlock(CardLinkWithHeadlineBlockMixin):
-    card_items = ListBlock(CardLinkBlock(), label="Karty odkazu")
+    card_items = ListBlock(CardLinkBlock(), label="Karty s odkazy")
 
     class Meta:
         template = "district/blocks/card_link_with_headline_block.html"
diff --git a/district/migrations/0106_alter_districtcrossroadpage_cards_content.py b/district/migrations/0106_alter_districtcrossroadpage_cards_content.py
new file mode 100644
index 0000000000000000000000000000000000000000..3f106be32e610f7ea096b90721e171c23e0e644e
--- /dev/null
+++ b/district/migrations/0106_alter_districtcrossroadpage_cards_content.py
@@ -0,0 +1,21 @@
+# Generated by Django 4.1.6 on 2023-02-28 07:51
+
+from django.db import migrations
+import wagtail.blocks
+import wagtail.fields
+import wagtail.images.blocks
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('district', '0105_alter_districtarticlepage_content'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='districtcrossroadpage',
+            name='cards_content',
+            field=wagtail.fields.StreamField([('cards', wagtail.blocks.StructBlock([('headline', wagtail.blocks.CharBlock(label='Titulek bloku', required=False)), ('card_items', wagtail.blocks.ListBlock(wagtail.blocks.StructBlock([('image', wagtail.images.blocks.ImageChooserBlock(label='Obrázek')), ('title', wagtail.blocks.CharBlock(label='Titulek', required=True)), ('text', wagtail.blocks.RichTextBlock(label='Krátký text pod nadpisem', required=False)), ('page', wagtail.blocks.PageChooserBlock(label='Stránka', page_type=['district.DistrictArticlePage', 'district.DistrictArticlesPage', 'district.DistrictCenterPage', 'district.DistrictContactPage', 'district.DistrictCrossroadPage', 'district.DistrictCustomPage', 'district.DistrictElectionCampaignPage', 'district.DistrictElectionProgramPage', 'district.DistrictElectionRootPage', 'district.DistrictPeoplePage', 'district.DistrictPersonPage', 'district.DistrictPostElectionStrategyPage', 'district.DistrictProgramPage'], required=False)), ('link', wagtail.blocks.URLBlock(label='Odkaz', required=False))]), label='Karty s odkazy'))]))], blank=True, use_json_field=True, verbose_name='Karty rozcestníku'),
+        ),
+    ]
diff --git a/district/templates/district/base.html b/district/templates/district/base.html
index c621364257e59fc041e38f02205a80f8fe1840c8..0f20b30bd7e8579b8006969b559f882b8250e118 100644
--- a/district/templates/district/base.html
+++ b/district/templates/district/base.html
@@ -59,7 +59,7 @@
           <div class="navbar__brand my-4 flex items-center lg:block lg:pr-8 lg:my-0">
             <a href="/">
               {% if page.root_page.custom_logo %}
-                {% image page.root_page.custom_logo width-128 as logo %}
+                {% image page.root_page.custom_logo width-512 as logo %}
                 <img
                   src="{{ logo.url }}"
                   class="w-10 lg:w-full lg:border-r lg:border-grey-300 lg:pr-8"
diff --git a/main/blocks.py b/main/blocks.py
index 71c244416bc018c0cc2a4bfa5ae146e2cf8d461f..04cab96d35c50b3452f2f4af2ceaa5e5253a2545 100644
--- a/main/blocks.py
+++ b/main/blocks.py
@@ -53,7 +53,7 @@ class CardLinkBlock(CardLinkBlockMixin):
     class Meta:
         template = "main/blocks/card_link_block.html"
         icon = "link"
-        label = "Karta odkazu"
+        label = "Karta s odkazem"
 
 
 class CTAMixin(StructBlock):
@@ -347,12 +347,12 @@ class TwoTextColumnBlock(StructBlock):
     text_column_2 = RichTextBlock(label="Druhý sloupec textu")
 
     class Meta:
-        icon = "text"
+        icon = "doc-full"
         label = "Text ve dvou sloupcích"
 
 
 class CardLinkWithHeadlineBlock(CardLinkWithHeadlineBlockMixin):
-    card_items = ListBlock(CardLinkBlock(), label="Karty odkazu")
+    card_items = ListBlock(CardLinkBlock(), label="Karty s odkazy")
 
     class Meta:
         template = "main/blocks/card_link_with_headline_block.html"
@@ -384,3 +384,38 @@ class InstagramPostsBlock(StructBlock):
         template = "main/blocks/instagram_block.html"
         icon = "openquote"
         label = "Instagramové posty"
+
+
+class HoaxBlock(StructBlock):
+    title = CharBlock(label="Titulek")
+    hoax = RichTextBlock(label="Hoax")
+    image = ImageChooserBlock(label="Obrázek")
+    image_explanation = CharBlock(label="Popis obrázku", required=False)
+    reality = RichTextBlock(label="Realita")
+
+    class Meta:
+        icon = "view"
+        label = "Hoax"
+        template = "main/blocks/hoax_block.html"
+
+
+class TeamBlock(StructBlock):
+    title = CharBlock(label="Název sekce týmů")
+    slug = CharBlock(
+        label="Slug sekce",
+        required=False,
+        help_text="Není třeba vyplňovat, bude automaticky vyplněno",
+    )
+    team_list = ListBlock(
+        CardLinkWithHeadlineBlock(label="Karta týmu"),
+        label="Týmy",
+    )
+
+    class Meta:
+        icon = "group"
+        label = "Týmy"
+
+    def get_prep_value(self, value):
+        value = super().get_prep_value(value)
+        value["slug"] = slugify(value["title"])
+        return value
diff --git a/main/migrations/0046_alter_mainpeoplepage_options_and_more.py b/main/migrations/0046_alter_mainpeoplepage_options_and_more.py
new file mode 100644
index 0000000000000000000000000000000000000000..ddf9b7772e5354ed2d5a7e09e2515201afabe59f
--- /dev/null
+++ b/main/migrations/0046_alter_mainpeoplepage_options_and_more.py
@@ -0,0 +1,48 @@
+# Generated by Django 4.1.6 on 2023-02-28 08:10
+
+from django.db import migrations, models
+import django.db.models.deletion
+import shared.models
+import wagtail.blocks
+import wagtail.fields
+import wagtail.images.blocks
+import wagtailmetadata.models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('wagtailcore', '0083_workflowcontenttype'),
+        ('wagtailimages', '0025_alter_image_file_alter_rendition_file'),
+        ('main', '0045_alter_mainprogrampage_program'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='mainpeoplepage',
+            options={'verbose_name': 'Lidé a týmy'},
+        ),
+        migrations.AlterField(
+            model_name='maincrossroadpage',
+            name='headlined_cards_content',
+            field=wagtail.fields.StreamField([('headlined_cards', wagtail.blocks.StructBlock([('headline', wagtail.blocks.CharBlock(label='Titulek bloku', required=False)), ('card_items', wagtail.blocks.ListBlock(wagtail.blocks.StructBlock([('image', wagtail.images.blocks.ImageChooserBlock(label='Obrázek')), ('title', wagtail.blocks.CharBlock(label='Titulek', required=True)), ('text', wagtail.blocks.RichTextBlock(label='Krátký text pod nadpisem', required=False)), ('page', wagtail.blocks.PageChooserBlock(label='Stránka', page_type=['main.MainArticlesPage', 'main.MainArticlePage', 'main.MainProgramPage', 'main.MainPeoplePage', 'main.MainPersonPage', 'main.MainSimplePage', 'main.MainContactPage', 'main.MainCrossroadPage'], required=False)), ('link', wagtail.blocks.URLBlock(label='Odkaz', required=False))]), label='Karty s odkazy'))]))], blank=True, use_json_field=True, verbose_name='Karty rozcestníku s nadpisem'),
+        ),
+        migrations.AlterField(
+            model_name='mainpeoplepage',
+            name='people',
+            field=wagtail.fields.StreamField([('people_group', wagtail.blocks.StructBlock([('title', wagtail.blocks.CharBlock(label='Titulek')), ('slug', wagtail.blocks.CharBlock(help_text='Není třeba vyplňovat, bude automaticky vyplněno', label='Slug skupiny', required=False)), ('person_list', wagtail.blocks.ListBlock(wagtail.blocks.PageChooserBlock(label='Detail osoby', page_type=['main.MainPersonPage']), label='Skupina osob'))], label='Seznam osob')), ('team_group', wagtail.blocks.StructBlock([('title', wagtail.blocks.CharBlock(label='Název sekce týmů')), ('slug', wagtail.blocks.CharBlock(help_text='Není třeba vyplňovat, bude automaticky vyplněno', label='Slug sekce', required=False)), ('team_list', wagtail.blocks.ListBlock(wagtail.blocks.StructBlock([('headline', wagtail.blocks.CharBlock(label='Titulek bloku', required=False)), ('card_items', wagtail.blocks.ListBlock(wagtail.blocks.StructBlock([('image', wagtail.images.blocks.ImageChooserBlock(label='Obrázek')), ('title', wagtail.blocks.CharBlock(label='Titulek', required=True)), ('text', wagtail.blocks.RichTextBlock(label='Krátký text pod nadpisem', required=False)), ('page', wagtail.blocks.PageChooserBlock(label='Stránka', page_type=['main.MainArticlesPage', 'main.MainArticlePage', 'main.MainProgramPage', 'main.MainPeoplePage', 'main.MainPersonPage', 'main.MainSimplePage', 'main.MainContactPage', 'main.MainCrossroadPage'], required=False)), ('link', wagtail.blocks.URLBlock(label='Odkaz', required=False))]), label='Karty s odkazy'))], label='Karta týmu'), label='Týmy'))]))], blank=True, use_json_field=True, verbose_name='Lidé a týmy'),
+        ),
+        migrations.CreateModel(
+            name='MainHoaxPage',
+            fields=[
+                ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
+                ('description', wagtail.fields.RichTextField(blank=True, null=True, verbose_name='Popis')),
+                ('content', wagtail.fields.StreamField([('hoax', wagtail.blocks.StructBlock([('title', wagtail.blocks.CharBlock(label='Titulek')), ('hoax', wagtail.blocks.RichTextBlock(label='Hoax')), ('image', wagtail.images.blocks.ImageChooserBlock(label='Obrázek')), ('image_explanation', wagtail.blocks.RichTextBlock(label='Popis obrázku', required=False)), ('reality', wagtail.blocks.RichTextBlock(label='Realita'))]))], blank=True, use_json_field=True, verbose_name='Hoaxy a jejich vysvětlení')),
+                ('search_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.image', verbose_name='Search image')),
+            ],
+            options={
+                'verbose_name': 'Hoaxy',
+            },
+            bases=(shared.models.SubpageMixin, wagtailmetadata.models.WagtailImageMetadataMixin, 'wagtailcore.page', models.Model),
+        ),
+    ]
diff --git a/main/migrations/0047_alter_mainhoaxpage_content.py b/main/migrations/0047_alter_mainhoaxpage_content.py
new file mode 100644
index 0000000000000000000000000000000000000000..630f00253877cdcec277a64004698ec8262690be
--- /dev/null
+++ b/main/migrations/0047_alter_mainhoaxpage_content.py
@@ -0,0 +1,21 @@
+# Generated by Django 4.1.6 on 2023-02-28 10:03
+
+from django.db import migrations
+import wagtail.blocks
+import wagtail.fields
+import wagtail.images.blocks
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('main', '0046_alter_mainpeoplepage_options_and_more'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='mainhoaxpage',
+            name='content',
+            field=wagtail.fields.StreamField([('hoax', wagtail.blocks.StructBlock([('title', wagtail.blocks.CharBlock(label='Titulek')), ('hoax', wagtail.blocks.RichTextBlock(label='Hoax')), ('image', wagtail.images.blocks.ImageChooserBlock(label='Obrázek')), ('image_explanation', wagtail.blocks.CharBlock(label='Popis obrázku', required=False)), ('reality', wagtail.blocks.RichTextBlock(label='Realita'))]))], blank=True, use_json_field=True, verbose_name='Hoaxy a jejich vysvětlení'),
+        ),
+    ]
diff --git a/main/migrations/0053_merge_20230406_1446.py b/main/migrations/0053_merge_20230406_1446.py
new file mode 100644
index 0000000000000000000000000000000000000000..ce339473f5c0b340a512536e69ff186ace76c58d
--- /dev/null
+++ b/main/migrations/0053_merge_20230406_1446.py
@@ -0,0 +1,14 @@
+# Generated by Django 4.1.6 on 2023-04-06 12:46
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('main', '0047_alter_mainhoaxpage_content'),
+        ('main', '0052_remove_mainpersonpage_instagram_username_and_more'),
+    ]
+
+    operations = [
+    ]
diff --git a/main/models.py b/main/models.py
index ad75686395a44c3826aaeab84bc1513ce3a9b395..a28e04ff5a1ac273873c5bc723fe8c976e2a70e5 100644
--- a/main/models.py
+++ b/main/models.py
@@ -23,6 +23,7 @@ from wagtail.blocks import CharBlock, RichTextBlock
 from wagtail.contrib.routable_page.models import RoutablePageMixin, route
 from wagtail.fields import RichTextField, StreamField
 from wagtail.models import Page
+from wagtail.search import index
 from wagtailmetadata.models import MetadataPageMixin
 
 from elections2021.constants import REGION_CHOICES  # pozor, import ze sousedního modulu
@@ -182,6 +183,7 @@ class MainHomePage(
         "main.MainSimplePage",
         "main.MainContactPage",
         "main.MainCrossroadPage",
+        "main.MainHoaxPage",
     ]
 
     ### OTHERS
@@ -354,7 +356,7 @@ class MainHomePage(
 
 
 class MainArticlesPage(
-    ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, Page
+    RoutablePageMixin, ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, Page
 ):
     perex = models.TextField()
     last_import_log = models.TextField(
@@ -450,22 +452,23 @@ class MainArticlesPage(
 
         return article_data_list
 
-    def get_context(self, request, *args, **kwargs):
+    def get_context(self, request, get_articles: bool = True, *args, **kwargs):
         ctx = super().get_context(request, args, kwargs)
 
-        article_timeline_list = self.get_article_data_list(1)
-        ctx["article_timeline_list"] = article_timeline_list
-        ctx["show_next_timeline_articles"] = MainArticlePage.objects.filter(
-            article_type=ARTICLE_TYPES.WORK_TIMELINE
-        ).live().count() > len(article_timeline_list)
-
-        article_list = (
-            MainArticlePage.objects.filter(article_type=ARTICLE_TYPES.PRESS_RELEASE)
-            .order_by("-date")
-            .live()[:11]
-        )  # dám LIMIT +1, abych věděl, jestli má cenu show_next
-        ctx["article_article_list"] = article_list[:10]
-        ctx["show_next_article"] = len(article_list) > 10
+        if get_articles:
+            article_timeline_list = self.get_article_data_list(1)
+            ctx["article_timeline_list"] = article_timeline_list
+            ctx["show_next_timeline_articles"] = MainArticlePage.objects.filter(
+                article_type=ARTICLE_TYPES.WORK_TIMELINE
+            ).live().count() > len(article_timeline_list)
+
+            article_list = (
+                MainArticlePage.objects.filter(article_type=ARTICLE_TYPES.PRESS_RELEASE)
+                .order_by("-date")
+                .live()[:11]
+            )  # dám LIMIT +1, abych věděl, jestli má cenu show_next
+            ctx["article_article_list"] = article_list[:10]
+            ctx["show_next_article"] = len(article_list) > 10
 
         return ctx
 
@@ -502,12 +505,69 @@ class MainArticlesPage(
         }
         return JsonResponse(data=data, safe=False)
 
+    def get_all_articles_search_response(self, request):
+        article_paginator = Paginator(
+            MainArticlePage
+            .objects
+            .order_by("-date")
+            .live()
+            .search(request.GET["q"]),
+            10,
+        )
+        article_page = article_paginator.get_page(request.GET.get("page", 1))
+        context = {"article_data_list": article_page.object_list}
+        html_content = render(
+            request,
+            "main/includes/person_article_preview.html",
+            context
+        ).content
+        data = {
+            "html": html_content.decode("utf-8"),
+            "has_next": article_page.has_next(),
+        }
+        return JsonResponse(data=data, safe=False)
+
+    @cached_property
+    def search_url(self):
+        return self.url + self.reverse_subpage("search")
+
+    @route(r"^search")
+    def search(self, request):
+        if request.method == "GET" and "q" in request.GET:
+            query = request.GET["q"]
+            
+            article_results = (
+                MainArticlePage
+                .objects
+                .order_by("-date")
+                .live()
+                .search(query)
+                [:11]
+            )
+            
+            return render(
+                request,
+                "main/main_article_search.html",
+                {
+                    **self.get_context(request, get_articles=False),
+                    "query": query,
+                    "article_results": article_results[:10],
+                    "show_more_articles": len(article_results) > 10,
+                    "sub_heading": f"Vyhledávání „{query}“"
+                }
+            )
+        else:
+            return HttpResponseRedirect(self.url)
+
     def serve(self, request, *args, **kwargs):
         if request.META.get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest":
             if "months" in request.GET:
                 return self.get_timeline_articles_response(request)
             if "page" in request.GET:
-                return self.get_articles_response(request)
+                if "q" not in request.GET:
+                    return self.get_articles_response(request)
+                else:
+                    return self.get_all_articles_search_response(request)
 
         return super().serve(request, *args, **kwargs)
 
@@ -567,6 +627,14 @@ class MainArticlePage(
     )
     tags = ClusterTaggableManager(through=MainArticleTag, blank=True)
 
+    search_fields = Page.search_fields + [
+        index.SearchField("title"),
+        index.SearchField("author"),
+        index.SearchField("author_page"),
+        index.SearchField("perex"),
+        index.SearchField("content"),
+    ]
+
     ### PANELS
 
     content_panels = ArticleMixin.content_panels + [
@@ -642,8 +710,11 @@ class MainPeoplePage(ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin,
 
     perex = RichTextField()
     people = StreamField(
-        [("people_group", blocks.PeopleGroupBlock(label="Seznam osob"))],
-        verbose_name="Lidé",
+        [
+            ("people_group", blocks.PeopleGroupBlock(label="Seznam osob")),
+            ("team_group", blocks.TeamBlock()),
+        ],
+        verbose_name="Lidé a týmy",
         blank=True,
         use_json_field=True,
     )
@@ -659,12 +730,16 @@ class MainPeoplePage(ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin,
     ### RELATIONS
 
     parent_page_types = ["main.MainHomePage"]
-    subpage_types = ["main.MainPersonPage"]
+    subpage_types = [
+        "main.MainPersonPage",
+        "main.MainSimplePage",
+        "main.MainCrossroadPage",
+    ]
 
     ### OTHERS
 
     class Meta:
-        verbose_name = "Lidé"
+        verbose_name = "Lidé a týmy"
 
 
 class MainPersonPage(ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, Page):
@@ -813,6 +888,7 @@ class MainSimplePage(ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin,
         "main.MainHomePage",
         "main.MainSimplePage",
         "main.MainCrossroadPage",
+        "main.MainPeoplePage",
     ]
     subpage_types = ["main.MainSimplePage"]
 
@@ -900,6 +976,7 @@ class MainCrossroadPage(
     parent_page_types = [
         "main.MainHomePage",
         "main.MainCrossroadPage",
+        "main.MainPeoplePage",
     ]
     subpage_types = [
         "main.MainSimplePage",
@@ -909,3 +986,44 @@ class MainCrossroadPage(
 
     class Meta:
         verbose_name = "Rozcestník s kartami"
+
+
+class MainHoaxPage(
+    ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, Page
+):
+    ### FIELDS
+
+    description = RichTextField(
+        "Popis",
+        blank=True,
+        null=True,
+    )
+
+    content = StreamField(
+        [
+            (("hoax"), blocks.HoaxBlock())
+        ],
+        verbose_name="Hoaxy a jejich vysvětlení",
+        blank=True,
+        use_json_field=True,
+    )
+
+    ### PANELS
+
+    content_panels = Page.content_panels + [
+        FieldPanel("description"),
+        FieldPanel("content"),
+    ]
+
+    promote_panels = make_promote_panels()
+
+    settings_panels = []
+
+    ### RELATIONS
+
+    parent_page_types = ["main.MainHomePage"]
+    subpage_types = []
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Hoaxy"
diff --git a/main/static/main/images/hoax.webp b/main/static/main/images/hoax.webp
new file mode 100644
index 0000000000000000000000000000000000000000..08eaefd99c7cf520355f540c33f12f12079bb6b6
Binary files /dev/null and b/main/static/main/images/hoax.webp differ
diff --git a/main/static/main/images/person-table.png b/main/static/main/images/person-table.png
new file mode 100644
index 0000000000000000000000000000000000000000..7558ff7093d4618b37bb4e02f8171132851ea22b
Binary files /dev/null and b/main/static/main/images/person-table.png differ
diff --git a/main/templates/main/blocks/article_download_block.html b/main/templates/main/blocks/article_download_block.html
index 7f61e04febbb136f645e2a53802356206ed55909..102896e798c7e8e56dfee90eb9f996d90609e103 100644
--- a/main/templates/main/blocks/article_download_block.html
+++ b/main/templates/main/blocks/article_download_block.html
@@ -7,9 +7,12 @@
       <span class="font-bold mr-1">Stáhnout soubor: </span>
       <span class="overflow-hidden text-ellipsis">{{ self.file }}</span>
     </div>
-    <a href="{{ self.file.url }}" class="btn btn__slide__wrap h-11 p-0" download>
-      <span class="btn text-lg bg-black text-white w-32 lg:text-base">Stáhnout</span>
-      <span class="btn text-lg bg-white text-black w-32 lg:text-base">Stáhnout</span>
+    <a href="{{ self.file.url }}" class="btn btn--black btn--to-yellow-500 btn--hoveractive uppercase">
+      <span class="btn__body-wrap">
+        <span class="btn__body text-lg lg:text-base">
+          Stáhnout
+        </span>
+      </span>
     </a>
   </div>
 </div>
diff --git a/main/templates/main/blocks/card_link_with_headline_block.html b/main/templates/main/blocks/card_link_with_headline_block.html
index 7a5ce6c5debc4ebee91c83f4ff19b568404a4539..ef0b9003c743065de2a67d5d4535f5c809d215a2 100644
--- a/main/templates/main/blocks/card_link_with_headline_block.html
+++ b/main/templates/main/blocks/card_link_with_headline_block.html
@@ -4,9 +4,11 @@
   {% if self.headline %}
     <h2 class="head-4xl mt-5 mb-5">{{ self.headline }}</h2>
   {% endif %}
-  <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
+  <ul class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
     {% for card_block in self.card_items %}
-      {% include_block card_block %}
+      <li>
+        {% include_block card_block %}
+      </li>
     {% endfor %}
-  </div>
+  </ul>
 </div>
diff --git a/main/templates/main/blocks/hoax_block.html b/main/templates/main/blocks/hoax_block.html
new file mode 100644
index 0000000000000000000000000000000000000000..51c465b0d7026bf1c39c6ad202a42dd9bdce7274
--- /dev/null
+++ b/main/templates/main/blocks/hoax_block.html
@@ -0,0 +1,36 @@
+{% load wagtailimages_tags wagtailcore_tags static %}
+{% image self.image width-800 as img %}
+
+<ui-popout>
+  <template slot="toggler">
+    {{ self.title }}
+  </template>
+  <ui-popout-content>
+    <div class="flex flex-wrap gap-4 lg:flex-nowrap">
+      <div class="grow lg:grow-0 lg:basis-2/3 max-w-screen-lg">
+        <div class="prose max-w-none">
+          {{ self.hoax|richtext }}
+        </div>
+        <img
+          class="mt-10"
+          src="{% static "main/images/hoax.webp" %}"
+          alt="Hoax"
+        >
+        <h3 class="head-2xl mt-10">Jak to je?</h3>
+        <div class="prose max-w-none">
+          {{ self.reality|richtext }}
+        </div>
+      </div>
+      <div class="lg:basis-1/3">
+        <img
+          class="w-full mb-3"
+          src="{{ img.url }}"
+          alt="{{ img.alt }}"
+        >
+        <small class="text-grey-300">
+          <i>{{ self.image_explanation }}</i>
+        </small>
+      </div>
+    </div>
+  </ui-popout-content>
+</ui-popout> 
diff --git a/main/templates/main/includes/layout/person_photo_page_header.html b/main/templates/main/includes/layout/person_photo_page_header.html
index 6ff48840d83c4e9df921d2cc634dac75dfa49b60..159958958aa990c7f278eaba8c72730ea134b453 100644
--- a/main/templates/main/includes/layout/person_photo_page_header.html
+++ b/main/templates/main/includes/layout/person_photo_page_header.html
@@ -5,12 +5,22 @@
   style="background-image: url('{{ image_url | default_if_none:"https://cc.cz/wp-content/uploads/2022/04/bartos-otv.jpg" }}')"
 >
   <div class="grid-container header-max-width pt-16">
-  <div class="pl-4 pr-2 col-start-1 col-end-3 sm:col-start-2 sm:col-end-13 sm:pr-0">
-    <h1 class="font-alt text-white">
-      <span class="text-2xl">{{ before_title | default_if_none:"" }}</span><br>
-      <span class="font-alt text-7xl">{{ page.title | default_if_none:"" }}</span><span class="text-2xl">{{ after_title | default_if_none:"" }}</span><br>
-      <span class="font-alt">{{ subtitle | default_if_none:"" }}</span>
-    </h1>
+    <div class="pl-4 pr-2 col-start-1 col-end-3 sm:col-start-2 sm:col-end-13 sm:pr-0">
+      <h1 class="font-alt text-white">
+        <span class="text-xl sm:text-2xl">{{ before_title | default_if_none:"" }}</span><br>
+        
+        <div class="flex items-baseline flex-col sm:flex-row">
+          <span class="font-alt text-6xl sm:text-7xl grow sm:grow-0">{{ page.title | default_if_none:"" }}</span>
+          {% if after_title %}
+            <span class="text-xl sm:text-2xl">
+              <span class="text-xl hidden sm:text-2xl sm:inline">, </span>{{ after_title }}
+            </span>
+          {% endif %}
+        </div>
+        <br>
+        
+        <span class="font-alt">{{ subtitle | default_if_none:"" }}</span>
+      </h1>
+    </div>
   </div>
-      </div>
 </header>
diff --git a/main/templates/main/includes/layout/simple_page_header.html b/main/templates/main/includes/layout/simple_page_header.html
index 0c3f226422cc12e2c43c499145947779efbdc124..209527a2c5cc13a71cde147a292c8a0f5f520357 100644
--- a/main/templates/main/includes/layout/simple_page_header.html
+++ b/main/templates/main/includes/layout/simple_page_header.html
@@ -4,6 +4,11 @@
       <h1 class="head-8xl text-white">
         {{ page.title }}
       </h1>
+      {% if sub_heading %}
+        <h2 class="head-3xl text-white">
+          {{ sub_heading }}
+        </h2>
+      {% endif %}
     </div>
   </div>
 </header>
diff --git a/main/templates/main/includes/newsletter_section.html b/main/templates/main/includes/newsletter_section.html
index 8366bdc5af4364bcf40aec7c1549621661f7fa38..34700766c514e1ebfa4f13dd092f6f99b5817e85 100644
--- a/main/templates/main/includes/newsletter_section.html
+++ b/main/templates/main/includes/newsletter_section.html
@@ -9,7 +9,7 @@
       <img src="{% static 'main/images/lahev.svg' %}" alt="newsletter_icon" class="newsletter-grid__icon text-7xl xl:text-9xl w-32">
     </div>
     <div>
-      <h5 class="font-alt mb-2 text-6xl xl:text-7xl uppercase">
+      <h5 class="font-alt mb-2 text-5xl md:text-6xl xl:text-7xl uppercase">
         Odebírej náš newsletter
       </h5>
       <span class="inline-block uppercase text-xl xl:text-base font-bold mb-4 xl:w-full">
diff --git a/main/templates/main/main_article_search.html b/main/templates/main/main_article_search.html
new file mode 100644
index 0000000000000000000000000000000000000000..4031c09f7081f91257819bb31c2b83a03af889f1
--- /dev/null
+++ b/main/templates/main/main_article_search.html
@@ -0,0 +1,108 @@
+{% extends "main/base.html" %}
+{% load wagtailcore_tags wagtailimages_tags shared_filters %}
+
+{% block content %}
+  {% include 'main/includes/layout/simple_page_header.html' with sub_heading=sub_heading %}
+
+  <main role="main">
+    <div class="__js-root">
+      <div class="grid-container article-section mb-8">
+        <div class="grid-full">
+          <div class="flex justify-center">
+            <div class="flex flex-col items-end gap-3">
+              <form
+                class="flex flex-row"
+                method="get"
+                action="{{ page.search_url }}"
+              >
+                <input
+                  class="bg-grey-150 w-56 h-10 px-4 text-lg xl:h-14 xl:px-5"
+                  type="text"
+                  id="q"
+                  name="q"
+                  value="{{ query }}"
+                  placeholder="Hledat články..."
+                  aria-label="Vyhledávací box"
+                >
+                <button
+                  class="btn btn--yellow-500 btn--to-yellow-600 btn--hoveractive"
+                  aria-label="Vyhledat"
+                  type="submit"
+                >
+                  <div class="btn__body-wrap h-10 w-12 min-h-0 min-w-0 xl:h-14 xl:w-14">
+                    <div class="btn__body p-0">
+                      <i class="ico--search"></i>
+                    </div>
+                  </div>
+                </button>
+              </form>
+              <a href="{{ page.url }}" class="btn btn--black btn--to-yellow-500 btn--hoveractive uppercase">
+                <span class="btn__body-wrap">
+                  <span class="btn__body text-lg lg:text-base">
+                    Zpět na seznam
+                  </span>
+                </span>
+              </a>
+            </div>
+          </div>
+        </div>
+      </div>
+      <section class="mb-3 xl:mb-14">
+        {% if article_results %}
+          <div id="searchArticleResultWrapper">
+            {% include 'main/includes/person_article_preview.html' with article_data_list=article_results %}
+          </div>
+          {% if show_more_articles %}
+            <div class="grid-container">
+              <div class="grid-content-with-right-side">
+                <a
+                  onclick="showMoreArticles(event, this)"
+                  href="#"
+                  data-url="{{ page_url }}"
+                  data-page="2"
+                  data-query="{{ query }}"
+                  class="btn btn--black btn--to-yellow-500 btn--hoveractive uppercase"
+                >
+                  <span class="btn__body-wrap">
+                      <span class="btn__body text-lg lg:text-base">
+                        Zobrazit další
+                      </span>
+                  </span>
+                </a>
+              </div>
+            </div>
+          {% endif %}
+        {% else %}
+          <div class="grid-container article-section mb-8">
+            <div class="grid-full">
+              <p class="text-grey-300 text-center">Žádné výsledky.</p>
+            </div>
+          </div>
+        {% endif %}
+      </section>
+      {% include "main/includes/newsletter_section.html" %}
+    </div>
+  </main>
+  
+  <script type="text/javascript">
+    async function showMoreArticles(event, btn) {
+      event.preventDefault()
+
+      let searchArticleResultWrapper = document.getElementById('searchArticleResultWrapper')
+      let url = (
+        btn.getAttribute('data-url')
+        + `?page=${btn.getAttribute('data-page')}`
+        + `&q=${btn.getAttribute('data-query')}`
+      )
+
+      const response = await fetch(url, {
+        method: "GET",
+        headers: {"X-Requested-With": "XMLHttpRequest"},
+      })
+      const data = await response.json()
+      searchArticleResultWrapper.innerHTML += data.html;
+      if (!data.has_next) { btn.style.display = 'none'; }
+      btn.setAttribute('data-page', parseInt(btn.getAttribute('data-page')) + 1)
+    }
+  </script>
+{% endblock content %}
diff --git a/main/templates/main/main_articles_page.html b/main/templates/main/main_articles_page.html
index 7ecdaa08378bedaf9030a3868063e2c59132413c..c26727f49e8b429b7b94dbb61292bee33de04d3f 100644
--- a/main/templates/main/main_articles_page.html
+++ b/main/templates/main/main_articles_page.html
@@ -20,13 +20,40 @@
                         v-slot="{ isCurrentView, toggleView }">
         <div class="grid-container article-section mb-8">
           <div class="grid-full">
-            <div class="flex justify-center">
+            <div class="flex flex-col items-center">
               <div class="switch">
                 <a @click="toggleView('timeline')" class="switch__item"
                    :class="{'switch__item--active': isCurrentView('timeline')}">Aktuality</a>
                 <a @click="toggleView('articles')" class="switch__item"
                    :class="{'switch__item--active': isCurrentView('articles')}">Tiskové zprávy</a>
               </div>
+              <div class="xl:mt-3">
+                <form
+                  class="flex flex-row"
+                  method="get"
+                  action="{{ page.search_url }}"
+                >
+                  <input
+                    class="bg-grey-150 w-56 h-10 px-4 text-lg xl:h-14 xl:px-5"
+                    type="text"
+                    id="q"
+                    name="q"
+                    placeholder="Hledat články..."
+                    aria-label="Vyhledávací box"
+                  >
+                  <button
+                    class="btn btn--yellow-500 btn--to-yellow-600 btn--hoveractive"
+                    aria-label="Vyhledat"
+                    type="submit"
+                  >
+                    <div class="btn__body-wrap h-10 w-12 min-h-0 min-w-0 xl:h-14 xl:w-14">
+                      <div class="btn__body p-0">
+                        <i class="ico--search"></i>
+                      </div>
+                    </div>
+                  </button>
+                </form>
+              </div>
             </div>
           </div>
         </div>
diff --git a/main/templates/main/main_hoax_page.html b/main/templates/main/main_hoax_page.html
new file mode 100644
index 0000000000000000000000000000000000000000..6bfac594994cfd0c5b12db3f0088a93891a13c18
--- /dev/null
+++ b/main/templates/main/main_hoax_page.html
@@ -0,0 +1,24 @@
+{% extends "main/base.html" %}
+{% load wagtailcore_tags %}
+
+{% block content %}
+  {% include 'main/includes/layout/simple_page_header.html' %}
+  <main role="main" class="mb-10 xl:mb-32 __js-root">
+    {% if page.description %}
+      <div class="grid-container mb-2 lg:mb-12">
+        <div class="grid-content">
+          <div class="prose max-w-none font-condensed text-xl text-black leading-7 mb-12 program-perex">
+            {{ page.description|richtext }}
+          </div>
+        </div>
+      </div>
+    {% endif %}
+    <div class="grid-container mb-2 lg:mb-12">
+      <div class="grid-left-side-with-content">
+        {% for block in page.content %}
+          {% include_block block %}
+        {% endfor %}
+      </div>
+    </div>
+  </main>
+{% endblock %}
diff --git a/main/templates/main/main_people_page.html b/main/templates/main/main_people_page.html
index 8f535c9d070d94a936f6c262a123d29d91435558..01ae7b43d9c3a787279d50b5a02e9349aecc5cb5 100644
--- a/main/templates/main/main_people_page.html
+++ b/main/templates/main/main_people_page.html
@@ -34,14 +34,27 @@
           </ui-horizontal-scrollable>
         </div>
         <div class="flex flex-wrap gap-4">
-          {% for people_group in page.people %}
-            <template v-if="isCurrentView('{{ people_group.value.slug }}-{{ forloop.counter }}')">
-              {% for person_page in people_group.value.person_list %}
-                {% include 'main/includes/person_contact_big.html' %}
-              {% endfor %}
+          {% for block in page.people %}
+            <template v-if="isCurrentView('{{ block.value.slug }}-{{ forloop.counter }}')">
+              {% if block.block_type == "people_group" %}
+                {% for person_page in block.value.person_list %}
+                  {% include 'main/includes/person_contact_big.html' %}
+                {% endfor %}
+              {% endif %}
             </template>
           {% endfor %}
         </div>
+        {% for block in page.people %}
+          <template v-if="isCurrentView('{{ block.value.slug }}-{{ forloop.counter }}')">
+            <div class="grid-left-side-with-content">
+              {% if block.block_type == "team_group" %}
+                {% for card_block in block.value.team_list %}
+                  {% include_block card_block %}
+                {% endfor %}
+              {% endif %}
+            </div>
+          </template>
+        {% endfor %}
       </ui-view-provider>
     </div>
   </div>
diff --git a/shared/blocks.py b/shared/blocks.py
index 1ca1526d574710b5245fe4e7522f21231bb3e98f..10249fced114a2d55ebdbd1f5c9b877bde9c24a8 100644
--- a/shared/blocks.py
+++ b/shared/blocks.py
@@ -628,7 +628,7 @@ class CardLinkBlockMixin(blocks.StructBlock):
     class Meta:
         # template = ""
         icon = "link"
-        label = "Karta odkazu"
+        label = "Karta s odkazem"
 
     def clean(self, value):
         errors = {}
@@ -650,7 +650,7 @@ class CardLinkBlockMixin(blocks.StructBlock):
 
 class CardLinkWithHeadlineBlockMixin(blocks.StructBlock):
     headline = blocks.CharBlock(label="Titulek bloku", required=False)
-    card_items = blocks.ListBlock(CardLinkBlockMixin(), label="Karty odkazu")
+    card_items = blocks.ListBlock(CardLinkBlockMixin(), label="Karty s odkazy")
 
     class Meta:
         # template = ""
diff --git a/uniweb/blocks.py b/uniweb/blocks.py
new file mode 100644
index 0000000000000000000000000000000000000000..1aaf9c48bca5524a4594ef6f237a453fb736c356
--- /dev/null
+++ b/uniweb/blocks.py
@@ -0,0 +1,42 @@
+from wagtail.blocks import (
+    CharBlock,
+    ListBlock,
+    PageChooserBlock,
+    StructBlock,
+    URLBlock,
+)
+
+
+class PersonUrlBlock(StructBlock):
+    title = CharBlock(label="Název", required=True)
+    url = URLBlock(label="URL", required=True)
+    custom_icon = CharBlock(
+        label="Vlastní ikonka ze styleguide",
+        required=False,
+        help_text="Pro vlastní ikonku zadejde název ikonky z https://styleguide.pirati.cz/latest/?p=viewall-atoms-icons (bez tečky), např. 'ico--beer'",
+    )
+
+
+class PersonCustomPositionBlock(StructBlock):
+    position = CharBlock(label="Název pozice", required=False)
+    person = PageChooserBlock(
+        label="Osoba",
+        page_type=["uniweb.UniwebPersonPage"],
+    )
+
+    class Meta:
+        icon = "user"
+        label = "Osoba s volitelnou pozicí"
+
+
+class PeopleGroupListBlock(StructBlock):
+    group_title = CharBlock(label="Titulek", required=True)
+    person_list = ListBlock(
+        PersonCustomPositionBlock(),
+        label="List osob",
+    )
+
+    class Meta:
+        template = "uniweb/blocks/people_group_block.html"
+        icon = "list-ul"
+        label = "Skupina členů" 
diff --git a/uniweb/migrations/0038_uniwebpersonpage_uniwebpeoplepage.py b/uniweb/migrations/0038_uniwebpersonpage_uniwebpeoplepage.py
new file mode 100644
index 0000000000000000000000000000000000000000..aa8762745cfffa846f5ba15f7324f107056ee32d
--- /dev/null
+++ b/uniweb/migrations/0038_uniwebpersonpage_uniwebpeoplepage.py
@@ -0,0 +1,64 @@
+# Generated by Django 4.1.6 on 2023-03-09 23:46
+
+from django.db import migrations, models
+import django.db.models.deletion
+import shared.models
+import wagtail.blocks
+import wagtail.fields
+import wagtailmetadata.models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('wagtailcore', '0083_workflowcontenttype'),
+        ('wagtailimages', '0025_alter_image_file_alter_rendition_file'),
+        ('uniweb', '0037_alter_uniwebflexiblepage_content_and_more'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='UniwebPersonPage',
+            fields=[
+                ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
+                ('job', models.CharField(blank=True, help_text="Např. 'Informatik'", max_length=128, null=True, verbose_name='Povolání')),
+                ('job_function', models.CharField(blank=True, help_text="Např. 'Předseda'", max_length=128, null=True, verbose_name='Funkce')),
+                ('text', wagtail.fields.RichTextField(blank=True, verbose_name='text')),
+                ('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='Email')),
+                ('show_email', models.BooleanField(default=True, verbose_name='Zobrazovat email na stránce?')),
+                ('phone', models.CharField(blank=True, max_length=16, null=True, verbose_name='Telefon')),
+                ('city', models.CharField(blank=True, max_length=64, null=True, verbose_name='Město/obec')),
+                ('age', models.IntegerField(blank=True, null=True, verbose_name='Věk')),
+                ('is_pirate', models.BooleanField(default=True, verbose_name='Je členem Pirátské strany?')),
+                ('other_party', models.CharField(blank=True, help_text='Vyplňte pokud osoba není Pirát', max_length=64, null=True, verbose_name='Strana')),
+                ('facebook_url', models.URLField(blank=True, null=True, verbose_name='Odkaz na Facebook')),
+                ('instagram_url', models.URLField(blank=True, null=True, verbose_name='Odkaz na Instagram')),
+                ('twitter_url', models.URLField(blank=True, null=True, verbose_name='Odkaz na Twitter')),
+                ('youtube_url', models.URLField(blank=True, null=True, verbose_name='Odkaz na Youtube kanál')),
+                ('flickr_url', models.URLField(blank=True, null=True, verbose_name='Odkaz na Flickr')),
+                ('custom_web_url', models.URLField(blank=True, null=True, verbose_name='Odkaz na vlastní web')),
+                ('other_urls', wagtail.fields.StreamField([('other_url', wagtail.blocks.StructBlock([('title', wagtail.blocks.CharBlock(label='Název', required=True)), ('url', wagtail.blocks.URLBlock(label='URL', required=True)), ('custom_icon', wagtail.blocks.CharBlock(help_text="Pro vlastní ikonku zadejde název ikonky z https://styleguide.pirati.cz/latest/?p=viewall-atoms-icons (bez tečky), např. 'ico--beer'", label='Vlastní ikonka ze styleguide', required=False))]))], blank=True, use_json_field=True, verbose_name='Další odkaz')),
+                ('background_photo', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='wagtailimages.image', verbose_name='obrázek do záhlaví')),
+                ('other_party_logo', models.ForeignKey(blank=True, help_text='Vyplňte pokud osoba není Pirát', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='wagtailimages.image', verbose_name='Logo strany')),
+                ('profile_photo', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='wagtailimages.image', verbose_name='profilová fotka')),
+                ('search_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.image', verbose_name='Search image')),
+            ],
+            options={
+                'verbose_name': 'Detail osoby',
+                'ordering': ('title',),
+            },
+            bases=(shared.models.SubpageMixin, wagtailmetadata.models.WagtailImageMetadataMixin, 'wagtailcore.page', models.Model),
+        ),
+        migrations.CreateModel(
+            name='UniwebPeoplePage',
+            fields=[
+                ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
+                ('content', wagtail.fields.StreamField([('text', wagtail.blocks.RichTextBlock(features=['h2', 'h3', 'h4', 'h5', 'bold', 'italic', 'ol', 'ul', 'hr', 'link', 'document-link', 'image', 'superscript', 'subscript', 'strikethrough', 'blockquote', 'embed'], label='Textový editor')), ('people_group', wagtail.blocks.StructBlock([('group_title', wagtail.blocks.CharBlock(label='Titulek', required=True)), ('person_list', wagtail.blocks.ListBlock(wagtail.blocks.StructBlock([('position', wagtail.blocks.CharBlock(label='Název pozice', required=False)), ('person', wagtail.blocks.PageChooserBlock(label='Osoba', page_type=['uniweb.UniwebPersonPage']))]), label='List osob'))]))], blank=True, use_json_field=True, verbose_name='Obsah stránky')),
+                ('search_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.image', verbose_name='Search image')),
+            ],
+            options={
+                'verbose_name': 'Lidé',
+            },
+            bases=(shared.models.SubpageMixin, wagtailmetadata.models.WagtailImageMetadataMixin, 'wagtailcore.page', models.Model),
+        ),
+    ]
diff --git a/uniweb/migrations/0039_alter_uniwebhomepage_top_menu.py b/uniweb/migrations/0039_alter_uniwebhomepage_top_menu.py
new file mode 100644
index 0000000000000000000000000000000000000000..7d2e980e4d180e76cc14b0287d5d0789b75f4bc2
--- /dev/null
+++ b/uniweb/migrations/0039_alter_uniwebhomepage_top_menu.py
@@ -0,0 +1,20 @@
+# Generated by Django 4.1.6 on 2023-03-13 09:58
+
+from django.db import migrations
+import wagtail.blocks
+import wagtail.fields
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('uniweb', '0038_uniwebpersonpage_uniwebpeoplepage'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='uniwebhomepage',
+            name='top_menu',
+            field=wagtail.fields.StreamField([('item', wagtail.blocks.StructBlock([('name', wagtail.blocks.CharBlock(label='název')), ('page', wagtail.blocks.PageChooserBlock(label='stránka', page_type=['uniweb.UniwebHomePage', 'uniweb.UniwebFlexiblePage', 'uniweb.UniwebArticlesIndexPage', 'uniweb.UniwebFormPage', 'uniweb.UniwebPeoplePage', 'uniweb.UniwebPersonPage']))]))], blank=True, use_json_field=True, verbose_name='horní menu'),
+        ),
+    ]
diff --git a/uniweb/models.py b/uniweb/models.py
index e6b613cf50ee0eddeaf417428af235fa41ef0cf4..e68eb96c9918f7090a39b255b5adfbb71338d39d 100644
--- a/uniweb/models.py
+++ b/uniweb/models.py
@@ -17,13 +17,14 @@ from wagtail.admin.panels import (
 from wagtail.contrib.forms.models import AbstractForm, AbstractFormField
 from wagtail.contrib.forms.panels import FormSubmissionsPanel
 from wagtail.contrib.table_block.blocks import TableBlock
-from wagtail.fields import StreamField
+from wagtail.fields import RichTextField, StreamField
 from wagtail.images.blocks import ImageChooserBlock
 from wagtail.models import Page
 from wagtailmetadata.models import MetadataPageMixin
 
 from calendar_utils.models import CalendarMixin
 from shared.blocks import ChartBlock
+from shared.const import RICH_TEXT_DEFAULT_FEATURES
 from shared.models import (
     ArticleMixin,
     ExtendedMetadataHomePageMixin,
@@ -33,6 +34,11 @@ from shared.models import (
 from shared.utils import make_promote_panels
 from tuning import admin_help
 
+from .blocks import (
+    PersonCustomPositionBlock,
+    PeopleGroupListBlock,
+    PersonUrlBlock,
+)
 from .constants import (
     ALIGN_CHOICES,
     ALIGN_CSS,
@@ -196,6 +202,8 @@ class MenuItemBlock(blocks.StructBlock):
             "uniweb.UniwebFlexiblePage",
             "uniweb.UniwebArticlesIndexPage",
             "uniweb.UniwebFormPage",
+            "uniweb.UniwebPeoplePage",
+            "uniweb.UniwebPersonPage",
         ],
     )
 
@@ -381,6 +389,7 @@ class UniwebHomePage(
         "uniweb.UniwebFlexiblePage",
         "uniweb.UniwebArticlesIndexPage",
         "uniweb.UniwebFormPage",
+        "uniweb.UniwebPeoplePage",
     ]
 
     ### OTHERS
@@ -580,3 +589,204 @@ class UniwebFormPage(
         form = super().get_form_class()
         form.base_fields["captcha"] = CaptchaField(label="opište písmena z obrázku")
         return form
+
+
+# Don't waste time making a new mixin for this,
+# we'll be doing Octopus imports within a short while.
+class UniwebPersonPage(
+    ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, Page
+):
+    ### FIELDS
+    job = models.CharField(
+        "Povolání",
+        max_length=128,
+        blank=True,
+        null=True,
+        help_text="Např. 'Informatik'",
+    )
+    job_function = models.CharField(
+        "Funkce", max_length=128, blank=True, null=True, help_text="Např. 'Předseda'"
+    )
+    background_photo = models.ForeignKey(
+        "wagtailimages.Image",
+        on_delete=models.PROTECT,
+        blank=True,
+        null=True,
+        related_name="+",
+        verbose_name="obrázek do záhlaví",
+    )
+    profile_photo = models.ForeignKey(
+        "wagtailimages.Image",
+        on_delete=models.PROTECT,
+        blank=True,
+        null=True,
+        related_name="+",
+        verbose_name="profilová fotka",
+    )
+    text = RichTextField("text", blank=True, features=RICH_TEXT_DEFAULT_FEATURES)
+
+    email = models.EmailField("Email", null=True, blank=True)
+    show_email = models.BooleanField("Zobrazovat email na stránce?", default=True)
+    phone = models.CharField("Telefon", max_length=16, blank=True, null=True)
+    city = models.CharField("Město/obec", max_length=64, blank=True, null=True)
+    age = models.IntegerField("Věk", blank=True, null=True)
+    is_pirate = models.BooleanField("Je členem Pirátské strany?", default=True)
+    other_party = models.CharField(
+        "Strana",
+        max_length=64,
+        blank=True,
+        null=True,
+        help_text="Vyplňte pokud osoba není Pirát",
+    )
+    other_party_logo = models.ForeignKey(
+        "wagtailimages.Image",
+        on_delete=models.PROTECT,
+        blank=True,
+        null=True,
+        related_name="+",
+        verbose_name="Logo strany",
+        help_text="Vyplňte pokud osoba není Pirát",
+    )
+
+    facebook_url = models.URLField("Odkaz na Facebook", blank=True, null=True)
+    instagram_url = models.URLField("Odkaz na Instagram", blank=True, null=True)
+    twitter_url = models.URLField("Odkaz na Twitter", blank=True, null=True)
+    youtube_url = models.URLField("Odkaz na Youtube kanál", blank=True, null=True)
+    flickr_url = models.URLField("Odkaz na Flickr", blank=True, null=True)
+    custom_web_url = models.URLField("Odkaz na vlastní web", blank=True, null=True)
+    other_urls = StreamField(
+        [("other_url", PersonUrlBlock())],
+        verbose_name="Další odkaz",
+        blank=True,
+        use_json_field=True,
+    )
+
+    ### PANELS
+
+    content_panels = Page.content_panels + [
+        MultiFieldPanel(
+            [
+                FieldPanel("job"),
+                FieldPanel("job_function"),
+            ],
+            "Základní údaje",
+        ),
+        MultiFieldPanel(
+            [
+                FieldPanel("profile_photo"),
+                FieldPanel("background_photo"),
+            ],
+            "Fotky",
+        ),
+        FieldPanel("text"),
+        MultiFieldPanel(
+            [
+                FieldPanel("email"),
+                FieldPanel("show_email"),
+                FieldPanel("phone"),
+                FieldPanel("city"),
+                FieldPanel("age"),
+                FieldPanel("is_pirate"),
+                FieldPanel("other_party"),
+                FieldPanel("other_party_logo"),
+            ],
+            "Kontaktní informace",
+        ),
+        MultiFieldPanel(
+            [
+                FieldPanel("facebook_url"),
+                FieldPanel("instagram_url"),
+                FieldPanel("twitter_url"),
+                FieldPanel("youtube_url"),
+                FieldPanel("flickr_url"),
+                FieldPanel("custom_web_url"),
+                FieldPanel("other_urls"),
+            ],
+            "Sociální sítě",
+        ),
+    ]
+
+    settings_panels = []
+
+    ### RELATIONS
+
+    parent_page_types = ["uniweb.UniwebPeoplePage"]
+    subpage_types = []
+
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Detail osoby"
+        ordering = ("title",)
+
+    def get_background_photo(self):
+        """
+        Vrací background_photo pro pozadí na stránce, pokud není nastaveno,
+        vezme falbback z homepage
+        """
+        return (
+            self.background_photo
+            if self.background_photo
+            else self.root_page.fallback_image
+        )
+
+    def get_context(self, request):
+        context = super().get_context(request)
+        # Na strance detailu cloveka se vpravo zobrazuji 3 dalsi nahodne profily
+        context["random_people"] = list(
+            self.get_siblings(inclusive=False).live().specific()
+        )
+        random.shuffle(context["random_people"])
+        context["random_people"] = context["random_people"][:3]
+        return context
+
+    def get_meta_image(self):
+        return self.search_image or self.profile_photo
+
+    def get_meta_description(self):
+        if self.search_description:
+            return self.search_description
+
+        if self.text:
+            return trim_to_length(strip_all_html_tags(self.text))
+
+        return None
+
+
+class UniwebPeoplePage(
+    ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, Page
+):
+    ### FIELDS
+
+    content = StreamField(
+        [
+            (
+                "text",
+                blocks.RichTextBlock(
+                    label="Textový editor", features=RICH_TEXT_DEFAULT_FEATURES
+                ),
+            ),
+            ("people_group", PeopleGroupListBlock()),
+        ],
+        verbose_name="Obsah stránky",
+        blank=True,
+        use_json_field=True,
+    )
+
+    ### PANELS
+
+    content_panels = Page.content_panels + [FieldPanel("content")]
+
+    promote_panels = make_promote_panels()
+
+    settings_panels = []
+
+    ### RELATIONS
+
+    parent_page_types = ["uniweb.UniwebHomePage"]
+    subpage_types = ["uniweb.UniwebPersonPage"]
+
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Lidé"
diff --git a/uniweb/templates/uniweb/blocks/people_group_block.html b/uniweb/templates/uniweb/blocks/people_group_block.html
new file mode 100644
index 0000000000000000000000000000000000000000..752458f02285438ff0a0e9c5d014660541bca857
--- /dev/null
+++ b/uniweb/templates/uniweb/blocks/people_group_block.html
@@ -0,0 +1,12 @@
+<section>
+  <h2 class="head-heavy-base mb-4">
+    {{ self.group_title }}
+  </h2>
+  <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 row-gap-8 col-gap-8">
+    {% for person_details in self.person_list %}
+        {% with person_details.person as person_page %}
+            {% include "shared/person_badge_snippet.html" with title=person_details.position|default:person_page.job_function %}
+        {% endwith %}
+    {% endfor %}
+  </div>
+</section>
diff --git a/uniweb/templates/uniweb/uniweb_people_page.html b/uniweb/templates/uniweb/uniweb_people_page.html
new file mode 100644
index 0000000000000000000000000000000000000000..03470d5c7efe3d27be19391583e7c8816fc321bb
--- /dev/null
+++ b/uniweb/templates/uniweb/uniweb_people_page.html
@@ -0,0 +1,17 @@
+{% extends "uniweb/base.html" %}
+{% load wagtailcore_tags wagtailimages_tags shared_filters %}
+
+{% block content %}
+  <header>
+    <h1 itemprop="headline" class="head-alt-md md:head-alt-lg max-w-5xl mb-8">
+      {{ page.title }}
+    </h1>
+  </header>
+
+  {% for block in page.content %}
+    {% include_block block %}
+    {% if not forloop.last %}
+      <hr class="hr--big">
+    {% endif %}
+  {% endfor %}
+{% endblock %}
diff --git a/uniweb/templates/uniweb/uniweb_person_page.html b/uniweb/templates/uniweb/uniweb_person_page.html
new file mode 100644
index 0000000000000000000000000000000000000000..9d1b880fd2358eddf11323037e7caa2a60c8bc06
--- /dev/null
+++ b/uniweb/templates/uniweb/uniweb_person_page.html
@@ -0,0 +1,179 @@
+{% extends "uniweb/base.html" %}
+{% load static wagtailcore_tags wagtailimages_tags shared_filters %}
+
+{% block subheader %}
+  {% image page.get_background_photo fill-1920x500-c75 jpegquality-80 as bg_img %}
+
+  <header class="hero hero--image pt-16 pb-24 lg:pt-32 pb-24" style="--image-url: url({{ bg_img.full_url }})">
+    <div class="container container--default text-center lg:text-left">
+      <h1 class="head-alt-lg md:head-alt-xl text-shadow-lg max-w-2xl">
+        {{ page.title }}
+      </h1>
+      <h2 class="head-xs text-shadow-lg mt-2 max-w-xl">
+        {{ page.job | default_if_none:"" }}
+      </h2>
+    </div>
+  </header>
+{% endblock %}
+
+{% block container_spacing %}py-8 lg:pb-16{% endblock %}
+
+{% block content %}
+  <div class="flex flex-col lg:flex-row lg:space-x-8 xl:space-x-16">
+    <section class="lg:w-3/5 xl:w-2/3">
+      <div class="content-block w-full">
+        {{ page.text|richtext }}
+      </div>
+    </section>
+
+    <section class="lg:w-2/5 xl:w-1/3 pt-8 lg:pt-0 order-first lg:order-last candidate-detail__sidebar">
+      <div class="container-padding--zero lg:card lg:elevation-10 lg:container-padding--auto">
+        <div class="card__body p-4 lg:p-8">
+          <div class="text-center mb-8">
+            <div class="avatar avatar--2xl lg:avatar--3xl avatar--bordered candidate-detail__avatar">
+              {% if page.profile_photo %}
+                {% image page.profile_photo fill-208x208 as profile_img %}
+                {% image page.profile_photo fill-416x416 as profile_img_2x %}
+                <img src="{{ profile_img.url }}" srcset="{{ profile_img.url }}, {{ profile_img_2x.url }} 2x" alt="{{ page.profile_photo }}">
+              {% else %}
+                <img src="{% static "shared/img/unknown_pirate_416x416.jpg" %}" alt="{{ person_page.title }}"/>
+              {% endif%}
+            </div>
+
+          </div>
+          {% if page.facebook_url or page.instagram_url or page.twitter_url or page.youtube_url or page.flickr_url or page.custom_web_url or page.other_urls %}
+            <div class="social-icon-group space-x-2 text-lg">
+              {% if page.facebook_url %}
+                <a href="{{ page.facebook_url }}" target="_blank" class="social-icon" rel="noreferrer noopener">
+                  <i class="ico--facebook"></i>
+                </a>
+              {% endif %}
+              {% if page.instagram_url %}
+                <a href="{{ page.instagram_url }}" target="_blank" class="social-icon" rel="noreferrer noopener">
+                  <i class="ico--instagram"></i></a>
+              {% endif %}
+              {% if page.twitter_url %}
+                <a href="{{ page.twitter_url }}" target="_blank" class="social-icon" rel="noreferrer noopener">
+                  <i class="ico--twitter"></i>
+                </a>
+              {% endif %}
+              {% if page.youtube_url %}
+                <a href="{{ page.youtube_url }}" target="_blank" class="social-icon" rel="noreferrer noopener">
+                  <i class="ico--youtube"></i>
+                </a>
+              {% endif %}
+              {% if page.flickr_url %}
+                <a href="{{ page.flickr_url }}" target="_blank" class="social-icon" rel="noreferrer noopener">
+                  <i class="ico--flickr"></i>
+                </a>
+              {% endif %}
+              {% if page.custom_web_url %}
+                <a href="{{ page.custom_web_url }}" target="_blank" class="social-icon" rel="noreferrer noopener">
+                  <i class="ico--globe"></i>
+                </a>
+              {% endif %}
+              {% for person_link_block in page.other_urls %}
+                <a
+                  href="{{ person_link_block.value.url }}"
+                  target="_blank"
+                  class="social-icon"
+                  rel="noreferrer noopener"
+                  title="{{ person_link_block.value.title }}"
+                >
+                  <i class="{% firstof person_link_block.value.custom_icon 'ico--globe' %}"></i>
+                </a>
+              {% endfor %}
+            </div>
+          {% endif %}
+
+          {% if page.is_pirate %}
+            <hr>
+            <div class="flex items-center">
+              <div class="avatar w-6 mr-2">
+                <img src="{% static "elections2021/images/logo-pirati-21px.svg" %}">
+              </div>
+              <span class="font-bold font-condensed">Pirátská strana</span>
+            </div>
+          {% endif %}
+
+          {% if not page.is_pirate and page.other_party %}
+            <hr>
+            <div class="flex items-center">
+              {% if page.other_party_logo %}
+                {% image page.other_party_logo width-48 as logo_img %}
+                <div class="avatar w-6 mr-2">
+                  <img src="{{ logo_img.url }}" alt="{{ page.other_party }}">
+                </div>
+              {% endif %}
+              <span class="font-bold font-condensed">{{ page.other_party }}</span>
+            </div>
+          {% endif %}
+
+          {% if page.phone or page.email and page.show_email %}
+            <hr>
+            <div class="content-block">
+              <div class="space-y-4">
+                {% if page.phone %}
+                  <div>
+                      <h4>Telefon</h4>
+                      <a href="tel:{{ page.phone }}" class="contact-line icon-link content-block--nostyle">
+                          <i class="ico--phone"></i><span>{{ page.phone }}</span>
+                      </a>
+                  </div>
+                {% endif %}
+
+                {% if page.email and page.show_email %}
+                  <div>
+                    <h4>Email</h4>
+                    <a href="mailto:{{ page.email }}" class="contact-line icon-link content-block--nostyle">
+                      <i class="ico--envelope"></i><span>{{ page.email }}</span>
+                    </a>
+                  </div>
+                {% endif %}
+              </div>
+            </div>
+          {% endif %}
+
+          {% if random_people %}
+            <hr>
+            <div class="content-block">
+              <h2>Lidé</h2>
+
+              <div class="space-y-4 mt-4">
+                {% for person in random_people %}
+                  {% include "shared/person_badge_snippet.html" with person_page=person skipcontacts=1 %}
+                {% endfor %}
+              </div>
+
+              <a href="{{ page.root_page.people_page.url }}"
+              class="btn btn--icon btn--violet-500 btn--fullwidth btn--hoveractive pt-4">
+                <div class="btn__body-wrap">
+                  <div class="btn__body ">Poznejte celý náš tým</div>
+                  <div class="btn__icon ">
+                    <i class="ico--chevron-right"></i>
+                  </div>
+                </div>
+              </a>
+            </div>
+          {% endif %}
+            {% comment %} <hr> {% endcomment %}
+{#              <h2>Kancelář</h2>#}
+{#              <h4>Poslanecká sněmovna</h4>#}
+{#              <p>#}
+{#                Jiřího náměstí 39, 290 33 Poděbrady#}
+{#              </p>#}
+{#              <iframe#}
+{#                src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d82007.99920528589!2d15.688131074078123!3d50.034780639742856!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x470dc94b239307b5%3A0x12d59894ccf624ae!2sPardubice!5e0!3m2!1scs!2scz!4v1589382658695!5m2!1scs!2scz"#}
+{#                width="100%" height="300" id="mapa-mobile" frameborder="0" style="border:0;" allowfullscreen=""#}
+{#                aria-hidden="false" tabindex="0"></iframe>#}
+{#              <h4>Otevírací doba</h4>#}
+{#              <p>Pondělí 14:00 - 18:00 objednat se přes: kancelář-podebrady@pirati.cz nebo 778 111 462.</p>#}
+
+          <!-- Mobile divider -->
+          <hr class="block lg:hidden">
+        </div>
+      </div>
+    </section>
+  </div>
+
+{% endblock %}