diff --git a/main/static/main/css/styles.css b/main/static/main/css/styles.css
index 5dc5146ed83be3e041627147452a4601dc03cde0..54e5929ddff1711384fc693feee685a8534bc89d 100644
--- a/main/static/main/css/styles.css
+++ b/main/static/main/css/styles.css
@@ -3608,6 +3608,14 @@ div.twitter-carousel .slick-arrow.slick-disabled:before, div.twitter-carousel .s
   height: 15rem;
 }
 
+.h-10{
+  height: 2.5rem;
+}
+
+.h-80{
+  height: 20rem;
+}
+
 .h-fit{
   height: -webkit-fit-content;
   height: -moz-fit-content;
@@ -3674,6 +3682,10 @@ div.twitter-carousel .slick-arrow.slick-disabled:before, div.twitter-carousel .s
   max-width: 42rem;
 }
 
+.flex-shrink-0{
+  flex-shrink: 0;
+}
+
 .shrink-0{
   flex-shrink: 0;
 }
@@ -3718,6 +3730,10 @@ div.twitter-carousel .slick-arrow.slick-disabled:before, div.twitter-carousel .s
   justify-content: flex-start;
 }
 
+.justify-end{
+  justify-content: flex-end;
+}
+
 .justify-center{
   justify-content: center;
 }
@@ -4567,10 +4583,6 @@ a.icon-link:hover span{
     width: 41.666667%;
   }
 
-  .sm\:max-w-xs{
-    max-width: 20rem;
-  }
-
   .sm\:flex-col{
     flex-direction: column;
   }
diff --git a/main/styleguide/source/_patterns/molecules/twitter-box.mustache b/main/styleguide/source/_patterns/molecules/twitter-box.mustache
index 05fd073231a1423dd648bc63cd146906074ed681..e895c73b58b63d61d7e701538149dab362cdcefc 100644
--- a/main/styleguide/source/_patterns/molecules/twitter-box.mustache
+++ b/main/styleguide/source/_patterns/molecules/twitter-box.mustache
@@ -1,6 +1,6 @@
-<a href="#" class="mb-5 p-4 w-full flex flex-col items-center justify-between text-center border border-grey-100 sm:mb-0 hover:no-underline">
-  <div>
-    <div class="flex flex-row sm:flex-col items-start sm:items-center">
+<a href="#" class="mb-5 w-full flex flex-col items-center justify-end overflow-hidden text-center border border-grey-100 sm:mb-0 hover:no-underline">
+  <div class="h-full p-4">
+    <div class="flex flex-row sm:flex-col items-start sm:items-center justify-center">
       <img
         class="rounded-full shadow-sm w-12 mr-2 sm:mr-0 mb-0 sm:mb-2"
         src="https://randomuser.me/api/portraits/women/56.jpg"
@@ -14,12 +14,22 @@
           @pirat.tomas.marny
         </small>
       </div>
+      <p class="text-small sm:text-base leading-6 mb-2">
+        Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
+        nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et
+        justo duo dolores et ea rebum.
+      </p>
     </div>
-    <p class="text-small sm:text-base leading-6 mb-2">
-      Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
-      nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et
-      justo duo dolores et ea rebum.
-    </p>
   </div>
-  <i class="ico--twitter text-turquoise-400 text-3xl sm:text-xl"></i>
+
+  <div class="flex-shrink-0 h-10">
+    <i class="ico--twitter text-turquoise-400 text-3xl sm:text-xl"></i>
+  </div>
+
+  <div class="flex-shrink-0 h-80">
+    <img
+      src="https://randomuser.me/api/portraits/women/56.jpg"
+      alt="Obrázek Tweetu"
+    />
+  </div>
 </a>
diff --git a/main/styleguide/source/_patterns/organisms/twitter-section.mustache b/main/styleguide/source/_patterns/organisms/twitter-section.mustache
index dc645e909ab855182be58426ecab37b543a35edc..5cedfbcd3d74a1f9099530089924ebebb2924715 100644
--- a/main/styleguide/source/_patterns/organisms/twitter-section.mustache
+++ b/main/styleguide/source/_patterns/organisms/twitter-section.mustache
@@ -5,16 +5,16 @@
   </h2>
   </div>
   <div class="flex flex-wrap justify-center">
