From 1c5ddf073baa039dbf09e5e6f3f577696c53dd07 Mon Sep 17 00:00:00 2001
From: Ondrej Rehounek <ondra.rehounek@seznam.cz>
Date: Mon, 8 Nov 2021 21:51:21 +0100
Subject: [PATCH] district: unfortunately big commit containing: add some
 fields to existing pages, change and add some templates, prepare some stuff
 for region module

---
 district/blocks.py                            |  57 +++
 .../migrations/0005_auto_20211108_2126.py     | 120 ++++++
 district/models.py                            | 165 +++++++--
 district/templates/district/base.html         |  34 +-
 .../blocks/homepage_header_block.html         |  13 +
 .../district/blocks/program_block.html        | 138 +++++++
 .../district/district_article_page.html       |   2 +-
 .../district/district_articles_page.html      |  56 +--
 .../district/district_contact_page.html       |  81 +++--
 .../district/district_home_page.html          |  28 +-
 .../district/district_people_page.html        |  19 +-
 .../district/district_person_page.html        |   2 +
 .../district/district_program_page.html       |  33 ++
 .../district/district_tags_page.html          |  39 +-
 .../templates/district/followus_snippet.html  |  13 -
 .../district/social_icons_snippet.html        |   5 -
 region/migrations/0001_initial.py             | 140 +++++++
 region/models.py                              | 341 +++++++++++++++++-
 region/templates/region/base.html             | 286 +++++++++++++++
 .../templates/region/region_article_page.html |  83 +++++
 .../region/region_articles_page.html          |  54 +++
 .../templates/region/region_contact_page.html |  88 +++++
 region/templates/region/region_home_page.html |  20 +
 .../templates/region/region_people_page.html  |  22 ++
 .../templates/region/region_person_page.html  | 104 ++++++
 .../templates/region/region_program_page.html |  33 ++
 region/templates/region/region_tags_page.html |  26 ++
 shared/templates/shared/article_preview.html  |   5 +-
 shared/templates/shared/followus_snippet.html |  13 +
 .../shared}/more_articles_snippet.html        |   0
 .../shared/social_icons_snippet.html          |   6 +
 .../styleguide/2.3.x/pagination.html          |   8 +-
 32 files changed, 1852 insertions(+), 182 deletions(-)
 create mode 100644 district/blocks.py
 create mode 100644 district/migrations/0005_auto_20211108_2126.py
 create mode 100644 district/templates/district/blocks/homepage_header_block.html
 create mode 100644 district/templates/district/blocks/program_block.html
 create mode 100644 district/templates/district/district_program_page.html
 delete mode 100644 district/templates/district/followus_snippet.html
 delete mode 100644 district/templates/district/social_icons_snippet.html
 create mode 100644 region/migrations/0001_initial.py
 create mode 100644 region/templates/region/base.html
 create mode 100644 region/templates/region/region_article_page.html
 create mode 100644 region/templates/region/region_articles_page.html
 create mode 100644 region/templates/region/region_contact_page.html
 create mode 100644 region/templates/region/region_home_page.html
 create mode 100644 region/templates/region/region_people_page.html
 create mode 100644 region/templates/region/region_person_page.html
 create mode 100644 region/templates/region/region_program_page.html
 create mode 100644 region/templates/region/region_tags_page.html
 create mode 100644 shared/templates/shared/followus_snippet.html
 rename {district/templates/district => shared/templates/shared}/more_articles_snippet.html (100%)
 create mode 100644 shared/templates/shared/social_icons_snippet.html

diff --git a/district/blocks.py b/district/blocks.py
new file mode 100644
index 00000000..950a9488
--- /dev/null
+++ b/district/blocks.py
@@ -0,0 +1,57 @@
+from django.forms import Select
+from wagtail.contrib.table_block.blocks import TableBlock
+from wagtail.core.blocks import (
+    CharBlock,
+    ChooserBlock,
+    IntegerBlock,
+    ListBlock,
+    StructBlock,
+    TextBlock,
+    URLBlock,
+)
+from wagtail.images.blocks import ImageChooserBlock
+
+from shared.models import Person
+
+
+class HomepageHeaderBlock(StructBlock):
+    title = CharBlock(label="Titulek", required=True)
+    subtitle = CharBlock(label="Podtitulek", required=False)
+    image = ImageChooserBlock()
+
+    class Meta:
+        template = "district/blocks/homepage_header_block.html"
+        icon = "image"
+        label = "Nadpis s obrázkem"
+
+
+class PersonChooserBlock(ChooserBlock):
+    target_model = Person
+    widget = Select
+
+    # TODO check if this is needed
+    def value_for_form(self, value):
+        if isinstance(value, self.target_model):
+            return value.pk
+        else:
+            return value
+
+
+class ProgramItemBlock(StructBlock):
+    title = CharBlock(label="Název", required=True)
+    issue_link = URLBlock(label="Odkaz na redmine", required=True)
+    completion_percentage = IntegerBlock(label="Procento dokončení", required=True)
+
+
+class ProgramBlock(StructBlock):
+    headline = CharBlock(label="Titulek bloku", required=True)
+    perex = TextBlock(label="Krátký text pod nadpisem", required=True)
+    person = PersonChooserBlock(label="Osoba", required=True)
+    completion_percentage = IntegerBlock(label="Procento dokončení", required=True)
+    program_items = ListBlock(ProgramItemBlock())
+    # program_items = TableBlock(label="Tabulka plnění programu", required=True)
+
+    class Meta:
+        template = "district/blocks/program_block.html"
+        icon = "list-ul"
+        label = "Blok programu"
diff --git a/district/migrations/0005_auto_20211108_2126.py b/district/migrations/0005_auto_20211108_2126.py
new file mode 100644
index 00000000..8fca7300
--- /dev/null
+++ b/district/migrations/0005_auto_20211108_2126.py
@@ -0,0 +1,120 @@
+# Generated by Django 3.2.8 on 2021-11-08 20:26
+
+import district.blocks
+from django.db import migrations, models
+import django.db.models.deletion
+import modelcluster.contrib.taggit
+import modelcluster.fields
+import shared.models
+import wagtail.core.blocks
+import wagtail.core.fields
+import wagtail.images.blocks
+import wagtailmetadata.models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('wagtailimages', '0023_add_choose_permissions'),
+        ('wagtailcore', '0062_comment_models_and_pagesubscription'),
+        ('shared', '0001_initial'),
+        ('taggit', '0003_taggeditem_add_unique_index'),
+        ('district', '0004_auto_20210209_1222'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='districthomepage',
+            options={'verbose_name': 'Web místního sdružení'},
+        ),
+        migrations.RemoveField(
+            model_name='districthomepage',
+            name='content',
+        ),
+        migrations.AddField(
+            model_name='districtcontactpage',
+            name='text',
+            field=wagtail.core.fields.RichTextField(blank=True, verbose_name='Text'),
+        ),
+        migrations.AddField(
+            model_name='districthomepage',
+            name='articles_title',
+            field=models.CharField(default='Děje se', max_length=256, verbose_name='Nadpis článků'),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='districthomepage',
+            name='calendar_button_text',
+            field=models.CharField(default='Kalendář', max_length=256, verbose_name='Text tlačítka kalendáře'),
+        ),
+        migrations.AddField(
+            model_name='districthomepage',
+            name='calendar_embed_link',
+            field=models.URLField(default='', help_text="Mělo by začínat 'https://calendar.google.com/calendar/embed?...'", verbose_name='Odkaz na embed kalendář'),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='districthomepage',
+            name='region_map_button_text',
+            field=models.CharField(default='Piráti v krajích', max_length=256, verbose_name='Text tlačítka mapy'),
+        ),
+        migrations.AddField(
+            model_name='districthomepage',
+            name='subheader',
+            field=wagtail.core.fields.StreamField([('header', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock(label='Titulek', required=True)), ('subtitle', wagtail.core.blocks.CharBlock(label='Podtitulek', required=False)), ('image', wagtail.images.blocks.ImageChooserBlock())]))], blank=True, verbose_name='Blok pod headerem'),
+        ),
+        migrations.AddField(
+            model_name='districthomepage',
+            name='twitter',
+            field=models.URLField(blank=True, null=True, verbose_name='Twitter URL'),
+        ),
+        migrations.AddField(
+            model_name='districthomepage',
+            name='youtube',
+            field=models.URLField(blank=True, null=True, verbose_name='YouTube URL'),
+        ),
+        migrations.AlterField(
+            model_name='districthomepage',
+            name='footperson_coord',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='district_footperson_coord', to='shared.person', verbose_name='Koordinátor'),
+        ),
+        migrations.AlterField(
+            model_name='districthomepage',
+            name='footperson_electman',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='district_footperson_electman', to='shared.person', verbose_name='Volební manažer'),
+        ),
+        migrations.AlterField(
+            model_name='districthomepage',
+            name='footperson_media',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='district_footperson_media', to='shared.person', verbose_name='Kontakt pro média'),
+        ),
+        migrations.CreateModel(
+            name='DistrictProgramPage',
+            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')),
+                ('perex', models.TextField(blank=True, verbose_name='Perex')),
+                ('content', wagtail.core.fields.StreamField([('program_block', wagtail.core.blocks.StructBlock([('headline', wagtail.core.blocks.CharBlock(label='Titulek bloku', required=True)), ('perex', wagtail.core.blocks.TextBlock(label='Krátký text pod nadpisem', required=True)), ('person', district.blocks.PersonChooserBlock(label='Osoba', required=True)), ('completion_percentage', wagtail.core.blocks.IntegerBlock(label='Procento dokončení', required=True)), ('program_items', wagtail.core.blocks.ListBlock(wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock(label='Název', required=True)), ('issue_link', wagtail.core.blocks.URLBlock(label='Odkaz na redmine', required=True)), ('completion_percentage', wagtail.core.blocks.IntegerBlock(label='Procento dokončení', required=True))])))]))], blank=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': 'Program',
+            },
+            bases=(shared.models.SubpageMixin, wagtailmetadata.models.WagtailImageMetadataMixin, 'wagtailcore.page', models.Model),
+        ),
+        migrations.CreateModel(
+            name='DistrictPersonTag',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('content_object', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, to='district.districtpersonpage')),
+                ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='district_districtpersontag_items', to='taggit.tag')),
+            ],
+            options={
+                'abstract': False,
+            },
+        ),
+        migrations.AddField(
+            model_name='districtpersonpage',
+            name='groups',
+            field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='Skupina pro zařazení na stránce Lidé', through='district.DistrictPersonTag', to='taggit.Tag', verbose_name='Tags'),
+        ),
+    ]
diff --git a/district/models.py b/district/models.py
index 4f33f986..0d1b76fc 100644
--- a/district/models.py
+++ b/district/models.py
@@ -5,7 +5,8 @@ from django.db import models
 from django.utils.translation import gettext_lazy
 from modelcluster.contrib.taggit import ClusterTaggableManager
 from modelcluster.fields import ParentalKey
