diff --git a/uniweb/constants.py b/uniweb/constants.py
index 885537a02d6589bb6ddb8c8b587e7e1b016ae827..3c9c0d49ed09350e400a93e473fe1d1bcb0d6cee 100644
--- a/uniweb/constants.py
+++ b/uniweb/constants.py
@@ -54,3 +54,5 @@ ALIGN_CSS = {
     CENTER: ["text-center"],
     RIGHT: ["text-right"],
 }
+
+ARTICLES_PER_PAGE = 12
diff --git a/uniweb/migrations/0011_uniwebarticlepage_uniwebarticlesindexpage.py b/uniweb/migrations/0011_uniwebarticlepage_uniwebarticlesindexpage.py
new file mode 100644
index 0000000000000000000000000000000000000000..13ca664cc9b4c3ca4a90d0416bca55fce0c8b032
--- /dev/null
+++ b/uniweb/migrations/0011_uniwebarticlepage_uniwebarticlesindexpage.py
@@ -0,0 +1,122 @@
+# Generated by Django 3.1.6 on 2021-02-16 14:45
+
+import django.db.models.deletion
+import django.utils.timezone
+import wagtail.core.fields
+import wagtailmetadata.models
+from django.db import migrations, models
+
+import shared.models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("wagtailcore", "0060_fix_workflow_unique_constraint"),
+        ("wagtailimages", "0023_add_choose_permissions"),
+        ("uniweb", "0010_auto_20210209_1222"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="UniwebArticlesIndexPage",
+            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": "Sekce článků",
+            },
+            bases=(
+                "wagtailcore.page",
+                shared.models.SubpageMixin,
+                wagtailmetadata.models.WagtailImageMetadataMixin,
+                models.Model,
+            ),
+        ),
+        migrations.CreateModel(
+            name="UniwebArticlePage",
+            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": "Článek",
+            },
+            bases=(
+                "wagtailcore.page",
+                shared.models.SubpageMixin,
+                wagtailmetadata.models.WagtailImageMetadataMixin,
+                models.Model,
+            ),
+        ),
+    ]
diff --git a/uniweb/migrations/0012_auto_20210217_0215.py b/uniweb/migrations/0012_auto_20210217_0215.py
new file mode 100644
index 0000000000000000000000000000000000000000..f0e38acf0649dbc819b9e4ad3cee88a61404e67a
--- /dev/null
+++ b/uniweb/migrations/0012_auto_20210217_0215.py
@@ -0,0 +1,44 @@
+# Generated by Django 3.1.6 on 2021-02-17 01:15
+
+import wagtail.core.blocks
+import wagtail.core.fields
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("uniweb", "0011_uniwebarticlepage_uniwebarticlesindexpage"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="uniwebhomepage",
+            name="top_menu",
+            field=wagtail.core.fields.StreamField(
+                [
+                    (
+                        "item",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                ("name", wagtail.core.blocks.CharBlock(label="název")),
+                                (
+                                    "page",
+                                    wagtail.core.blocks.PageChooserBlock(
+                                        label="stránka",
+                                        page_type=[
+                                            "uniweb.UniwebHomePage",
+                                            "uniweb.UniwebFlexiblePage",
+                                            "uniweb.UniwebArticlesIndexPage",
+                                        ],
+                                    ),
+                                ),
+                            ]
+                        ),
+                    )
+                ],
+                blank=True,
+                verbose_name="horní menu",
+            ),
+        ),
+    ]
diff --git a/uniweb/models.py b/uniweb/models.py
index 1a31145f226f119cf8e80b9911daecdfa6e019da..e1388fed3b28db92a27f5e9294ce74d7b8eee907 100644
--- a/uniweb/models.py
+++ b/uniweb/models.py
@@ -1,10 +1,12 @@
 from django import forms
+from django.core.paginator import Paginator
 from django.db import models
 from django.utils.translation import gettext_lazy
 from wagtail.admin.edit_handlers import (
     FieldPanel,
     HelpPanel,
     MultiFieldPanel,
+    PublishingPanel,
     StreamFieldPanel,
 )
 from wagtail.contrib.table_block.blocks import TableBlock