-    <div class="w-full flex max-w-sm sm:max-w-xs">
+    <div class="flex max-w-sm max-w-xs w-full">
       {{> molecules-twitter-box }}
     </div>
-    <div class="w-full flex max-w-sm sm:max-w-xs">
+    <div class="flex max-w-sm max-w-xs w-full">
       {{> molecules-twitter-box }}
     </div>
-    <div class="w-full flex max-w-sm sm:max-w-xs">
+    <div class="flex max-w-sm max-w-xs w-full">
       {{> molecules-twitter-box }}
     </div>
-    <div class="w-full flex max-w-sm sm:max-w-xs">
+    <div class="flex max-w-sm max-w-xs w-full">
       {{> molecules-twitter-box }}
     </div>
   </div>
diff --git a/main/templates/main/includes/twitter_widget.html b/main/templates/main/includes/twitter_widget.html
index befe8e701492d6b8d2c25abcb7233b152d700bac..4b3da50580621682122f63abf3fd3f990c2bab1d 100644
--- a/main/templates/main/includes/twitter_widget.html
+++ b/main/templates/main/includes/twitter_widget.html
@@ -1,15 +1,15 @@
 <div class="flex flex-wrap justify-center">
   {% for tweet in tweet_list %}
-    <div class="w-full flex max-w-sm sm:max-w-xs">
+    <div class="flex max-w-sm max-w-xs w-full">
       <a
         href="https://twitter.com/{{ tweet.author_username }}"
-        class="mb-5 p-4 w-full flex flex-col items-center justify-between text-center border border-grey-100 sm:mb-0 hover:no-underline"
+        class="mb-5 w-full flex flex-col items-center justify-end overflow-hidden text-center border border-grey-100 sm:mb-0 hover:no-underline"
       >
-        <div>
-          <div class="flex flex-row sm:flex-col items-start sm:items-center">
+        <div class="h-full p-4">
+          <div class="flex flex-row sm:flex-col items-start sm:items-center justify-center">
             <img
               class="rounded-full shadow-sm w-12 mr-2 sm:mr-0 mb-0 sm:mb-2"
-              src="{{ tweet.author_img_url }}"
+              src="{{ tweet.author_img.url }}"
               alt="user image"
             />
             <div class="flex flex-col sm:flex-col">
@@ -21,11 +21,20 @@
               </small>
             </div>
           </div>
-          <p class="text-small sm:text-base leading-6 mb-2">
+          <p class="text-small sm:text-base leading-6">
             {{ tweet.text }}
           </p>
         </div>
-        <i class="ico--twitter text-turquoise-400 text-3xl sm:text-xl"></i>
+
+        <div class="flex-shrink-0 h-10">
+          <i class="ico--twitter text-turquoise-400 text-3xl sm:text-xl"></i>
+        </div>
+
+        {% if tweet.image %}
+          <div class="flex-shrink-0 h-80" style="height: 320px;">
+            <img src="{{ tweet.image.url }}" alt="Obrázek Tweetu" />
+          </div>
+        {% endif %}
       </a>
     </div>
   {% endfor %}
diff --git a/main/templates/main/main_person_page.html b/main/templates/main/main_person_page.html
index 2e260edbfffa7ad8b985114a8d07b2ac749c7efa..175d75e46333b4e70b05f48e271137c8d17de72f 100644
--- a/main/templates/main/main_person_page.html
+++ b/main/templates/main/main_person_page.html
@@ -68,7 +68,7 @@
                   <div class="mb-5 p-4 flex flex-col h-full items-center text-center border border-grey-100 sm:mb-0">
                     <div class="flex flex-row sm:flex-col items-center">
                       <img class="rounded-full shadow-sm w-12 h-12 mb-4 sm:mb-2"
-                           src="{{ tweet.author_img_url }}"
+                           src="{{ tweet.author_img.url }}"
                            alt="user image"/>
                       <div class="flex flex-col sm:flex-col">
                         <h5 class="font-alt text-xl mb-2 sm:text-base">{{ tweet.author_name }}</h5>