-from taggit.models import TaggedItemBase
+from taggit.models import Tag, TaggedItemBase
+from uniweb.constants import RICH_TEXT_FEATURES
 from wagtail.admin.edit_handlers import (
     CommentPanel,
     FieldPanel,
@@ -13,25 +14,39 @@ from wagtail.admin.edit_handlers import (
     StreamFieldPanel,
 )
 from wagtail.core import blocks
-from wagtail.core.fields import StreamField
+from wagtail.core.fields import RichTextField, StreamField
 from wagtail.core.models import Page
 from wagtailmetadata.models import MetadataPageMixin
 
 from shared.models import ArticleMixin, Person, SubpageMixin
 
+from .blocks import HomepageHeaderBlock, ProgramBlock
+
 
 class DistrictHomePage(MetadataPageMixin, Page):
     ### FIELDS
 
-    content = StreamField(
-        [
-            ("title", blocks.CharBlock(label="nadpis", icon="title")),
-        ],
-        verbose_name="obsah stránky",
+    subheader = StreamField(
+        [("header", HomepageHeaderBlock())],
+        verbose_name="Blok pod headerem",
         blank=True,
     )
 
+    articles_title = models.CharField("Nadpis článků", max_length=256)
+    region_map_button_text = models.CharField(
+        "Text tlačítka mapy", max_length=256, default="Piráti v krajích"
+    )
+    calendar_button_text = models.CharField(
+        "Text tlačítka kalendáře", max_length=256, default="Kalendář"
+    )
+    calendar_embed_link = models.URLField(
+        "Odkaz na embed kalendář",
+        help_text="Mělo by začínat 'https://calendar.google.com/calendar/embed?...'",
+    )
+
     facebook = models.URLField("Facebook URL", blank=True, null=True)
+    twitter = models.URLField("Twitter URL", blank=True, null=True)
+    youtube = models.URLField("YouTube URL", blank=True, null=True)
     forum = models.URLField("Fórum URL", blank=True, null=True)
 
     contact_email = models.EmailField("kontaktni email", max_length=250, blank=True)
@@ -49,7 +64,7 @@ class DistrictHomePage(MetadataPageMixin, Page):
         on_delete=models.PROTECT,
         null=True,
         blank=True,
-        related_name="footperson_coord",
+        related_name="district_footperson_coord",
     )
     footperson_electman = models.ForeignKey(
         Person,
@@ -57,7 +72,7 @@ class DistrictHomePage(MetadataPageMixin, Page):
         on_delete=models.PROTECT,
         null=True,
         blank=True,
-        related_name="footperson_electman",
+        related_name="district_footperson_electman",
     )
     footperson_media = models.ForeignKey(
         Person,
@@ -65,7 +80,7 @@ class DistrictHomePage(MetadataPageMixin, Page):
         on_delete=models.PROTECT,
         null=True,
         blank=True,
-        related_name="footperson_media",
+        related_name="district_footperson_media",
     )
 
     # settings
@@ -76,7 +91,11 @@ class DistrictHomePage(MetadataPageMixin, Page):
     ### PANELS
 
     content_panels = Page.content_panels + [
-        StreamFieldPanel("content"),
+        StreamFieldPanel("subheader"),
+        FieldPanel("articles_title"),
+        FieldPanel("region_map_button_text"),
+        FieldPanel("calendar_button_text"),
+        FieldPanel("calendar_embed_link"),
     ]
 
     promote_panels = [
@@ -84,6 +103,8 @@ class DistrictHomePage(MetadataPageMixin, Page):
             [
                 FieldPanel("facebook"),
                 FieldPanel("forum"),
+                FieldPanel("twitter"),
+                FieldPanel("youtube"),
             ],
             gettext_lazy("Common page configuration"),
         ),
@@ -117,13 +138,14 @@ class DistrictHomePage(MetadataPageMixin, Page):
         "district.DistrictArticlesPage",
         "district.DistrictContactPage",
         "district.DistrictPeoplePage",
+        "district.DistrictProgramPage",
         "district.DistrictTagsPage",
     ]
 
     ### OTHERS
 
     class Meta:
-        verbose_name = "Web místního sdružení (experimentální rozpracovaná verze!)"
+        verbose_name = "Web místního sdružení"
 
     def _first_subpage_of_type(self, page_type):
         return self.get_descendants().type(page_type).live().specific()[0]
@@ -229,11 +251,13 @@ class DistrictContactPage(SubpageMixin, MetadataPageMixin, Page):
         verbose_name="Kontakty",
         blank=True,
     )
+    text = RichTextField("Text", blank=True, features=RICH_TEXT_FEATURES)
 
     ### PANELS
 
     content_panels = Page.content_panels + [
         StreamFieldPanel("contact_people"),
+        FieldPanel("text"),
     ]
 
     ### RELATIONS
@@ -262,33 +286,86 @@ class DistrictTagsPage(SubpageMixin, MetadataPageMixin, Page):
     class Meta:
         verbose_name = "Stránka s tagy"
 
-    def get_context(self, request):
+    def get_context(self, request, *args, **kwargs) -> dict:
         context = super().get_context(request)
 
-        # Natrid clanky do hashtable dle tagu (v template by se to delalo podstatne hur)
-        tags = {}
-        for x in self.root_page.articles_page.get_children().live().specific():
-            for y in x.tags.all():
-                try:
-                    tags[y.name].append(x)
-                except KeyError:
-                    tags[y.name] = [x]
+        # Potřebujeme IDčka článků pro správnou root_page pro filtrování zobrazených
+        # tagů i samotných stránek, protože se filtrují přes specifický field
+        # (tags__slug)
+        site_article_ids = (
+            self.root_page.articles_page.get_children()
+            .live()
+            .specific()
+            .values_list("id", flat=True)
+        )
+
+        # Naplním "tag" a "article_page_list" parametry
+        context.update(**self.get_tag_and_articles(request, site_article_ids))
+        context["tag_list"] = self.get_tag_qs(site_article_ids)
 
-        context["tags"] = tags
+        # Pro obecnou paginaci posílám "extra_query", abych si podržel tag pro další GET
+        context["extra_query"] = "&tag={}".format(request.GET.get("tag", ""))
         return context
 
+    def get_tag_and_articles(self, request, site_article_ids: list) -> dict:
+        """
+        Vrátí vyfiltrované články podle tagu a page query pro z daného "výběru"
+        pro danou stránku (site_article_ids). Lepší by bylo články a tag řešit
+        separátně, ale pak by se musel rozpadnout ten try/except na více bloků.
+        """
+        article_page_qs = DistrictArticlePage.objects.filter(id__in=site_article_ids)
+
+        try:
+            tag = DistrictArticleTag.objects.filter(tag__slug=request.GET["tag"])[0].tag
+            article_page_qs = article_page_qs.filter(tags__slug=tag.slug)
+        except (KeyError, IndexError):
+            tag = None
+
+        return {
+            "article_page_list": Paginator(
+                article_page_qs,
+                self.root_page.articles_page.max_items,
+            ).get_page(request.GET.get("page")),
+            "tag": tag,
+        }
+
+    @staticmethod
+    def get_tag_qs(site_article_ids: list) -> models.QuerySet:
+        """
+        Getuje Tagy pouze pro DistrictArticlePage omezeno IDčky getnutých přes
+        root_page. Počítá, kolik článků je s daným tagem.
+        """
+        return (
+            Tag.objects.filter(districtarticlepage__id__in=site_article_ids)
+            .order_by("slug")
+            .annotate(count=models.Count("slug"))
+            .values("name", "slug", "count")
+        )
+
+
+class DistrictPersonTag(TaggedItemBase):
+    content_object = ParentalKey(
+        "district.DistrictPersonPage", on_delete=models.CASCADE
+    )
+
 
 class DistrictPersonPage(SubpageMixin, MetadataPageMixin, Page):
     ### FIELDS
 
-    person = models.ForeignKey(Person, on_delete=models.PROTECT, null=True)
+    groups = ClusterTaggableManager(
+        through=DistrictPersonTag,
+        blank=True,
+        help_text="Skupina pro zařazení na stránce Lidé",
+    )
     perex = models.TextField("Perex osoby", blank=True)
+    person = models.ForeignKey(Person, on_delete=models.PROTECT, null=True)
 
     ### PANELS
 
     content_panels = Page.content_panels + [
         FieldPanel("person"),
         FieldPanel("perex"),
+        FieldPanel("groups"),
     ]
 
     ### RELATIONS
@@ -303,8 +380,9 @@ class DistrictPersonPage(SubpageMixin, MetadataPageMixin, Page):
 
     @property
     def pageperex(self):