@@ -15,12 +17,13 @@ from wagtail.images.blocks import ImageChooserBlock
 from wagtail.images.edit_handlers import ImageChooserPanel
 from wagtailmetadata.models import MetadataPageMixin
 
-from shared.models import SubpageMixin
+from shared.models import ArticleMixin, SubpageMixin
 from tuning import help
 
 from .constants import (
     ALIGN_CHOICES,
     ALIGN_CSS,
+    ARTICLES_PER_PAGE,
     BLACK_ON_WHITE,
     COLOR_CHOICES,
     COLOR_CSS,
@@ -143,7 +146,11 @@ class MenuItemBlock(blocks.StructBlock):
     name = blocks.CharBlock(label="název")
     page = blocks.PageChooserBlock(
         label="stránka",
-        page_type=["uniweb.UniwebHomePage", "uniweb.UniwebFlexiblePage"],
+        page_type=[
+            "uniweb.UniwebHomePage",
+            "uniweb.UniwebFlexiblePage",
+            "uniweb.UniwebArticlesIndexPage",
+        ],
     )
 
     class Meta:
@@ -255,6 +262,7 @@ class UniwebHomePage(Page, UniwebContentMixin, MetadataPageMixin):
 
     subpage_types = [
         "uniweb.UniwebFlexiblePage",
+        "uniweb.UniwebArticlesIndexPage",
     ]
 
     ### OTHERS
@@ -300,3 +308,86 @@ class UniwebFlexiblePage(Page, UniwebContentMixin, SubpageMixin, MetadataPageMix
 
     class Meta:
         verbose_name = "Flexibilní stránka"
+
+
+class UniwebArticlesIndexPage(Page, SubpageMixin, MetadataPageMixin):
+    ### FIELDS
+
+    ### PANELS
+
+    promote_panels = [
+        MultiFieldPanel(
+            [
+                FieldPanel("slug"),
+                FieldPanel("seo_title"),
+                FieldPanel("search_description"),
+                ImageChooserPanel("search_image"),
+                HelpPanel(help.build(help.NO_SEO_TITLE, help.NO_SEARCH_IMAGE)),
+            ],
+            gettext_lazy("Common page configuration"),
+        ),
+    ]
+
+    settings_panels = []
+
+    ### RELATIONS
+
+    parent_page_types = ["uniweb.UniwebHomePage"]
+    subpage_types = ["uniweb.UniwebArticlePage"]
+
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Sekce článků"
+
+    def get_context(self, request):
+        context = super().get_context(request)
+        articles = (
+            self.get_children().live().specific().order_by("-uniwebarticlepage__date")
+        )
+        num = request.GET.get("page")
+        context["articles"] = Paginator(articles, ARTICLES_PER_PAGE).get_page(num)
+        return context
+
+
+class UniwebArticlePage(Page, ArticleMixin, SubpageMixin, MetadataPageMixin):
+    ### FIELDS
+
+    ### PANELS
+
+    content_panels = ArticleMixin.content_panels
+
+    promote_panels = [
+        MultiFieldPanel(
+            [
+                FieldPanel("slug"),
+                FieldPanel("seo_title"),
+                FieldPanel("search_description"),
+                ImageChooserPanel("search_image"),
+                HelpPanel(help.build(help.NO_SEO_TITLE, help.NO_SEARCH_IMAGE)),
+            ],
+            gettext_lazy("Common page configuration"),
+        ),
+    ]
+
+    settings_panels = [PublishingPanel()]
+
+    ### RELATIONS
+
+    parent_page_types = ["uniweb.UniwebArticlesIndexPage"]
+    subpage_types = []
+
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Článek"
+
+    def get_context(self, request):
+        context = super().get_context(request)
+        context["related_articles"] = (
+            self.get_siblings(inclusive=False)
+            .live()
+            .specific()
+            .order_by("-uniwebarticlepage__date")[:3]
+        )
+        return context
diff --git a/uniweb/templates/uniweb/uniweb_article_page.html b/uniweb/templates/uniweb/uniweb_article_page.html
new file mode 100644
index 0000000000000000000000000000000000000000..8f779824f00237632d8049c5661c1d878ce03a9a
--- /dev/null
+++ b/uniweb/templates/uniweb/uniweb_article_page.html
@@ -0,0 +1,72 @@
+{% extends "uniweb/base.html" %}
+{% load wagtailcore_tags wagtailimages_tags %}
+
+{% block content %}
+
+<article itemtype="http://schema.org/BlogPosting" itemscope="">
+  <header>
+    <link itemprop="mainEntityOfPage" href="{% pageurl page %}">
+    <meta itemprop="datePublished" content="{{ page.first_published_at }}">
+    <meta itemprop="dateModified" content="{{ page.last_published_at }}">
+
+    <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 my-4">
+        <span class="pr-2">{{ page.date|date:"SHORT_DATE_FORMAT" }}</span>
+        {% if page.author %}
+          <span class="pl-2" itemprop="author" itemtype="http://schema.org/Person" itemscope="">
+            <span itemprop="name">{{ page.author }}</span>
+          </span>
+        {% endif %}
+      </div>
+
+      {# TODO tags #}
+      {% comment %}
+      <div class="my-4">
+        <button class="btn btn--grey-125 btn--condensed">
+          <div class="btn__body ">Kategorie 1</div>
+        </button>
+        <button class="btn btn--grey-125 btn--condensed">
+          <div class="btn__body ">Kategorie 2</div>
+        </button>
+      </div>
+      {% endcomment %}
+    </div>
+
+    <figure class="figure">
+      {% image page.image fill-1200x600 as img %}
+      <img src="{{ img.url }}" alt="{{ page.title }}" />
+    </figure>
+  </header>
+
+  <div class="lg:flex mt-8 lg:space-x-16">
+    <div itemprop="description" class="content-block w-full">
+      {{ page.text|richtext }}
+    </div>
+  </div>
+</article>
+
+<section class="mt-16 md:mt-24">
+  {% if related_articles %}
+    <h1 class="head-alt-base md:head-alt-md pb-4">Další {{ page.get_parent.title }}</h1>
+    <div class="article-card-list grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 lg:gap-8">
+      {% for article in related_articles %}
+        {% include "styleguide/2.3.x/article_card.html" %}
+      {% endfor %}
+    </div>
+  {% endif %}
+
+  <div class="text-center mt-8 md:mt-16">
+    <a href="{% pageurl page.get_parent %}" class="btn btn--icon text-xl">
+      <div class="btn__body-wrap">
+        <div class="btn__body ">{{ page.get_parent.title }}</div>
+        <div class="btn__icon ">
+          <i class="ico--chevron-right"></i>
+        </div>
+      </div>
+    </a>
+  </div>
+</section>
+
+{% endblock %}
diff --git a/uniweb/templates/uniweb/uniweb_articles_index_page.html b/uniweb/templates/uniweb/uniweb_articles_index_page.html
new file mode 100644
index 0000000000000000000000000000000000000000..6ec837fcc44aca2d4321f89539ed13b13b641029
--- /dev/null
+++ b/uniweb/templates/uniweb/uniweb_articles_index_page.html
@@ -0,0 +1,35 @@
+{% extends "uniweb/base.html" %}
+
+{% block content %}
+
+<section>
+  <h1 class="head-alt-md md:head-alt-lg max-w-5xl mb-4">{{ page.title }}</h1>
+
+  {# TODO tags #}
+  {% comment %}
+  <nav>
+    <button class="btn btn--grey-125 btn--condensed">
+      <div class="btn__body ">Zobrazit vše</div>
+    </button>
+    <button class="btn btn--grey-125 btn--condensed">
+      <div class="btn__body ">Kategorie 1</div>
+    </button>
+    <button class="btn btn--grey-125 btn--condensed">
+      <div class="btn__body ">Kategorie 2</div>
+    </button>
+    <button class="btn btn--grey-125 btn--condensed">
+      <div class="btn__body ">Kategorie 3</div>
+    </button>
+  </nav>
+  {% endcomment %}
+
+  <hr>
+
+  <main>
+    {% include "styleguide/2.3.x/article_card_list.html" %}
+  </main>
+
+  {% include "styleguide/2.3.x/pagination.html" with paginator=articles %}
+</section>
+
+{% endblock %}