diff --git a/twitter_utils/migrations/0002_remove_tweet_author_img_url_tweet_author_img_and_more.py b/twitter_utils/migrations/0002_remove_tweet_author_img_url_tweet_author_img_and_more.py
new file mode 100644
index 0000000000000000000000000000000000000000..6a4e74c3ae0f9b3b3375096cf8bd7ba8d88e9a79
--- /dev/null
+++ b/twitter_utils/migrations/0002_remove_tweet_author_img_url_tweet_author_img_and_more.py
@@ -0,0 +1,33 @@
+# Generated by Django 4.0.7 on 2022-10-21 09:45
+
+from django.db import migrations, models
+
+import twitter_utils.storages
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("twitter_utils", "0001_initial"),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name="tweet",
+            name="author_img_url",
+        ),
+        migrations.AddField(
+            model_name="tweet",
+            name="author_img",
+            field=models.ImageField(
+                null=True,
+                storage=twitter_utils.storages.OverwriteStorage,
+                upload_to="twitter_accounts",
+            ),
+        ),
+        migrations.AddField(
+            model_name="tweet",
+            name="image",
+            field=models.ImageField(null=True, upload_to="twitter"),
+        ),
+    ]
diff --git a/twitter_utils/migrations/0003_alter_tweet_author_img.py b/twitter_utils/migrations/0003_alter_tweet_author_img.py
new file mode 100644
index 0000000000000000000000000000000000000000..ce4ae896c6cb6c4566931e47e581de039b549ea3
--- /dev/null
+++ b/twitter_utils/migrations/0003_alter_tweet_author_img.py
@@ -0,0 +1,23 @@
+# Generated by Django 4.0.7 on 2022-10-21 09:45
+
+from django.db import migrations, models
+
+import twitter_utils.storages
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("twitter_utils", "0002_remove_tweet_author_img_url_tweet_author_img_and_more"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="tweet",
+            name="author_img",
+            field=models.ImageField(
+                storage=twitter_utils.storages.OverwriteStorage,
+                upload_to="twitter_accounts",
+            ),
+        ),
+    ]
diff --git a/twitter_utils/models.py b/twitter_utils/models.py
index 0f4c7115dc95b96d20c8d733ec5199aa8febc9ee..b15e9eb8f4622e7110c49a4cc949c46fd668123d 100644
--- a/twitter_utils/models.py
+++ b/twitter_utils/models.py
@@ -1,5 +1,7 @@
 from django.db import models
 
+from twitter_utils.storages import OverwriteStorage
+
 
 class TweetQueryset(models.QuerySet):
     def username(self, username):