-        """Vraci perex Pirata nejblizzsi lokalnimu kontextu.
-        Zamerne jiny nazev, aby v template bylo na vyber z x.perex, x.person.perex a x.pageperex
+        """
+        Vraci perex Pirata nejblizzsi lokalnimu kontextu. Zamerne jiny nazev, aby
+        v template bylo na vyber z x.perex, x.person.perex a x.pageperex
         """
         return self.perex or self.person.perex
 
@@ -334,5 +412,40 @@ class DistrictPeoplePage(SubpageMixin, MetadataPageMixin, Page):
 
     def get_context(self, request):
         context = super().get_context(request)
-        context["people"] = self.get_children().live().specific()
+
+        # Groupy (tagy) si natáhnu přes QS s orderingem, abych mohl udělat regroup v šabloně
+        context["district_person_tag_qs"] = DistrictPersonTag.objects.select_related(
+            "content_object"
+        ).order_by("tag_id")
+
         return context
+
+
+class DistrictProgramPage(SubpageMixin, MetadataPageMixin, Page):
+    ### FIELDS
+
+    perex = models.TextField("Perex", blank=True)
+    content = StreamField(
+        [
+            ("program_block", ProgramBlock()),
+        ],
+        verbose_name="obsah stránky",
+        blank=True,
+    )
+
+    ### PANELS
+
+    content_panels = Page.content_panels + [
+        FieldPanel("perex"),
+        StreamFieldPanel("content"),
+    ]
+
+    ### RELATIONS
+
+    parent_page_types = ["district.DistrictHomePage"]
+    subpage_types = []
+
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Program"
diff --git a/district/templates/district/base.html b/district/templates/district/base.html
index 8434d04d..4653aa6d 100644
--- a/district/templates/district/base.html
+++ b/district/templates/district/base.html
@@ -72,7 +72,7 @@
             </div>
 
             <div class="social-icon-group space-x-2 text-grey-200 py-4 lg:py-0">
-              {% include "district/social_icons_snippet.html" %}
+              {% include "shared/social_icons_snippet.html" %}
             </div>
 
           </div>
@@ -119,22 +119,29 @@
       <nav class="subnav py-2">
         <div class="container container--wide">
           <div class="flex">
-
-            {% comment %}
-            <button @click="toggleView('regions')" class="btn btn--condensed btn--grey-500 btn--hoveractive btn--to-white text-sm mr-2  px-0" :class="{'btn--activated': isCurrentView('regions')}">
+            <button
+              class="btn btn--condensed btn--grey-500 btn--hoveractive btn--to-white text-sm mr-2  px-0"
+              :class="{'btn--activated': isCurrentView('regions')}"
+              @click="toggleView('regions')"
+            >
               <div class="btn__body py-2">
-                <span>Piráti v dalších krajích</span>
+                <span>{{ page.root_page.region_map_button_text }}</span>
                 <i class="ico--chevron-down ml-4"></i>
               </div>
             </button>
 
-            <button @click="toggleView('calendar')" class="btn btn--inline-icon btn--condensed btn--hoveractive btn--grey-500 btn--to-orange-300 text-sm px-0" :class="{'btn--activated': isCurrentView('calendar')}">
+            <button
+              class="btn btn--inline-icon btn--condensed btn--hoveractive btn--grey-500 btn--to-orange-300 text-sm px-0"
+              :class="{'btn--activated': isCurrentView('calendar')}"
+              @click="toggleView('calendar')"
+            >
               <div class="btn__body py-2">
                 <i class="btn__inline-icon ico--calendar mr-0 md:mr-2 text-orange-300"></i>
-                <span class="hidden md:block">Krajský kalendář</span>
+                <span class="hidden md:block">
+                  {{ page.root_page.calendar_button_text|default_if_none:"Kalendář" }}
+                </span>
               </div>
             </button>
-            {% endcomment %}
 
             {% if page.root_page.facebook %}
               <a href="{{ page.root_page.facebook }}" target="_blank" rel="noopener noreferrer" class="btn btn--inline-icon btn--condensed btn--hoveractive btn--grey-500 btn--to-brands-facebook text-sm ml-2  px-0">
@@ -151,16 +158,15 @@
 
       <aside class="subnav-aside">
         <div class="subnav-aside__item" :class="{'subnav-aside__item--visible': isCurrentView('regions')}">
-          <a @click="toggleView('regions')" class="subnav-aside__close"><i class="ico--close"></i></a>
+{#          <a @click="toggleView('regions')" class="subnav-aside__close"><i class="ico--close"></i></a>#}
           <ui-region-map class="container container--default" />
         </div>
         <div class="subnav-aside__item" :class="{'subnav-aside__item--visible': isCurrentView('calendar')}">
-          <a @click="toggleView('calendar')" class="subnav-aside__close"><i class="ico--close"></i></a>
+{#          <a @click="toggleView('calendar')" class="subnav-aside__close"><i class="ico--close"></i></a>#}
           <div class="container container--default">
-
-              <iframe src="https://calendar.google.com/calendar/embed?showTitle=0&showNav=0&showDate=0&showPrint=0&showTabs=0&showCalendars=0&showTz=0&mode=AGENDA&height=500&wkst=2&hl=cs&bgcolor=%23FFFFFF&src=kddvdvu3adcjef2kro4j6mm838%40group.calendar.google.com&color=%232952A3&ctz=Europe%2FPrague" style="border-width:0; width: 100%; height: 410px; border: 0; overflow: hidden;"></iframe>
+              <iframe src="{{ page.root_page.calendar_embed_link }}" style="border-width:0; width: 100%; height: 410px; border: 0; overflow: hidden;"></iframe>
               <p class="mt-4">
-                <a class="btn btn--orange-200 btn--hoveractive" href="https://calendar.google.com/calendar/embed?showTitle=0&showNav=0&showDate=0&showPrint=0&showTabs=0&showCalendars=0&showTz=0&mode=AGENDA&height=500&wkst=2&hl=cs&bgcolor=%23FFFFFF&src=kddvdvu3adcjef2kro4j6mm838%40group.calendar.google.com&color=%232952A3&ctz=Europe%2FPrague">
+                <a class="btn btn--orange-200 btn--hoveractive" href="{{ page.root_page.calendar_embed_link }}">
                   <span class="btn__body">Zobrazit všechny akce</span>
                 </a>
               </p>
@@ -230,7 +236,7 @@
         <section class="footer__social lg:text-right">
           <div class="mb-4">
             <div class="social-icon-group space-x-2 text-white pb-4">
-              {% include "district/social_icons_snippet.html" %}
+              {% include "shared/social_icons_snippet.html" %}
             </div>
             <a href="mailto:{{ page.root_page.contact_email|default:"info@pirati.cz" }}" class="contact-line icon-link content-block--nostyle " ><i class="ico--envelope"></i><span>Dejte nám vědět</span></a>
           </div>
diff --git a/district/templates/district/blocks/homepage_header_block.html b/district/templates/district/blocks/homepage_header_block.html
new file mode 100644
index 00000000..bf9c6076
--- /dev/null
+++ b/district/templates/district/blocks/homepage_header_block.html
@@ -0,0 +1,13 @@
+<header
+  class="hero hero--image py-16 "
+  style="--image-url: url(https://praha8.pirati.cz/assets/posts/libensky-zamek-c76ce3fd0a7d061e15025fbb7080f4dbd12fab3daebdcbd42d2ab6b1cdbaa2f0.jpg)"
+>
+  <div class="container container--default">
+    <h1 class="head-alt-md md:head-alt-lg max-w-2xl ">
+      Piráti Praha 8
+    </h1>
+    <h2 class="head-xs mt-2 ">
+      Makáme v opozici. Držíme směr!
+    </h2>
+  </div>
+</header>
diff --git a/district/templates/district/blocks/program_block.html b/district/templates/district/blocks/program_block.html
new file mode 100644
index 00000000..c4f9ee1e
--- /dev/null
+++ b/district/templates/district/blocks/program_block.html
@@ -0,0 +1,138 @@
+<article class="mt-8">
+  <div class="lg:flex lg:space-x-16">
+    <div class="lg:w-3/5 xl:w-2/3">
+      <h2 class="head-heavy-sm mb-2 lg:mb-4">
+        {{ self.headline }}
+      </h2>
+      <div itemprop="description" class="w-full content-block">
+        <p>
+          {{ self.perex }}
+        </p>
+      </div>
+    </div>
+    <div class="pt-8 lg:w-1/3 md:pt-0">
+      <div class="card">
+        <div class="card__body">
+          <div class="badge badge--condensed">
+            <a href="/lide/martin-stanek.html" class="avatar badge__avatar avatar--sm">
+              <img src="/assets/bac4c3-0c8ce9ef9b8e4b48c898da14ee6fba5b78836ed019538622f72b4c6584aee7b6.jpg"
+                   alt="Martin Staněk">
+            </a>
+            <div class="badge__body">
+              <h2 class="head-heavy-2xs badge__title">
+                <a href="/lide/martin-stanek.html" title="Martin Staněk" class="content-block--nostyle">
+                  Martin Staněk
+                </a>
+              </h2>
+              <p class="badge__occupation">
+                Garant
+              </p>
+
+              <a href="tel:775 058 555"
+                 class="contact-line icon-link content-block--nostyle contact-line--responsive badge__link">
+                <i class="ico--phone"></i>
+                <span>775 058 555</span>
+              </a>
+
+              <a href="mailto:martin.stanek@pirati.cz"
+                 class="contact-line icon-link content-block--nostyle contact-line--responsive badge__link">
+                <i class="ico--envelope"></i>
+                <span>martin.stanek@pirati.cz</span>
+              </a>
+            </div>
+          </div>
+
+          <div class="content-block">
+            <div class="space-y-4 mt-8">
+              <div>
+                <a href="https://redmine.pirati.cz/issues/28177" class="contact-line icon-link content-block--nostyle">
+                  <i class="ico--info"></i>
+                  <span id="redmineid_28177">Plnění programu: 10%</span>
+                </a>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <div class="mt-4">
+    <table class="table table--striped table--bordered w-full">
+      <thead>
+      <tr>
+        <td>Název</td>
+        <td>Stav plnění</td>
+      </tr>
+      </thead>
+      <tbody>
+      {% for item in self.program_items %}
+        <tr>
+          <td>
+            <a href="{{ item.issue_link }}" target="_blank">
+              {{ item.title }}
+            </a>
+          </td>
+          <td>{{ item.completion_percentage }} %</td>
+        </tr>
+      {% endfor %}
+      </tbody>
+    </table>
+  </div>
+</article>
+
+<div class="content-block">
+  <div class="space-y-4 mt-8">
+    <div>
+      <a href="https://redmine.pirati.cz/issues/28177" class="contact-line icon-link content-block--nostyle">
+        <i class="ico--info"></i>
+        <span id="redmineid_28177">Plnění programu: 10%</span>
+      </a>
+    </div>
+  </div>
+</div>
+
+<script>
+  fetch('https://redmine.pirati.cz/issues/28177.json')
+  .then(response => response.json())
+  .then(data => console.log(data));
+
+  fetch('https://redmine.pirati.cz/issues.json?parent_id=28177&sort=id:as')
+  .then(response => response.json())
+  .then(data => console.log(data));
+
+    {#pirates.priorityStack.push(function (context) {#}
+    {#    var url = 'https://redmine.pirati.cz/issues/28177.json';#}
+    {#    var xhr = pirates.createCORSRequest('GET', url);#}
+    {#    if (!xhr) {#}
+    {#        alert('CORS not supported');#}
+    {#        return;#}
+    {#    }#}
+    {#    xhr.onload = function () {#}
+    {#        var doc = JSON.parse(xhr.responseText);#}
+    {#        var redmine = document.getElementById('redmineid_28177');#}
+    {#        redmine.textContent = "Plnění programu: " + doc.issue.done_ratio + "%";#}
+    {#    }#}
+    {#    xhr.onerror = function () {#}
+    {#        console.log('Woops, there was an error making the request.');#}
+    {#    };#}
+    {#    xhr.send();#}
+    {#});#}
+    {#pirates.priorityStack.push(function (context) {#}
+    {#    var url = 'https://redmine.pirati.cz/issues.json?parent_id=28177&sort=id:asc';#}
+    {#    var xhr = pirates.createCORSRequest('GET', url);#}
+    {#    if (!xhr) {#}
+    {#        alert('CORS not supported');#}
+    {#        return;#}
+    {#    }#}
+    {#    xhr.onload = function () {#}
+    {#        var doc = JSON.parse(xhr.responseText);#}
+    {#        var div = document.getElementById('redmine_tasks_28177');#}
+    {#        div.appendChild(pirates.integrations.redmine.tasks(doc));#}
+    {#    }#}
+    {#    xhr.onerror = function () {#}
+    {#        console.log('Woops, there was an error making the request.');#}
+    {#    };#}
+    {#    xhr.send();#}
+    {#});#}
+</script>
diff --git a/district/templates/district/district_article_page.html b/district/templates/district/district_article_page.html
index a02c4056..e618a634 100644
--- a/district/templates/district/district_article_page.html
+++ b/district/templates/district/district_article_page.html
@@ -77,7 +77,7 @@
 
 </div>
 
-{% include "district/more_articles_snippet.html" %}
+{% include "shared/more_articles_snippet.html" %}
 
 
 {% endblock %}
diff --git a/district/templates/district/district_articles_page.html b/district/templates/district/district_articles_page.html
index 1d89ee4c..69c472dc 100644
--- a/district/templates/district/district_articles_page.html
+++ b/district/templates/district/district_articles_page.html
@@ -1,54 +1,22 @@
 {% extends "district/base.html" %}
 
 {% block content %}
-<main>
+  <main>
 
-  <div class="container container--default py-8 lg:py-24">
+    <div class="container container--default py-8 lg:py-24">
 
-    <header>
-       <h1 itemprop="headline" class="head-alt-md md:head-alt-lg max-w-5xl mb-8">{{ page.title }}</h1>
-    </header>
+      <header>
+        <h1 itemprop="headline" class="head-alt-md md:head-alt-lg max-w-5xl mb-8">{{ page.title }}</h1>
+      </header>
 
-    <div class="article-card-list grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 lg:gap-8">
-    {% for a in articles %}
-        {% include "shared/article_preview.html" with article=a %}
-    {% endfor %}
-    </div>
-
-    <div class="pagination-container" role="navigation" aria-label="Pagination">
-      <nav>
-
-      {% if articles.has_previous %}
-      <a href="{{ page.root_page.articles_page.url }}?page={{ articles.previous_page_number }}" class="btn btn--icon btn--grey-125 btn--hoveractive btn--to-black btn--condensed btn--inverted-icon px-0"  aria-label="Předchozí stránka">
-          <div class="btn__body-wrap">
-            <div class="btn__body ">Předchozí</div>
-            <div class="btn__icon ">
-              <i class="ico--chevron-left"></i>
-            </div>
-          </div>
-      </a>
-      {% endif %}
-
-     {% for i in articles.paginator.page_range %}
-      <a href="{{ page.root_page.articles_page.url }}?page={{ i }}" class="btn {% if i == articles.number %} btn--grey-500 {% else %} btn--grey-125 {% endif %} btn--hoveractive btn--to-black btn--condensed hidden md:inline-block px-0"  aria-label="Stránka {{ i }}">
-          <div class="btn__body ">{{ i }}</div>
-      </a>
-     {% endfor %}
-
-     {% if articles.has_next %}
-      <a href="{{ page.root_page.articles_page.url }}?page={{ articles.next_page_number }}" class="btn btn--icon btn--grey-125 btn--hoveractive btn--to-black btn--condensed px-0"  aria-label="Další stránka">
-          <div class="btn__body-wrap">
-            <div class="btn__body ">Další</div>
-            <div class="btn__icon ">
-              <i class="ico--chevron-right"></i>
-            </div>
-          </div>
-      </a>
-      {% endif %}
+      <div class="article-card-list grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 lg:gap-8">
+        {% for a in articles %}
+          {% include "shared/article_preview.html" with article=a %}
+        {% endfor %}
+      </div>
 
-      </nav>
+      {% include 'styleguide/2.3.x/pagination.html' with paginator=article_page_list %}
     </div>
-  </div>
 
-</main>
+  </main>
 {% endblock %}
diff --git a/district/templates/district/district_contact_page.html b/district/templates/district/district_contact_page.html
index a5bd3d0b..b1c6c77b 100644
--- a/district/templates/district/district_contact_page.html
+++ b/district/templates/district/district_contact_page.html
@@ -3,66 +3,68 @@
 
 {% block content %}
 
-<div class="container container--default py-8">
-
-
+  <div class="container container--default py-8">
     <div class="lg:flex lg:mt-8 space-y-16 lg:space-y-0 lg:space-x-8 xl:space-x-16 mb-5">
       <section class="lg:w-3/5 xl:w-2/3">
 
-  <header>
-  <h1 itemprop="headline" class="head-alt-md md:head-alt-lg max-w-5xl mb-8">{{ page.title }}</h1>
-  </header>
+        <header>
+          <h1 itemprop="headline" class="head-alt-md md:head-alt-lg max-w-5xl mb-8">{{ page.title }}</h1>
+        </header>
 
-  {% for item in page.contact_people %}
+        {% for item in page.contact_people %}
 
-    <div>
-      <h2 class="head-heavy-sm mb-2 lg:mb-4 mt-4">{{ item.value.name }}</h2>
-      <div class="card elevation-3 p-3 mb-3">
-        {% include "shared/person_badge_snippet.html" with person=item.value.person  %}
-      </div>
-    </div>
+          <div>
+            <h2 class="head-heavy-sm mb-2 lg:mb-4 mt-4">{{ item.value.name }}</h2>
+            <div class="card elevation-3 p-3 mb-3">
+              {% include "shared/person_badge_snippet.html" with person=item.value.person %}
+            </div>
+          </div>
+
+        {% endfor %}
 
-  {% endfor %}
+        <div class="content-block">
+          {{ page.text | richtext }}
+        </div>
 
-  </section>
+      </section>
 
-  <section class="lg:w-2/5 xl:w-1/3 lg:pt-0">
-     <div class="lg:card lg:elevation-10">
-       <div class="lg:card__body content-block">
+      <section class="lg:w-2/5 xl:w-1/3 lg:pt-0">
+        <div class="lg:card lg:elevation-10">
+          <div class="lg:card__body content-block">
 
             <h2>Základní údaje</h2>
 
             <div class="space-y-4">
               <div>
-                  <h4>Emailová adresa</h4>
-                  <a href="mailto:yveta.martinkova@pirati.cz" class="contact-line icon-link content-block--nostyle " >
-                    <i class="ico--envelope"></i><span>{{ page.root_page.contact_email }}</span>
-                  </a>
+                <h4>Emailová adresa</h4>
+                <a href="mailto:yveta.martinkova@pirati.cz" class="contact-line icon-link content-block--nostyle ">
+                  <i class="ico--envelope"></i><span>{{ page.root_page.contact_email }}</span>
+                </a>
               </div>
 
               <div>
-                  <h4>Telefonický kontakt</h4>
-                  <a href="tel:{{ page.root_page.contact_phone }}" class="contact-line icon-link content-block--nostyle " >
-                    <i class="ico--phone"></i><span>{{ page.root_page.contact_phone }}</span>
-                  </a>
+                <h4>Telefonický kontakt</h4>
+                <a href="tel:{{ page.root_page.contact_phone }}" class="contact-line icon-link content-block--nostyle ">
+                  <i class="ico--phone"></i><span>{{ page.root_page.contact_phone }}</span>
+                </a>
               </div>
 
               <div>
-                  <h4>Transparentní účty</h4>
-                  2100048174/2010 a <a href="https://wiki.pirati.cz/fo/seznam_uctu">další účty</a>
+                <h4>Transparentní účty</h4>
+                2100048174/2010 a <a href="https://wiki.pirati.cz/fo/seznam_uctu">další účty</a>
               </div>
 
               <div>
-                  <h4>Datová schránka</h4>
-                  <span class="contact-line icon-link content-block--nostyle " >
+                <h4>Datová schránka</h4>
+                <span class="contact-line icon-link content-block--nostyle ">
                   <i class="ico--drawer"></i><span>b2i4r6j</span></span>
               </div>
 
               <div>
-                  <h4>Celostátní web</h4>
-                  <a href="https://www.pirati.cz" class="contact-line icon-link content-block--nostyle " >
-                     <i class="ico--pirati"></i><span>www.pirati.cz</span>
-                  </a>
+                <h4>Celostátní web</h4>
+                <a href="https://www.pirati.cz" class="contact-line icon-link content-block--nostyle ">
+                  <i class="ico--pirati"></i><span>www.pirati.cz</span>
+                </a>
               </div>
 
               <p>Každý člen strany má email ve tvaru: <tt>jmeno.prijmeni@pirati.cz</tt></p>
@@ -74,14 +76,13 @@
             <h2>Sídlo a kontaktní centrum</h2>
             <strong>Piráti Zlínský kraj</strong>
 
+          </div>
         </div>
-      </div>
-  </section>
-
-  </div>
+      </section>
+    </div>
 
-  {% include "district/followus_snippet.html" %}
+    {% include "shared/followus_snippet.html" %}
 
-</div>
+  </div>
 
 {% endblock %}
diff --git a/district/templates/district/district_home_page.html b/district/templates/district/district_home_page.html
index 275f6237..1915413c 100644
--- a/district/templates/district/district_home_page.html
+++ b/district/templates/district/district_home_page.html
@@ -1,20 +1,28 @@
 {% extends "district/base.html" %}
 {% load wagtailcore_tags %}
 
-{% block content %}
-<main>
-
-    <h1 class="head-alt-md md:head-alt-lg pb-4 lg:pb-8 pt-5">Aktuální témata</h1>
+{% block subheader %}
+  {% for block in page.subheader %}
+    {% include_block block %}
+  {% endfor %}
+{% endblock subheader %}
 
+{% block content %}
+  <main>
+    <h2 class="head-alt-md pb-4 lg:pb-8">
+      {{ page.articles_title }}
+    </h2>
     <!--  list of articles -->
     <div class="article-card-list grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 lg:gap-8">
-        {% for a in page.articles %}
-            {% include "shared/article_preview.html" with article=a %}
-        {% endfor %}
+      {% for a in page.articles %}
+        {% include "shared/article_preview.html" with article=a %}
+      {% endfor %}
     </div>
 
-    {% include "district/more_articles_snippet.html" %}
-    {% include "district/followus_snippet.html" %}
+    <div class="mb-8">
+      {% include "shared/more_articles_snippet.html" %}
+    </div>
 
-</main>
+    {% include "shared/followus_snippet.html" %}
+  </main>
 {% endblock %}
diff --git a/district/templates/district/district_people_page.html b/district/templates/district/district_people_page.html
index a0228fde..2debc43a 100644
--- a/district/templates/district/district_people_page.html
+++ b/district/templates/district/district_people_page.html
@@ -9,14 +9,21 @@
   <h1 itemprop="headline" class="head-alt-md md:head-alt-lg max-w-5xl mb-8">{{ page.title }}</h1>
   </header>
 
-  <h2 class="head-heavy-base mb-4">Členové a příznivci</h2>
+  {% regroup district_person_tag_qs by tag as person_group_list %}
 
-  <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 row-gap-8 col-gap-8">
-  {% for person in people %}
-    {% include "shared/person_badge_snippet.html" with person=person  %}
+  {% for person_group in person_group_list %}
+    <h2 class="head-heavy-base mb-4">
+      {{ person_group.grouper.name }}
+    </h2>
+    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 row-gap-8 col-gap-8">
+      {% for group_tag in person_group.list %}
+        {% include "shared/person_badge_snippet.html" with person=group_tag.content_object  %}
+      {% endfor %}
+    </div>
+    {% if not forloop.last %}
+      <hr class="hr--big">
+    {% endif %}
   {% endfor %}
-  </div>
-
 </div>
 
 {% endblock %}
diff --git a/district/templates/district/district_person_page.html b/district/templates/district/district_person_page.html
index fa889e7f..2ff22ccd 100644
--- a/district/templates/district/district_person_page.html
+++ b/district/templates/district/district_person_page.html
@@ -48,6 +48,8 @@
     </div>
     {% endif %}
 
+    {{ page.person.name }}
+
     <div class="content-block">
         <hr />
         <div class="space-y-4">
diff --git a/district/templates/district/district_program_page.html b/district/templates/district/district_program_page.html
new file mode 100644
index 00000000..8637887c
--- /dev/null
+++ b/district/templates/district/district_program_page.html
@@ -0,0 +1,33 @@
+{% extends "district/base.html" %}
+{% load wagtailcore_tags wagtailimages_tags shared_filters %}
+
+{% block content %}
+
+  <div class="container container--default py-8">
+    <div class="lg:flex lg:mt-8 space-y-16 lg:space-y-0 lg:space-x-8 xl:space-x-16 mb-5">
+      <section>
+
+        <header>
+          <h1 itemprop="headline" class="head-alt-md md:head-alt-lg max-w-5xl mb-8">
+            {{ page.title }}
+          </h1>
+        </header>
+
+        <p>
+          {{ page.perex }}
+        </p>
+
+{#        {{ page.content }}#}
+
+        {% for block in page.content %}
+
+          {% include_block block %}
+
+        {% endfor %}
+
+      </section>
+
+    </div>
+  </div>
+
+{% endblock %}
diff --git a/district/templates/district/district_tags_page.html b/district/templates/district/district_tags_page.html
index e4feb3fe..30f7ebd0 100644
--- a/district/templates/district/district_tags_page.html
+++ b/district/templates/district/district_tags_page.html
@@ -1,26 +1,31 @@
 {% extends "district/base.html" %}
 
 {% block content %}
-<main>
+  <main>
 
-    <h1 class="head-alt-md md:head-alt-lg max-w-5xl mb-4 mt-5">{{ page }}</h1>
+    <h1 class="head-alt-md md:head-alt-lg max-w-5xl mb-4 mt-5">
+      {% if tag %}{{ page.title }} "{{ tag.name }}"{% else %}Výběr z článků{% endif %}
+    </h1>
 
-    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
-    {% for tag, articles in tags.items %}
+    <div class="article-card-list grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 lg:gap-8">
+      {% for a in article_page_list %}
+        {% include "shared/article_preview.html" with article=a %}
+      {% endfor %}
+    </div>
 
-        <section class="card">
-          <div class="card__body p-4">
-            <h3 class="head-heavy-xs mb-2" id="{{ tag }}">{{ tag }}</h3>
-            <ul class="unordered-list unordered-list--linked unordered-list--dense leading-normal font-light text-sm">
-            {% for x in articles %}
-                <li><a href="{{ x.url }}">{{ x }}</a></li>
-            {% endfor %}
-            </ul>
-          </div>
-        </section>
+    {% include 'styleguide/2.3.x/pagination.html' with paginator=article_page_list %}
 
-    {% endfor %}
-    </div>
+    <h2 class="mt-8 head-alt-base">Další štítky:</h2>
 
-</main>
+    <div class="inline-block-nogap mt-4">
+      {% for tag in tag_list %}
+        <a
+          href="{{ page.url }}?tag={{ tag.slug }}"
+          class="btn article-card__category-button btn--condensed text-sm font-light btn--grey-{% if tag.slug == request.GET.tag %}500{% else %}125{% endif %} btn--hoveractive"
+        >
+          <div class="btn__body ">{{ tag.name }} ({{ tag.count }})</div>
+        </a>
+      {% endfor %}
+    </div>
+  </main>
 {% endblock %}
diff --git a/district/templates/district/followus_snippet.html b/district/templates/district/followus_snippet.html
deleted file mode 100644
index c6c7ca96..00000000
--- a/district/templates/district/followus_snippet.html
+++ /dev/null
@@ -1,13 +0,0 @@
-  <div class="d-flex">
-
-      <a href="{{page.facebook}}" class="super-button bg-brands-facebook text-white container-padding--zero lg:container-padding--auto lg:w-full m-2" >
-        <span class="super-button__body">Sledujte nás na Facebooku</span>
-        <i class="super-button__icon ico--facebook"></i>
-      </a>
-
-      <a href="{{ page.forum }}" class="super-button bg-black text-white container-padding--zero lg:container-padding--auto lg:w-full m-2"   >
-        <span class="super-button__body">Sledujte naše fórum</span>
-        <i class="super-button__icon ico--bubbles"></i>
-      </a>
-
-  </div>
diff --git a/district/templates/district/social_icons_snippet.html b/district/templates/district/social_icons_snippet.html
deleted file mode 100644
index 89a60835..00000000
--- a/district/templates/district/social_icons_snippet.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<a href="https://www.twitter.com/PiratskaStrana" rel="noopener noreferrer" target="_blank" title="Náš účet na Twitteru" class="social-icon "><i class="ico--twitter"></i></a>
-<a href="/feed.xml" rel="noopener noreferrer" target="_blank" title="Články tohoto webu v RSS" class="social-icon "><i class="ico--feed"></i></a>
-<a href=https://www.instagram.com/pirati.cz/ rel="noopener noreferrer" target="_blank" title="Instagram - Česká pirátská strana" class="social-icon "><i class="ico--instagram"></i></a>
-<a href=https://www.flickr.com/photos/pirati/ rel="noopener noreferrer" target="_blank" title="Flickr - Česká pirátská strana" class="social-icon "><i class="ico--flickr"></i></a>
-<a href="mailto:{{ page.root_page.contact_email|default:"info@pirati.cz" }}" class="social-icon "><i class="ico--envelope"></i></a>
diff --git a/region/migrations/0001_initial.py b/region/migrations/0001_initial.py
new file mode 100644
index 00000000..5e59b9d1
--- /dev/null
+++ b/region/migrations/0001_initial.py
@@ -0,0 +1,140 @@
+# Generated by Django 3.2.8 on 2021-11-08 20:43
+
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+import modelcluster.contrib.taggit
+import modelcluster.fields
+import shared.models
+import wagtail.core.blocks
+import wagtail.core.fields
+import wagtailmetadata.models
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('wagtailcore', '0062_comment_models_and_pagesubscription'),
+        ('wagtailimages', '0023_add_choose_permissions'),
+        ('shared', '0001_initial'),
+        ('taggit', '0003_taggeditem_add_unique_index'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='RegionArticlePage',
+            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')),
+                ('date', models.DateField(default=django.utils.timezone.now, verbose_name='datum')),
+                ('perex', models.TextField(verbose_name='perex')),
+                ('text', wagtail.core.fields.RichTextField(blank=True, verbose_name='článek')),
+                ('author', models.CharField(blank=True, max_length=250, null=True, verbose_name='autor')),
+                ('image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='wagtailimages.image', verbose_name='obrázek')),
+                ('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': 'Aktualita',
+            },
+            bases=(shared.models.SubpageMixin, wagtailmetadata.models.WagtailImageMetadataMixin, 'wagtailcore.page', models.Model),
+        ),
+        migrations.CreateModel(
+            name='RegionTagsPage',
+            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')),
+                ('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': 'Stránka s tagy',
+            },
+            bases=(shared.models.SubpageMixin, wagtailmetadata.models.WagtailImageMetadataMixin, 'wagtailcore.page', models.Model),
+        ),
+        migrations.CreateModel(
+            name='RegionPersonPage',
+            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')),
+                ('perex', models.TextField(blank=True, verbose_name='Perex osoby')),
+                ('person', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='shared.person')),
+                ('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',
+            },
+            bases=(shared.models.SubpageMixin, wagtailmetadata.models.WagtailImageMetadataMixin, 'wagtailcore.page', models.Model),
+        ),
+        migrations.CreateModel(
+            name='RegionPeoplePage',
+            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')),
+                ('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),
+        ),
+        migrations.CreateModel(
+            name='RegionHomePage',
+            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.core.fields.StreamField([('title', wagtail.core.blocks.CharBlock(icon='title', label='nadpis'))], blank=True, verbose_name='obsah stránky')),
+                ('facebook', models.URLField(blank=True, null=True, verbose_name='Facebook URL')),
+                ('forum', models.URLField(blank=True, null=True, verbose_name='Fórum URL')),
+                ('contact_email', models.EmailField(blank=True, max_length=250, verbose_name='kontaktni email')),
+                ('contact_phone', models.TextField(blank=True, max_length=250, verbose_name='kontaktni telefon')),
+                ('contact_newcomers', models.URLField(blank=True, null=True, verbose_name='URL pro zájemce o členství')),
+                ('donation_page', models.URLField(blank=True, null=True, verbose_name='URL pro příjem darů')),
+                ('matomo_id', models.IntegerField(blank=True, null=True, verbose_name='Matomo ID pro sledování návštěvnosti')),
+                ('footperson_coord', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='region_footperson_coord', to='shared.person', verbose_name='Koordinátor')),
+                ('footperson_electman', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='region_footperson_electman', to='shared.person', verbose_name='Volební manažer')),
+                ('footperson_media', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='region_footperson_media', to='shared.person', verbose_name='Kontakt pro média')),
+                ('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': 'Web regionálního sdružení',
+            },
+            bases=(wagtailmetadata.models.WagtailImageMetadataMixin, 'wagtailcore.page', models.Model),
+        ),
+        migrations.CreateModel(
+            name='RegionContactPage',
+            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')),
+                ('contact_people', wagtail.core.fields.StreamField([('item', wagtail.core.blocks.StructBlock([('name', wagtail.core.blocks.CharBlock(label='Role')), ('person', wagtail.core.blocks.PageChooserBlock(label='Osoba', page_type=['region.RegionPersonPage']))]))], blank=True, verbose_name='Kontakty')),
+                ('text', wagtail.core.fields.RichTextField(blank=True, verbose_name='Text')),
+                ('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': 'Kontakty',
+            },
+            bases=(shared.models.SubpageMixin, wagtailmetadata.models.WagtailImageMetadataMixin, 'wagtailcore.page', models.Model),
+        ),
+        migrations.CreateModel(
+            name='RegionArticleTag',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('content_object', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, to='region.regionarticlepage')),
+                ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='region_regionarticletag_items', to='taggit.tag')),
+            ],
+            options={
+                'abstract': False,
+            },
+        ),
+        migrations.CreateModel(
+            name='RegionArticlesPage',
+            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')),
+                ('max_items', models.IntegerField(default=12, verbose_name='Počet článků na stránce')),
+                ('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': 'Aktuality',
+            },
+            bases=(shared.models.SubpageMixin, wagtailmetadata.models.WagtailImageMetadataMixin, 'wagtailcore.page', models.Model),
+        ),
+        migrations.AddField(
+            model_name='regionarticlepage',
+            name='tags',
+            field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='region.RegionArticleTag', to='taggit.Tag', verbose_name='Tags'),
+        ),
+    ]
diff --git a/region/models.py b/region/models.py
index 71a83623..81ed0d9f 100644
--- a/region/models.py
+++ b/region/models.py
@@ -1,3 +1,342 @@
+import random
+
+from django.core.paginator import Paginator
 from django.db import models
+from django.utils.translation import gettext_lazy
+from modelcluster.contrib.taggit import ClusterTaggableManager
+from modelcluster.fields import ParentalKey
+from taggit.models import TaggedItemBase
+from uniweb.constants import RICH_TEXT_FEATURES
+from wagtail.admin.edit_handlers import (
+    CommentPanel,
+    FieldPanel,
+    MultiFieldPanel,
+    StreamFieldPanel,
+)
+from wagtail.core import blocks
+from wagtail.core.fields import RichTextField, StreamField
+from wagtail.core.models import Page
+from wagtailmetadata.models import MetadataPageMixin
+
+from shared.models import ArticleMixin, Person, SubpageMixin
+
+
+# TODO zatím prakticky shodné s district.models - až bude hotové, tak společné věci přenést do shared
+
+
+class RegionHomePage(MetadataPageMixin, Page):
+    ### FIELDS
+
+    content = StreamField(
+        [
+            ("title", blocks.CharBlock(label="nadpis", icon="title")),
+        ],
+        verbose_name="obsah stránky",
+        blank=True,
+    )
+
+    facebook = models.URLField("Facebook URL", blank=True, null=True)
+    forum = models.URLField("Fórum URL", blank=True, null=True)
+
+    contact_email = models.EmailField("kontaktni email", max_length=250, blank=True)
+    contact_phone = models.TextField("kontaktni telefon", max_length=250, blank=True)
+    contact_newcomers = models.URLField(
+        "URL pro zájemce o členství", blank=True, null=True
+    )
+
+    donation_page = models.URLField("URL pro příjem darů", blank=True, null=True)
+
+    # Lide uvedeni v paticce
+    footperson_coord = models.ForeignKey(
+        Person,
+        verbose_name="Koordinátor",
+        on_delete=models.PROTECT,
+        null=True,
+        blank=True,
+        related_name="region_footperson_coord",
+    )
+    footperson_electman = models.ForeignKey(
+        Person,
+        verbose_name="Volební manažer",
+        on_delete=models.PROTECT,
+        null=True,
+        blank=True,
+        related_name="region_footperson_electman",
+    )
+    footperson_media = models.ForeignKey(
+        Person,
+        verbose_name="Kontakt pro média",
+        on_delete=models.PROTECT,
+        null=True,
+        blank=True,
+        related_name="region_footperson_media",
+    )
+
+    # settings
+    matomo_id = models.IntegerField(
+        "Matomo ID pro sledování návštěvnosti", blank=True, null=True
+    )
+
+    ### PANELS
+
+    content_panels = Page.content_panels + [
+        StreamFieldPanel("content"),
+    ]
+
+    promote_panels = [
+        MultiFieldPanel(
+            [
+                FieldPanel("facebook"),
+                FieldPanel("forum"),
+            ],
+            gettext_lazy("Common page configuration"),
+        ),
+    ]
+
+    settings_panels = [
+        FieldPanel("matomo_id"),
+        FieldPanel("donation_page"),
+        MultiFieldPanel(
+            [
+                FieldPanel("contact_email"),
+                FieldPanel("contact_phone"),
+                FieldPanel("contact_newcomers"),
+            ],
+            gettext_lazy("Kontakty"),
+        ),
+        MultiFieldPanel(
+            [
+                FieldPanel("footperson_coord"),
+                FieldPanel("footperson_electman"),
+                FieldPanel("footperson_media"),
+            ],
+            gettext_lazy("Lidé v zápatí stránky"),
+        ),
+        CommentPanel(),
+    ]
+
+    ### RELATIONS
+
+    subpage_types = [
+        "region.RegionArticlesPage",
+        "region.RegionContactPage",
+        "region.RegionPeoplePage",
+        "region.RegionTagsPage",
+    ]
+
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Web regionálního sdružení"
+
+    def _first_subpage_of_type(self, page_type):
+        return self.get_descendants().type(page_type).live().specific()[0]
+
+    @property
+    def articles(self):
+        return self.get_descendants().type(RegionArticlePage).live().specific()
+
+    @property
+    def articles_page(self):
+        return self._first_subpage_of_type(RegionArticlesPage)
+
+    @property
+    def people_page(self):
+        return self._first_subpage_of_type(RegionPeoplePage)
+
+    @property
+    def contact_page(self):
+        return self._first_subpage_of_type(RegionContactPage)
+
+    @property
+    def tags_page(self):
+        return self._first_subpage_of_type(RegionTagsPage)
+
+    @property
+    def root_page(self):
+        return self
+
+
+class RegionArticleTag(TaggedItemBase):
+    content_object = ParentalKey("region.RegionArticlePage", on_delete=models.CASCADE)
+
+
+class RegionArticlePage(ArticleMixin, SubpageMixin, MetadataPageMixin, Page):
+    ### FIELDS
+
+    tags = ClusterTaggableManager(through=RegionArticleTag, blank=True)
+
+    ### PANELS
+
+    content_panels = ArticleMixin.content_panels + [FieldPanel("tags")]
+
+    ### RELATIONS
+
+    parent_page_types = ["region.RegionArticlesPage"]
+    subpage_types = []
+
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Aktualita"
+
+
+class RegionArticlesPage(SubpageMixin, MetadataPageMixin, Page):
+    ### FIELDS
+
+    max_items = models.IntegerField("Počet článků na stránce", default=12)
+
+    ### PANELS
+
+    content_panels = Page.content_panels + [
+        FieldPanel("max_items"),
+    ]
+
+    settings_panels = [CommentPanel()]
+
+    ### RELATIONS
+
+    parent_page_types = ["region.RegionHomePage"]
+    subpage_types = ["region.RegionArticlePage"]
+
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Aktuality"
+
+    def get_context(self, request):
+        context = super().get_context(request)
+        context["articles"] = Paginator(
+            self.get_children().live().specific(),
+            self.max_items,
+        ).get_page(request.GET.get("page"))
+        return context
+
+
+class RegionContactPage(SubpageMixin, MetadataPageMixin, Page):
+    class ContactItemBlock(blocks.StructBlock):
+        name = blocks.CharBlock(label="Role")
+        person = blocks.PageChooserBlock(
+            label="Osoba",
+            page_type=["region.RegionPersonPage"],
+        )
+
+        class Meta:
+            label = "Kontakt"
+
+    ### FIELDS
+
+    contact_people = StreamField(
+        [("item", ContactItemBlock())],
+        verbose_name="Kontakty",
+        blank=True,
+    )
+    text = RichTextField("Text", blank=True, features=RICH_TEXT_FEATURES)
+
+    ### PANELS
+
+    content_panels = Page.content_panels + [
+        StreamFieldPanel("contact_people"),
+        FieldPanel("text"),
+    ]
+
+    ### RELATIONS
+
+    parent_page_types = ["region.RegionHomePage"]
+    subpage_types = []
+
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Kontakty"
+
+
+class RegionTagsPage(SubpageMixin, MetadataPageMixin, Page):
+    ### PANELS
+
+    settings_panels = [CommentPanel()]
+
+    ### RELATIONS
+
+    parent_page_types = ["region.RegionHomePage"]
+    subpage_types = []
+
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Stránka s tagy"
+
+    def get_context(self, request):
+        context = super().get_context(request)
+
+        # Natrid clanky do hashtable dle tagu (v template by se to delalo podstatne hur)
+        tags = {}
+        for x in self.root_page.articles_page.get_children().live().specific():
+            for y in x.tags.all():
+                try:
+                    tags[y.name].append(x)
+                except KeyError:
+                    tags[y.name] = [x]
+
+        context["tags"] = tags
+        return context
+
+
+class RegionPersonPage(SubpageMixin, MetadataPageMixin, Page):
+    ### FIELDS
+
+    person = models.ForeignKey(Person, on_delete=models.PROTECT, null=True)
+    perex = models.TextField("Perex osoby", blank=True)
+
+    ### PANELS
+
+    content_panels = Page.content_panels + [
+        # InlinePanel("person"),
+        FieldPanel("perex"),
+    ]
+
+    ### RELATIONS
+
+    parent_page_types = ["region.RegionPeoplePage"]
+    subpage_types = []
+
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Detail osoby"
+
+    @property
+    def pageperex(self):
+        """Vraci perex Pirata nejblizzsi lokalnimu kontextu.
+        Zamerne jiny nazev, aby v template bylo na vyber z x.perex, x.person.perex a x.pageperex
+        """
+        return self.perex or self.person.perex
+
+    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
+
+
+class RegionPeoplePage(SubpageMixin, MetadataPageMixin, Page):
+    settings_panels = [CommentPanel()]
+
+    ### RELATIONS
+
+    parent_page_types = ["region.RegionHomePage"]
+    subpage_types = ["region.RegionPersonPage"]
+
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Lidé"
 
-# Create your models here.
+    def get_context(self, request):
+        context = super().get_context(request)
+        context["people"] = self.get_children().live().specific()
+        return context
diff --git a/region/templates/region/base.html b/region/templates/region/base.html
new file mode 100644
index 00000000..64e6fd8d
--- /dev/null
+++ b/region/templates/region/base.html
@@ -0,0 +1,286 @@
+{% load static wagtailcore_tags wagtailimages_tags wagtailmetadata_tags %}
+<!doctype html>
+<html lang="cs">
+<head>
+  <!-- Meta -->
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width" />
+  {% meta_tags %}
+  {% if settings.MAJAK_ENV == "test" %}
+    <meta name="robots" content="noindex, nofollow">
+  {% endif %}
+
+  <!-- Favicon -->
+  {% include "shared/favicon_snippet.html" %}
+
+  <!-- Bootstrap CSS -->
+
+  <!-- Styles -->
+  <link rel="stylesheet" href="{% static "styleguide18/assets/css/styles.css" %}">
+
+  <style type="text/css">
+    .inline-block {
+      display: inline-block;
+    }
+  </style>
+
+  {% if page.root_page.matomo_id %}
+    {% include "shared/matomo_snippet.html" with matomo_id=page.root_page.matomo_id %}
+  {% endif %}
+</head>
+
+<body>
+
+  <nav class="navbar __js-root py-lg-6">
+    <ui-app inline-template>
+      <ui-navbar inline-template>
+      <div>
+        <div class="container container--wide navbar__content" :class="{'navbar__content--initialized': true}">
+
+          <div class="navbar__brand my-4 flex items-center lg:block lg:pr-8 lg:my-0">
+            <a href="/">
+              <img src="{% static "styleguide18/assets/images/logo-round-white.svg" %}" class="w-10 lg:w-full lg:border-r lg:border-grey-300 lg:pr-8" />
+            </a>
+            <span class="lg:hidden pl-4 font-bold text-xl">Pirátská strana</span>
+          </div>
+
+          <div class="navbar__menutoggle my-4 flex justify-end lg:hidden">
+            <a href="#" @click="show = !show" class="no-underline hover:no-underline">
+              <i class="ico--menu text-3xl"></i>
+            </a>
+          </div>
+
+          <div v-if="show || isLgScreenSize" class="navbar__external navbar__section navbar__section--expandable container-padding--zero lg:container-padding--auto lg:flex lg:space-x-8 lg:pb-2">
+
+            <div class="text-grey-200 text-sm lg:space-x-8 leading-loose lg:leading-normal">
+
+              <a href="https://www.pirati.cz" class="contact-line icon-link content-block--nostyle block lg:inline-block" target="_blank" rel="noopener noreferrer">
+                <i class="ico--home"></i>
+                <span>pirati.cz</span>
+              </a>
+
+              <a href="https://piratskyobchod.cz" class="contact-line icon-link content-block--nostyle block lg:inline-block" target="_blank" rel="noopener noreferrer">
+                <i class="ico--cart"></i>
+                <span>piratskyobchod.cz</span>
+              </a>
+
+              <a href="http://www.piratskelisty.cz" class="contact-line icon-link content-block--nostyle block lg:inline-block" target="_blank" rel="noopener noreferrer">
+                <i class="ico--newspaper"></i>
+                <span>Pirátské listy</span>
+              </a>
+
+            </div>
+
+            <div class="social-icon-group space-x-2 text-grey-200 py-4 lg:py-0">
+              {% include "shared/social_icons_snippet.html" %}
+            </div>
+
+          </div>
+
+          <div v-if="show || isLgScreenSize" class="navbar__main navbar__section navbar__section--expandable container-padding--zero lg:container-padding--auto">
+              <ul class="navbar-menu text-white">
+                  <li class="navbar-menu__item"><a href="{% pageurl page.root_page.articles_page %}" class="navbar-menu__link">{{ page.root_page.articles_page }}</a></li>
+                  <li class="navbar-menu__item"><a href="{% pageurl page.root_page.people_page %}" class="navbar-menu__link">{{ page.root_page.people_page }}</a></li>
+                  {% comment %}
+                  <li class="navbar-menu__item"><a href="/komunalni-program/" class="navbar-menu__link">Komunální program</a></li>
+                  {% endcomment %}
+                  <li class="navbar-menu__item"><a href="{% pageurl page.root_page.contact_page %}" class="navbar-menu__link">{{ page.root_page.contact_page }}</a></li>
+              </ul>
+          </div>
+
+          <div v-if="show || isLgScreenSize" class="navbar__actions navbar__section navbar__section--expandable container-padding--zero lg:container-padding--auto self-start flex flex-col sm:flex-row lg:flex-col sm:space-x-4 space-y-2 sm:space-y-0 lg:space-y-2 xl:flex-row xl:space-x-2 xl:space-y-0">
+            <a href="https://dary.pirati.cz/projekty-kampane/zlk-potrebuje-peci/" rel="noopener noreferrer" target="_blank" class="btn btn--icon btn--cyan-200 btn--hoveractive btn--condensed btn--fullwidth md:btn--autowidth lg:text-sm xl:text-base">
+              <div class="btn__body-wrap">
+                <div class="btn__body ">Přispěj</div>
+                <div class="btn__icon ">
+                  <i class="ico--pig"></i>
+                </div>
+              </div>
+            </a>
+            <a href="https://nalodeni.pirati.cz" rel="noopener noreferrer" target="_blank" class="btn btn--icon btn--blue-300 btn--hoveractive btn--condensed btn--fullwidth md:btn--autowidth lg:text-sm xl:text-base">
+              <div class="btn__body-wrap">
+                <div class="btn__body ">Naloď se</div>
+                <div class="btn__icon ">
+                  <i class="ico--anchor"></i>
+                </div>
+              </div>
+            </a>
+          </div>
+        </div>
+      </div>
+      </ui-navbar>
+    </ui-app>
+</nav>
+
+<div class="__js-root">
+  <ui-app inline-template>
+
+    <ui-view-provider :initial="{regions: false, calendar: false}" v-slot="{ isCurrentView, toggleView }">
+      <nav class="subnav py-2">
+        <div class="container container--wide">
+          <div class="flex">
+
+            {% comment %}
+            <button @click="toggleView('regions')" class="btn btn--condensed btn--grey-500 btn--hoveractive btn--to-white text-sm mr-2  px-0" :class="{'btn--activated': isCurrentView('regions')}">
+              <div class="btn__body py-2">
+                <span>Piráti v dalších krajích</span>
+                <i class="ico--chevron-down ml-4"></i>
+              </div>
+            </button>
+
+            <button @click="toggleView('calendar')" class="btn btn--inline-icon btn--condensed btn--hoveractive btn--grey-500 btn--to-orange-300 text-sm px-0" :class="{'btn--activated': isCurrentView('calendar')}">
+              <div class="btn__body py-2">
+                <i class="btn__inline-icon ico--calendar mr-0 md:mr-2 text-orange-300"></i>
+                <span class="hidden md:block">Krajský kalendář</span>
+              </div>
+            </button>
+            {% endcomment %}
+
+            {% if page.root_page.facebook %}
+              <a href="{{ page.root_page.facebook }}" target="_blank" rel="noopener noreferrer" class="btn btn--inline-icon btn--condensed btn--hoveractive btn--grey-500 btn--to-brands-facebook text-sm ml-2  px-0">
+                <div class="btn__body py-2">
+                  <i class="btn__inline-icon ico--facebook mr-0 md:mr-2 text-brands-facebook"></i>
+                  <span class="hidden md:block">{{ page.root_page }}</span>
+                </div>
+              </a>
+            {% endif %}
+
+          </div>
+        </div>
+      </nav>
+
+      <aside class="subnav-aside">
+        <div class="subnav-aside__item" :class="{'subnav-aside__item--visible': isCurrentView('regions')}">
+          <a @click="toggleView('regions')" class="subnav-aside__close"><i class="ico--close"></i></a>
+          <ui-region-map class="container container--default" />
+        </div>
+        <div class="subnav-aside__item" :class="{'subnav-aside__item--visible': isCurrentView('calendar')}">
+          <a @click="toggleView('calendar')" class="subnav-aside__close"><i class="ico--close"></i></a>
+          <div class="container container--default">
+
+              <iframe src="https://calendar.google.com/calendar/embed?showTitle=0&showNav=0&showDate=0&showPrint=0&showTabs=0&showCalendars=0&showTz=0&mode=AGENDA&height=500&wkst=2&hl=cs&bgcolor=%23FFFFFF&src=kddvdvu3adcjef2kro4j6mm838%40group.calendar.google.com&color=%232952A3&ctz=Europe%2FPrague" style="border-width:0; width: 100%; height: 410px; border: 0; overflow: hidden;"></iframe>
+              <p class="mt-4">
+                <a class="btn btn--orange-200 btn--hoveractive" href="https://calendar.google.com/calendar/embed?showTitle=0&showNav=0&showDate=0&showPrint=0&showTabs=0&showCalendars=0&showTz=0&mode=AGENDA&height=500&wkst=2&hl=cs&bgcolor=%23FFFFFF&src=kddvdvu3adcjef2kro4j6mm838%40group.calendar.google.com&color=%232952A3&ctz=Europe%2FPrague">
+                  <span class="btn__body">Zobrazit všechny akce</span>
+                </a>
+              </p>
+
+          </div>
+        </div>
+      </aside>
+    </ui-view-provider>
+
+
+  </ui-app>
+</div>
+
+
+  {% block subheader %}{% endblock %}
+  <div class="container container--default lg:py-4">
+  {% block content %}{% endblock %}
+  </div>
+
+
+  <footer class="footer bg-grey-700 text-white __js-root">
+
+  <ui-app inline-template>
+
+    <div>
+      <div class="footer__main py-4 lg:py-16 container container--default pt-5">
+
+        <section class="footer__brand">
+          <img src="{% static "shared/img/logo-full-white.svg" %}" alt="Pirátská strana" class="w-32 md:w-40 pb-6" />
+          <p class="para hidden md:block md:mb-4 lg:mb-0 text-grey-200">
+            Piráti, {% now "Y" %}. Všechna práva vyhlazena.
+            Sdílejte a nechte ostatní sdílet za stejných podmínek.
+          </p>
+        </section>
+
+        <section class="footer__main-links bg-grey-700 text-white lg:grid grid-cols-3 gap-4">
+            <div class="pb-4">
+              <ui-footer-collapsible label="Připoj se">
+                <ul class="mt-6 space-y-2 text-grey-200">
+                    <li><a href="{{ page.root_page.contact_newcomers|default:"https://nalodeni.pirati.cz" }}">Zájemci o členství</a></li>
+                    <li><a href="{{ page.root_page.contact_page.url }}">Dej nám vědět</a></li>
+                    <li><a href="https://nalodeni.pirati.cz">Nalodění</a></li>
+                </ul>
+              </ui-footer-collapsible>
+            </div>
+
+            <div class="pb-4 border-t border-grey-400 lg:border-t-0">
+              <ui-footer-collapsible label="Makáme">
+                <ul class="mt-6 space-y-2 text-grey-200">
+                    <li><a href="{{ page.root_page.people_page.url }}">{{ page.root_page.people_page }}</a></li>
+                    <li><a href="{{ page.root_page.articles_page.url }}">{{ page.root_page.articles_page }}</a></li>
+                </ul>
+              </ui-footer-collapsible>
+            </div>
+
+            <div class="pb-4 border-t border-grey-400 lg:border-t-0">
+              <ui-footer-collapsible label="Otevřenost">
+                <ul class="mt-6 space-y-2 text-grey-200">
+                    <li><a href="https://ucet.pirati.cz">Transparentní účet</a></li>
+                    <li><a href="https://smlouvy.pirati.cz">Registr smluv</a></li>
+                    <li><a href="https://wiki.pirati.cz/fo/otevrene_ucetnictvi">Otevřené účetnictví</a></li>
+                </ul>
+              </ui-footer-collapsible>
+            </div>
+        </section>
+
+        <section class="footer__social lg:text-right">
+          <div class="mb-4">
+            <div class="social-icon-group space-x-2 text-white pb-4">
+              {% include "shared/social_icons_snippet.html" %}
+            </div>
+            <a href="mailto:{{ page.root_page.contact_email|default:"info@pirati.cz" }}" class="contact-line icon-link content-block--nostyle " ><i class="ico--envelope"></i><span>Dejte nám vědět</span></a>
+          </div>
+
+          <div class="flex flex-col md:flex-row lg:flex-col lg:items-end space-y-2 lg:space-x-0 mr-0 pr-0">
+
+            <a href="{{ page.root_page.donation_page|default:"https://dary.pirati.cz" }}" rel="noopener noreferrer" target="_blank" class="btn btn--icon btn--cyan-200 btn--hoveractive text-lg btn--fullwidth sm:btn--autowidth px-0 mx-0">
+              <div class="btn__body-wrap">
+                <div class="btn__body ">Přispěj</div>
+                <div class="btn__icon "><i class="ico--pig"></i></div>
+              </div>
+            </a>
+
+            <a href="https://nalodeni.pirati.cz" rel="noopener noreferrer" target="_blank" class="btn btn--icon btn--blue-300 btn--hoveractive text-lg btn--fullwidth sm:btn--autowidth mt-0 px-0 mx-0">
+              <div class="btn__body-wrap">
+                <div class="btn__body ">Naloď se</div>
+                <div class="btn__icon "><i class="ico--anchor"></i></div>
+              </div>
+            </a>
+
+          </div>
+
+        </section>
+      </div>
+
+      <section class="bg-black py-4 lg:py-12">
+        <div class="container container--default">
+          <div class="grid gap-4 grid-cols-1 md:grid-cols-2 xl:grid-cols-3">
+            {% if page.root_page.footperson_coord %}
+              {% include "shared/person_badge_snippet.html" with person=page.root_page.footperson_coord title="Koordinátor" %}
+            {% endif %}
+            {% if page.root_page.footperson_electman %}
+              {% include "shared/person_badge_snippet.html" with person=page.root_page.footperson_electman title="Volební manažer" %}
+            {% endif %}
+            {% if page.root_page.footperson_media %}
+              {% include "shared/person_badge_snippet.html" with person=page.root_page.footperson_media title="Kontakt pro média" %}
+            {% endif %}
+          </div>
+        </div>
+      </section>
+
+    </div>
+  </ui-app>
+</footer>
+
+
+  <script src="{% static "styleguide18/assets/js/vue.2.6.11.js" %}"></script>
+  <script src="{% static "styleguide18/assets/js/main.bundle.js" %}"></script>
+  <script src="{% static "shared/vendor/jquery/jquery-3.4.1.min.js" %}"></script>
+  <script src="{% static "shared/vendor/lazysizes/lazysizes.min.js" %}"></script>
+  <script src="{% static "shared/vendor/fancybox/jquery.fancybox.min.js" %}"></script>
+</body>
+</html>
diff --git a/region/templates/region/region_article_page.html b/region/templates/region/region_article_page.html
new file mode 100644
index 00000000..b7652255
--- /dev/null
+++ b/region/templates/region/region_article_page.html
@@ -0,0 +1,83 @@
+{% extends "region/base.html" %}
+{% load static wagtailcore_tags wagtailimages_tags %}
+
+{% block content %}
+
+<div class="container container--default py-8 lg:py-24">
+
+  <article itemtype="http://schema.org/BlogPosting" itemscope="">
+
+    <header>
+      <link itemprop="mainEntityOfPage" href="{{ page.url }}">
+      <meta itemprop="datePublished" content="{{ page.last_published_at }}">
+      <meta itemprop="dateModified" content="">
+
+      <h1 itemprop="headline" class="head-alt-md md:head-alt-lg max-w-5xl mb-4">{{ page.title }}</h1>
+
+      <div class="flex flex-col md:flex-row md:items-center">
+
+        <div class="inline-flex divide-x flex-grow">
+          <span class="pr-2">{{ page.date|date:"SHORT_DATE_FORMAT" }}</span>
+          <span class="pl-2" itemprop="author" itemtype="http://schema.org/Person" itemscope="">
+            <span itemprop="name">{{ page.author }}</span>
+          </span>
+        </div>
+
+        <div class="my-4">
+          {% for tag in page.tags.all %}
+              <a href="{{ page.root_page.tags_page.url }}#{{ tag}}" class="btn btn--grey-125 btn--condensed" ><div class="btn__body ">{{ tag }}</div></a>
+          {% endfor %}
+        </div>
+
+      </div>
+
+    <figure class="figure">
+      {% image page.image width-2000 as img %}
+      <img src="{{ img.url }}" alt="{{ page.title }}" />
+    </figure>
+
+    </header>
+
+    <div class="lg:flex mt-8 lg:space-x-16">
+
+      <div class="lg:w-2/3">
+        <div itemprop="description" class="w-full content-block">
+          {{ page.text|richtext }}
+        </div>
+      </div>
+
+      <div class="pt-8 lg:w-1/3 md:pt-0">
+        <div class="space-y-8">
+          <div class="sharebox md:card md:elevation-10 ">
+            <div class="md:card__body">
+              <span class="head-alt-base md:head-alt-md">Sdílení je aktem lásky</span>
+              <div class="flex w-full space-x-4 pt-4 md:pt-8 text-center text-white">
+                <a
+                  href="https://www.facebook.com/sharer/sharer.php?u={{ page.full_url|urlencode }}"
+                  onclick="window.open(this.href, 'pop-up', 'left=20,top=20,width=500,height=500,toolbar=1,resizable=0'); return false;"
+                  class="bg-brands-facebook px-8 py-3 text-2xl w-full"
+                ><i class="ico--facebook"></i></a>
+                <a
+                  href="https://twitter.com/intent/tweet?text={{ page.title|urlencode }}&url={{ page.full_url|urlencode }}"
+                  onclick="window.open(this.href, 'pop-up', 'left=20,top=20,width=500,height=500,toolbar=1,resizable=0'); return false;"
+                  class="bg-brands-twitter px-8 py-3 text-2xl w-full"
+                ><i class="ico--twitter"></i></a>
+              </div>
+          </div>
+          <div class="h-52 overflow-hidden hidden md:block">
+            <img src="{% static "shared/img/flag.png" %}" alt="Pirátská strana" class="w-80 object-cover m-auto" />
+          </div>
+        </div>
+
+        </div>
+      </div>
+
+    </div>
+  </article>
+
+</div>
+
+{% include "shared/more_articles_snippet.html" %}
+
+
+{% endblock %}
diff --git a/region/templates/region/region_articles_page.html b/region/templates/region/region_articles_page.html
new file mode 100644
index 00000000..aa7178f4
--- /dev/null
+++ b/region/templates/region/region_articles_page.html
@@ -0,0 +1,54 @@
+{% extends "region/base.html" %}
+
+{% block content %}
+<main>
+
+  <div class="container container--default py-8 lg:py-24">
+
+    <header>
+       <h1 itemprop="headline" class="head-alt-md md:head-alt-lg max-w-5xl mb-8">{{ page.title }}</h1>
+    </header>
+
+    <div class="article-card-list grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 lg:gap-8">
+    {% for a in articles %}
+        {% include "shared/article_preview.html" with article=a %}
+    {% endfor %}
+    </div>
+
+    <div class="pagination-container" role="navigation" aria-label="Pagination">
+      <nav>
+
+      {% if articles.has_previous %}
+      <a href="{{ page.root_page.articles_page.url }}?page={{ articles.previous_page_number }}" class="btn btn--icon btn--grey-125 btn--hoveractive btn--to-black btn--condensed btn--inverted-icon px-0"  aria-label="Předchozí stránka">
+          <div class="btn__body-wrap">
+            <div class="btn__body ">Předchozí</div>
+            <div class="btn__icon ">
+              <i class="ico--chevron-left"></i>
+            </div>
+          </div>
+      </a>
+      {% endif %}
+
+     {% for i in articles.paginator.page_range %}
+      <a href="{{ page.root_page.articles_page.url }}?page={{ i }}" class="btn {% if i == articles.number %} btn--grey-500 {% else %} btn--grey-125 {% endif %} btn--hoveractive btn--to-black btn--condensed hidden md:inline-block px-0"  aria-label="Stránka {{ i }}">
+          <div class="btn__body ">{{ i }}</div>
+      </a>
+     {% endfor %}
+
+     {% if articles.has_next %}
+      <a href="{{ page.root_page.articles_page.url }}?page={{ articles.next_page_number }}" class="btn btn--icon btn--grey-125 btn--hoveractive btn--to-black btn--condensed px-0"  aria-label="Další stránka">
+          <div class="btn__body-wrap">
+            <div class="btn__body ">Další</div>
+            <div class="btn__icon ">
+              <i class="ico--chevron-right"></i>
+            </div>
+          </div>
+      </a>
+      {% endif %}
+
+      </nav>
+    </div>
+  </div>
+
+</main>
+{% endblock %}
diff --git a/region/templates/region/region_contact_page.html b/region/templates/region/region_contact_page.html
new file mode 100644
index 00000000..eaab2163
--- /dev/null
+++ b/region/templates/region/region_contact_page.html
@@ -0,0 +1,88 @@
+{% extends "region/base.html" %}
+{% load wagtailcore_tags wagtailimages_tags shared_filters %}
+
+{% block content %}
+
+  <div class="container container--default py-8">
+    <div class="lg:flex lg:mt-8 space-y-16 lg:space-y-0 lg:space-x-8 xl:space-x-16 mb-5">
+      <section class="lg:w-3/5 xl:w-2/3">
+
+        <header>
+          <h1 itemprop="headline" class="head-alt-md md:head-alt-lg max-w-5xl mb-8">{{ page.title }}</h1>
+        </header>
+
+        {% for item in page.contact_people %}
+
+          <div>
+            <h2 class="head-heavy-sm mb-2 lg:mb-4 mt-4">{{ item.value.name }}</h2>
+            <div class="card elevation-3 p-3 mb-3">
+              {% include "shared/person_badge_snippet.html" with person=item.value.person %}
+            </div>
+          </div>
+
+        {% endfor %}
+
+        <div class="content-block">
+          {{ page.text | richtext }}
+        </div>
+
+      </section>
+
+      <section class="lg:w-2/5 xl:w-1/3 lg:pt-0">
+        <div class="lg:card lg:elevation-10">
+          <div class="lg:card__body content-block">
+
+            <h2>Základní údaje</h2>
+
+            <div class="space-y-4">
+              <div>
+                <h4>Emailová adresa</h4>
+                <a href="mailto:yveta.martinkova@pirati.cz" class="contact-line icon-link content-block--nostyle ">
+                  <i class="ico--envelope"></i><span>{{ page.root_page.contact_email }}</span>
+                </a>
+              </div>
+
+              <div>
+                <h4>Telefonický kontakt</h4>
+                <a href="tel:{{ page.root_page.contact_phone }}" class="contact-line icon-link content-block--nostyle ">
+                  <i class="ico--phone"></i><span>{{ page.root_page.contact_phone }}</span>
+                </a>
+              </div>
+
+              <div>
+                <h4>Transparentní účty</h4>
+                2100048174/2010 a <a href="https://wiki.pirati.cz/fo/seznam_uctu">další účty</a>
+              </div>
+
+              <div>
+                <h4>Datová schránka</h4>
+                <span class="contact-line icon-link content-block--nostyle ">
+                  <i class="ico--drawer"></i><span>b2i4r6j</span></span>
+              </div>
+
+              <div>
+                <h4>Celostátní web</h4>
+                <a href="https://www.pirati.cz" class="contact-line icon-link content-block--nostyle ">
+                  <i class="ico--pirati"></i><span>www.pirati.cz</span>
+                </a>
+              </div>
+
+              <p>Každý člen strany má email ve tvaru: <tt>jmeno.prijmeni@pirati.cz</tt></p>
+
+            </div>
+
+            <hr class="hr">
+
+            <h2>Sídlo a kontaktní centrum</h2>
+            <strong>Piráti Zlínský kraj</strong>
+
+          </div>
+        </div>
+      </section>
+    </div>
+
+    {% include "shared/followus_snippet.html" %}
+
+  </div>
+
+{% endblock %}
diff --git a/region/templates/region/region_home_page.html b/region/templates/region/region_home_page.html
new file mode 100644
index 00000000..1b9f7036
--- /dev/null
+++ b/region/templates/region/region_home_page.html
@@ -0,0 +1,20 @@
+{% extends "region/base.html" %}
+{% load wagtailcore_tags %}
+
+{% block content %}
+<main>
+
+    <h1 class="head-alt-md md:head-alt-lg pb-4 lg:pb-8 pt-5">Aktuální témata</h1>
+
+    <!--  list of articles -->
+    <div class="article-card-list grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 lg:gap-8">
+        {% for a in page.articles %}
+            {% include "shared/article_preview.html" with article=a %}
+        {% endfor %}
+    </div>
+
+    {% include "shared/more_articles_snippet.html" %}
+    {% include "shared/followus_snippet.html" %}
+
+</main>
+{% endblock %}
diff --git a/region/templates/region/region_people_page.html b/region/templates/region/region_people_page.html
new file mode 100644
index 00000000..49cad809
--- /dev/null
+++ b/region/templates/region/region_people_page.html
@@ -0,0 +1,22 @@
+{% extends "region/base.html" %}
+{% load wagtailcore_tags wagtailimages_tags shared_filters %}
+
+{% block content %}
+
+<div class="container container--default py-8 lg:py-24">
+
+  <header>
+    <h1 itemprop="headline" class="head-alt-md md:head-alt-lg max-w-5xl mb-8">{{ page.title }}</h1>
+  </header>
+
+  <h2 class="head-heavy-base mb-4">Členové a příznivci</h2>
+
+    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 row-gap-8 col-gap-8">
+      {% for person in people %}
+        {% include "shared/person_badge_snippet.html" with person=person  %}
+      {% endfor %}
+    </div>
+
+</div>
+
+{% endblock %}
diff --git a/region/templates/region/region_person_page.html b/region/templates/region/region_person_page.html
new file mode 100644
index 00000000..13cde222
--- /dev/null
+++ b/region/templates/region/region_person_page.html
@@ -0,0 +1,104 @@
+{% extends "region/base.html" %}
+{% load wagtailcore_tags wagtailimages_tags shared_filters %}
+
+{% block subheader %}
+
+<header class="hero hero--image pt-16 pb-24 lg:pt-32 pb-24 candidate-detail__hero"
+  style="--image-url: url(https://roznov.pirati.cz/assets/articles/2020/kampan20/zahajenikampan1-067fb446ec8933ae14591cbc29fc53ebb3009e4185900838bfb94752addbfa7b.jpg)"
+>
+
+  <div class="container container--default py-2">
+    <h1 class="head-alt-md md:head-alt-lg max-w-2xl text-left lg:text-left px-4">
+       <span class="academic-title-name">{{ page.name }}</span>
+    </h1>
+    <h2 class="head-xs mt-2 max-w-xl mx-auto text-center lg:text-left"></h2>
+  </div>
+</header>
+
+{% endblock %}
+
+{% block content %}
+
+<div class="container container--default py-8 lg:pb-24">
+
+  <main>
+    <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.longtext }}
+        </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">
+        <aside class="container-padding--zero lg:container-padding--auto lg:card lg:elevation-10">
+  <div class="lg: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">
+        <img src="{{ page.portrait }}" alt="" />
+      </div>
+    </div>
+
+    {% if page.facebook %}
+    <div class="flex flex-wrap item-center">
+      <div class="social-icon-group space-x-0/5">
+        <a class="social-icon" target="_blank" rel="noreferrer noopener" href="{{ page.facebook }}"><i class="ico--facebook"></i></a>
+      </div>
+    </div>
+    {% endif %}
+
+    <div class="content-block">
+        <hr />
+        <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 %}
+            <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>
+        </div>
+    </div>
+
+    <hr />
+
+    <div class="hidden lg:block">
+
+      <div class="content-block">
+        <h2>Lidé</h2>
+      </div>
+
+      <div class="space-y-4">
+      {% for person in random_people %}
+        {% include "shared/person_badge_snippet.html" with person=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>
+
+  </div>
+</aside>
+      </section>
+
+    </div>
+  </main>
+</div>
+
+{% endblock %}
diff --git a/region/templates/region/region_program_page.html b/region/templates/region/region_program_page.html
new file mode 100644
index 00000000..2bbc41fa
--- /dev/null
+++ b/region/templates/region/region_program_page.html
@@ -0,0 +1,33 @@
+{% extends "region/base.html" %}
+{% load wagtailcore_tags wagtailimages_tags shared_filters %}
+
+{% block content %}
+
+  <div class="container container--default py-8">
+    <div class="lg:flex lg:mt-8 space-y-16 lg:space-y-0 lg:space-x-8 xl:space-x-16 mb-5">
+      <section>
+
+        <header>
+          <h1 itemprop="headline" class="head-alt-md md:head-alt-lg max-w-5xl mb-8">
+            {{ page.title }}
+          </h1>
+        </header>
+
+        <p>
+          {{ page.perex }}
+        </p>
+
+{#        {{ page.content }}#}
+
+        {% for block in page.content %}
+
+          {% include_block block %}
+
+        {% endfor %}
+
+      </section>
+
+    </div>
+  </div>
+
+{% endblock %}
diff --git a/region/templates/region/region_tags_page.html b/region/templates/region/region_tags_page.html
new file mode 100644
index 00000000..5d07b0ff
--- /dev/null
+++ b/region/templates/region/region_tags_page.html
@@ -0,0 +1,26 @@
+{% extends "region/base.html" %}
+
+{% block content %}
+<main>
+
+    <h1 class="head-alt-md md:head-alt-lg max-w-5xl mb-4 mt-5">{{ page }}</h1>
+
+    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
+    {% for tag, articles in tags.items %}
+
+        <section class="card">
+          <div class="card__body p-4">
+            <h3 class="head-heavy-xs mb-2" id="{{ tag }}">{{ tag }}</h3>
+            <ul class="unordered-list unordered-list--linked unordered-list--dense leading-normal font-light text-sm">
+            {% for x in articles %}
+                <li><a href="{{ x.url }}">{{ x }}</a></li>
+            {% endfor %}
+            </ul>
+          </div>
+        </section>
+
+    {% endfor %}
+    </div>
+
+</main>
+{% endblock %}
diff --git a/shared/templates/shared/article_preview.html b/shared/templates/shared/article_preview.html
index 953dbc43..1ada7699 100644
--- a/shared/templates/shared/article_preview.html
+++ b/shared/templates/shared/article_preview.html
@@ -47,7 +47,10 @@
     <p class="card-body-text flex-grow">{{article.perex}}</p>
     <div class="inline-block-nogap mt-4">
         {% for tag in article.tags.all %}
-          <a href="{{ page.root_page.tags_page.url }}#{{ tag }}" class="btn article-card__category-button btn--condensed text-sm font-light btn--grey-700 p-0"   >
+          <a
+            href="{{ page.root_page.tags_page.url }}?tag={{ tag.slug }}"
+            class="btn article-card__category-button btn--condensed text-sm font-light btn--grey-125 btn--hoveractive"
+          >
             <div class="btn__body">{{ tag }}</div>
           </a>
         {% endfor %}
diff --git a/shared/templates/shared/followus_snippet.html b/shared/templates/shared/followus_snippet.html
new file mode 100644
index 00000000..59181100
--- /dev/null
+++ b/shared/templates/shared/followus_snippet.html
@@ -0,0 +1,13 @@
+<div class="flex flex-col lg:flex-row lg:space-x-8">
+  <a href="{{ page.facebook }}"
+     class="super-button bg-brands-facebook text-white container-padding--zero lg:container-padding--auto lg:w-1/2 m-2">
+    <span class="super-button__body">Sledujte nás na Facebooku</span>
+    <i class="super-button__icon ico--facebook"></i>
+  </a>
+
+  <a href="{{ page.forum }}"
+     class="super-button bg-black text-white container-padding--zero lg:container-padding--auto lg:w-1/2 m-2">
+    <span class="super-button__body">Sledujte naše fórum</span>
+    <i class="super-button__icon ico--bubbles"></i>
+  </a>
+</div>
diff --git a/district/templates/district/more_articles_snippet.html b/shared/templates/shared/more_articles_snippet.html
similarity index 100%
rename from district/templates/district/more_articles_snippet.html
rename to shared/templates/shared/more_articles_snippet.html
diff --git a/shared/templates/shared/social_icons_snippet.html b/shared/templates/shared/social_icons_snippet.html
new file mode 100644
index 00000000..dbcf521c
--- /dev/null
+++ b/shared/templates/shared/social_icons_snippet.html
@@ -0,0 +1,6 @@
+<a href="{{ page.root_page.twitter|default:"https://www.twitter.com/PiratskaStrana" }}" rel="noopener noreferrer" target="_blank" title="Náš účet na Twitteru" class="social-icon "><i class="ico--twitter"></i></a>
+<a href="{{ page.root_page.youtube|default:"https://www.youtube.com/channel/UC_zxYLGrkmrYazYt0MzyVlA" }}" rel="noopener noreferrer" target="_blank" title="Náš účet na YouTube" class="social-icon "><i class="ico--youtube"></i></a>
+<a href="/feed.xml" rel="noopener noreferrer" target="_blank" title="Články tohoto webu v RSS" class="social-icon "><i class="ico--feed"></i></a>
+<a href=https://www.instagram.com/pirati.cz/" rel="noopener noreferrer" target="_blank" title="Instagram - Česká pirátská strana" class="social-icon "><i class="ico--instagram"></i></a>
+<a href=https://www.flickr.com/photos/pirati/" rel="noopener noreferrer" target="_blank" title="Flickr - Česká pirátská strana" class="social-icon "><i class="ico--flickr"></i></a>
+<a href="mailto:{{ page.root_page.contact_email|default:"info@pirati.cz" }}" class="social-icon "><i class="ico--envelope"></i></a>
diff --git a/shared/templates/styleguide/2.3.x/pagination.html b/shared/templates/styleguide/2.3.x/pagination.html
index 967622a3..c6da34ae 100644
--- a/shared/templates/styleguide/2.3.x/pagination.html
+++ b/shared/templates/styleguide/2.3.x/pagination.html
@@ -4,7 +4,7 @@
   <nav class="pagination space-x-1">
 
     {% if paginator.has_previous %}
-    <a href="{% pageurl page %}?page={{ paginator.previous_page_number }}" class="btn btn--icon btn--grey-125 btn--hoveractive btn--to-black btn--condensed btn--inverted-icon">
+    <a href="{% pageurl page %}?page={{ paginator.previous_page_number }}{{ extra_query }}" class="btn btn--icon btn--grey-125 btn--hoveractive btn--to-black btn--condensed btn--inverted-icon">
       <div class="btn__body-wrap">
         <div class="btn__body ">předchozí</div>
         <div class="btn__icon ">
@@ -16,16 +16,16 @@
 
     {% for i in paginator.paginator.page_range %}
       {% if i == paginator.number %}
-      <a href="{% pageurl page %}?page={{ i }}" class="btn btn--grey-500 btn--condensed hidden md:inline-block">
+      <a href="{% pageurl page %}?page={{ i }}{{ extra_query }}" class="btn btn--grey-500 btn--condensed hidden md:inline-block">
       {% else %}
-      <a href="{% pageurl page %}?page={{ i }}" class="btn btn--grey-125 btn--hoveractive btn--to-black btn--condensed hidden md:inline-block">
+      <a href="{% pageurl page %}?page={{ i }}{{ extra_query }}" class="btn btn--grey-125 btn--hoveractive btn--to-black btn--condensed hidden md:inline-block">
       {% endif %}
         <div class="btn__body ">{{ i }}</div>
       </a>
     {% endfor %}
 
     {% if paginator.has_next %}
-    <a href="{% pageurl page %}?page={{ paginator.next_page_number }}" class="btn btn--icon btn--grey-125 btn--hoveractive btn--to-black btn--condensed">
+    <a href="{% pageurl page %}?page={{ paginator.next_page_number }}{{ extra_query }}" class="btn btn--icon btn--grey-125 btn--hoveractive btn--to-black btn--condensed">
       <div class="btn__body-wrap">
         <div class="btn__body ">další</div>
         <div class="btn__icon ">
-- 
GitLab