@@ -16,11 +18,13 @@ class Tweet(models.Model):
     nejnovějších Tweetů (2022).
     """
 
-    author_img_url = models.URLField(
-        default="https://pbs.twimg.com/profile_images/1556544269443387394/jSO2A2Fr_200x200.jpg"
-    )  # TODO consider another default, maybe from static
+    author_img = models.ImageField(
+        storage=OverwriteStorage, upload_to="twitter_accounts"
+    )
     author_name = models.CharField(max_length=128, default="Piráti")
     author_username = models.CharField(max_length=128, default="PiratskaStrana")
+
+    image = models.ImageField(null=True, upload_to="twitter")
     text = models.TextField()
     twitter_id = models.CharField(max_length=32, unique=True)
 
diff --git a/twitter_utils/services.py b/twitter_utils/services.py
index 9057c65b71d24eab13618299795c09e49322b27d..38eec1eb6050714d23f657409aab68e3e941608e 100644
--- a/twitter_utils/services.py
+++ b/twitter_utils/services.py
@@ -1,7 +1,10 @@
 import logging
+import os
 from datetime import timedelta
 from typing import TYPE_CHECKING
+from urllib import request
 
+from django.core.files import File
 from django.utils import timezone
 from tweepy import Client
 from tweepy.errors import BadRequest
@@ -11,6 +14,7 @@ from main.models import MainHomePage, MainPersonPage
 from .models import Tweet
 
 if TYPE_CHECKING:
+    from tweepy import Media
     from tweepy import Tweet as TweetResponse
     from tweepy import User
 
@@ -35,14 +39,27 @@ class TweetDownloadService:
         self.days_back = days_back
 
     @staticmethod
-    def get_latest_saved_tweet_id() -> list[int]:
+    def download_remote_image(image_url) -> (str, File):
+        try:
+            response = request.urlretrieve(image_url)
+        except Exception as exc:
+            logger.warning(exc)
+            return "", None
+        return os.path.basename(image_url), File(open(response[0], "rb"))
+
+    @staticmethod
+    def get_existing_tweet_id_list() -> list[int]:
         """
         Vrací IDs už uložených Tweetů - možná by stálo za to brát jen z určitého
         časového období...
         """
         return Tweet.objects.values_list("twitter_id", flat=True)
 
-    def get_tweets_response(self, user_id) -> list["TweetResponse"]:
+    @staticmethod
+    def get_tweet_media_url(media_key, media_list):
+        return next(m.url for m in media_list if m.media_key == media_key)
+
+    def get_tweets_response(self, user_id) -> (list["TweetResponse"], list["Media"]):
         """
         Vrací list tweetů (objektů) pro daného Twitter uživatele.
         """
@@ -61,7 +78,7 @@ class TweetDownloadService:
             user_fields=["name", "username"],
         )
 
-        return tweets_response.data or []
+        return tweets_response.data or [], tweets_response[1].get("media", [])
 
     def get_user_list_data(self) -> list["User"]:
         twitter_usernames_block = MainHomePage.objects.first().twitter_usernames
@@ -105,22 +122,48 @@ class TweetDownloadService:
         """
         Obaluje celý proces downloadu Tweetů z API do DB.
         """
+        existing_tweet_id_list = self.get_existing_tweet_id_list()
         user_data_list = self.get_user_list_data()
-        existing_tweet_id_list = self.get_latest_saved_tweet_id()
 
         tweets_to_save = []
 
         for user_data in user_data_list:
-            for tweet in self.get_tweets_response(user_id=user_data.id):
-                if str(tweet.id) not in existing_tweet_id_list:
-                    tweets_to_save.append(
-                        Tweet(
-                            author_img_url=user_data.profile_image_url,
-                            author_name=user_data.name,
-                            author_username=user_data.username,
-                            text=tweet.text.split("https://t.co")[0],
-                            twitter_id=str(tweet.id),
-                        )
-                    )
+            tweet_resp_list, media_list = self.get_tweets_response(user_id=user_data.id)
+            for tweet_response in tweet_resp_list:
+                if str(tweet_response.id) in existing_tweet_id_list:
+                    continue
+
+                # vyzobej data z responses
+                tweet = Tweet(
+                    author_name=user_data.name,
+                    author_username=user_data.username,
+                    text=tweet_response.text.split("https://t.co")[0],
+                    twitter_id=str(tweet_response.id),
+                )
+
+                # ulož obrázek Twitter účtu do media
+                tweet.author_img.save(
+                    *self.download_remote_image(user_data.profile_image_url),
+                    False  # to prevent model save before bulk create
+                )
+
+                # zkus dohledat obrázek pro Tweet
+                if tweet_response.attachments:
+                    self.try_find_image_for_tweet(tweet, tweet_response, media_list)
+
+                # přidej do seznamu k uložení
+                tweets_to_save.append(tweet)
 
         return Tweet.objects.bulk_create(tweets_to_save)
+
+    def try_find_image_for_tweet(
+        self, tweet: Tweet, tweet_response: "TweetResponse", media_list: list["Media"]
+    ):
+        tweet_media_keys = tweet_response.attachments.get("media_keys", [])
+        if tweet_media_keys:
+            img_url = self.get_tweet_media_url(tweet_media_keys[0], media_list)
+            if img_url:  # ne vždycky je obrázek v media_listu...
+                tweet.image.save(
+                    *self.download_remote_image(image_url=img_url),
+                    False  # to prevent model save before bulk create
+                )
diff --git a/twitter_utils/storages.py b/twitter_utils/storages.py
new file mode 100644
index 0000000000000000000000000000000000000000..04ffc57c65063e95d4a2cc24074df87088d19fa2
--- /dev/null
+++ b/twitter_utils/storages.py
@@ -0,0 +1,19 @@
+import os
+
+from django.conf import settings
+from django.core.files.storage import get_storage_class
+
+
+class OverwriteStorage(get_storage_class()):
+    def get_available_name(self, name, max_length):
+        """
+        Returns a filename that's free on the target storage system, and
+        available for new content to be written to. This file storage solves overwrite
+        on upload problem.
+
+        Found at https://djangosnippets.org/snippets/976/
+        """
+        # If the filename already exists, remove it as if it was a true file system
+        if self.exists(name):
+            os.remove(os.path.join(settings.MEDIA_ROOT, name))
+        return name