diff --git a/contracts/admin.py b/contracts/admin.py
index 5ff3a2b0be70a36a1756f3d53b06ec76922a14b0..b6804649bae106ce2932326b9c5efd36ce31660f 100644
--- a/contracts/admin.py
+++ b/contracts/admin.py
@@ -10,15 +10,15 @@ from .forms import ContractAdminForm, ContractFileAdminForm, SigneeAdminForm
 from .models import (
     Contract,
     Contractee,
-    ContracteeRepresentative,
     ContracteeSignature,
     ContractFile,
     ContractFilingArea,
     ContractIntent,
     ContractIssue,
     ContractType,
+    ContractContracteeRepresentative,
+    ContractSigneeRepresentative,
     Signee,
-    SigneeRepresentative,
     SigneeSignature,
 )
 
@@ -73,6 +73,17 @@ class ContractIntentInline(admin.TabularInline):
     extra = 0
 
 
+class ContractContracteeRepresentativeInline(admin.TabularInline):
+    form = ContractFileAdminForm
+    model = ContractContracteeRepresentative
+    extra = 0
+
+
+class ContractSigneeRepresentativeInline(admin.TabularInline):
+    model = ContractSigneeRepresentative
+    extra = 0
+
+
 class ContractAdmin(MarkdownxGuardedModelAdmin):
     form = ContractAdminForm
 
@@ -83,8 +94,22 @@ class ContractAdmin(MarkdownxGuardedModelAdmin):
         SigneeSignatureInline,
         ContractFileInline,
         ContractIntentInline,
+        ContractContracteeRepresentativeInline,
+        ContractSigneeRepresentativeInline,
     )
 
+    def __init__(self, *args, **kwargs):
+        from .models import Contract
+        
+        super().__init__(*args, **kwargs)
+        
+        if hasattr(self, "instance"):
+            self.fields["contractee_representatives"].queryset = (
+                Contract
+                .objects
+                .filter(contract=self.instance)
+            )
+
     def get_fieldsets(self, request, obj=None):
         fieldsets = [
             (
@@ -205,11 +230,6 @@ class ContractAdmin(MarkdownxGuardedModelAdmin):
 # BEGIN Signing parties
 
 
-class SigneeRepresentativeInline(admin.TabularInline):
-    model = SigneeRepresentative
-    extra = 0
-
-
 class SigneeAdmin(MarkdownxGuardedModelAdmin):
     form = SigneeAdminForm
 
@@ -232,8 +252,6 @@ class SigneeAdmin(MarkdownxGuardedModelAdmin):
     list_filter = ("entity_type",)
     list_display = ("name", "entity_type")
 
-    inlines = (SigneeRepresentativeInline,)
-
     def load_ares_data_button(self, obj):
         return format_html(
             "<button type=\"button\" id=\"load_ares_data\">Načíst data</button>"
@@ -243,24 +261,14 @@ class SigneeAdmin(MarkdownxGuardedModelAdmin):
     load_ares_data_button.short_description = "ARES"
 
 
-class ContracteeRepresentativeInline(admin.TabularInline):
-    form = ContractFileAdminForm
-    model = ContracteeRepresentative
-    extra = 0
-
-
-class ContracteeAdmin(MarkdownxGuardedModelAdmin):
-    inlines = (ContracteeRepresentativeInline,)
-
-
 # END Signing parties
 
 
 for model in (
     SigneeSignature,
     ContracteeSignature,
-    SigneeRepresentative,
-    ContracteeRepresentative,
+    ContractSigneeRepresentative,
+    ContractContracteeRepresentative,
     ContractType,
     ContractIntent,
 ):
@@ -275,6 +283,5 @@ for model in (
     admin.site.register(model, MarkdownxGuardedModelAdmin)
 
 admin.site.register(Signee, SigneeAdmin)
-admin.site.register(Contractee, ContracteeAdmin)
 
 admin.site.register(Contract, ContractAdmin)
diff --git a/contracts/migrations/0002_alter_contractee_address_country_and_more.py b/contracts/migrations/0002_alter_contractee_address_country_and_more.py
new file mode 100644
index 0000000000000000000000000000000000000000..026c2995260eb10cbd449f2a86c00c6fe363e7e3
--- /dev/null
+++ b/contracts/migrations/0002_alter_contractee_address_country_and_more.py
@@ -0,0 +1,23 @@
+# Generated by Django 4.1.4 on 2023-03-16 21:13
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contracts', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='contractee',
+            name='address_country',
+            field=models.CharField(default='Česká Republika', max_length=256, verbose_name='Země'),
+        ),
+        migrations.AlterField(
+            model_name='signee',
+            name='address_country',
+            field=models.CharField(default='Česká Republika', max_length=256, verbose_name='Země'),
+        ),
+    ]
diff --git a/contracts/migrations/0003_contractcontracteerepresentative_and_more.py b/contracts/migrations/0003_contractcontracteerepresentative_and_more.py
new file mode 100644
index 0000000000000000000000000000000000000000..29fdb316b8028d16e17ef69d40a08074f720c45e
--- /dev/null
+++ b/contracts/migrations/0003_contractcontracteerepresentative_and_more.py
@@ -0,0 +1,55 @@
+# Generated by Django 4.1.4 on 2023-03-16 21:56
+
+import contracts.models
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contracts', '0002_alter_contractee_address_country_and_more'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='ContractContracteeRepresentative',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=256, verbose_name='Jméno')),
+                ('function', models.CharField(blank=True, max_length=256, null=True, verbose_name='Funkce')),
+                ('contract', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contractee_representatives', to='contracts.contract', verbose_name='Smlouva')),
+                ('contractee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contractee_representatives', to='contracts.contractee', verbose_name='Naše smluvní strana')),
+            ],
+            options={
+                'verbose_name': 'Zástupce naší smluvní strany',
+                'verbose_name_plural': 'Zástupci naší smluvní strany',
+            },
+            bases=(contracts.models.RepresentativeMixin, models.Model),
+        ),
+        migrations.CreateModel(
+            name='ContractSigneeRepresentative',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=256, verbose_name='Jméno')),
+                ('function', models.CharField(blank=True, max_length=256, null=True, verbose_name='Funkce')),
+                ('contract', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='signee_representatives', to='contracts.contract', verbose_name='Smlouva')),
+                ('signee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='representatives', to='contracts.signee', verbose_name='Druhá smluvní strana')),
+            ],
+            options={
+                'verbose_name': 'Zástupce druhé smluvní strany',
+                'verbose_name_plural': 'Zástupci druhé smluvní strany',
+            },
+            bases=(contracts.models.RepresentativeMixin, models.Model),
+        ),
+        migrations.RemoveField(
+            model_name='signeerepresentative',
+            name='signee',
+        ),
+        migrations.DeleteModel(
+            name='ContracteeRepresentative',
+        ),
+        migrations.DeleteModel(
+            name='SigneeRepresentative',
+        ),
+    ]
diff --git a/contracts/models.py b/contracts/models.py
index 509ed7daaf5aced4a101b16520c85ce5c074d621..ea19f34a26596daa32d7ccc38c8375823ead7dff 100644
--- a/contracts/models.py
+++ b/contracts/models.py
@@ -115,44 +115,9 @@ class Signee(models.Model):
         if self.department is not None:
             result += f", {self.department}"
 
-        representative_names = []
-
-        for representative in self.representatives.all():
-            representative_names.append(representative.name)
-
-        if len(representative_names) != 0:
-            result += " - zástupci " + ", ".join(representative_names)
-
         return result
 
 
-class SigneeRepresentative(RepresentativeMixin, models.Model):
-    signee = models.ForeignKey(
-        Signee,
-        on_delete=models.CASCADE,
-        related_name="representatives",
-        verbose_name="Smluvní strana",
-    )
-
-    name = models.CharField(
-        max_length=256,
-        verbose_name="Jméno",
-    )
-
-    function = models.CharField(
-        max_length=256,
-        blank=True,
-        null=True,
-        verbose_name="Funkce",
-    )
-
-    class Meta:
-        app_label = "contracts"
-
-        verbose_name = "Zástupce"
-        verbose_name_plural = "Zástupci"
-
-
 class Contractee(models.Model):
     name = models.CharField(
         max_length=256,
@@ -218,44 +183,9 @@ class Contractee(models.Model):
         if self.department is not None:
             result += f", {self.department}"
 
-        representative_names = []
-
-        for representative in self.representatives.all():
-            representative_names.append(representative.name)
-
-        if len(representative_names) != 0:
-            result += " - zástupci " + ", ".join(representative_names)
-
         return result
 
 
-class ContracteeRepresentative(RepresentativeMixin, models.Model):
-    contractee = models.ForeignKey(
-        Contractee,
-        on_delete=models.CASCADE,
-        related_name="representatives",
-        verbose_name="Smluvní strana",
-    )
-
-    name = models.CharField(
-        max_length=256,
-        verbose_name="Jméno",
-    )
-
-    function = models.CharField(
-        max_length=256,
-        blank=True,
-        null=True,
-        verbose_name="Funkce",
-    )
-
-    class Meta:
-        app_label = "contracts"
-
-        verbose_name = "Zástupce"
-        verbose_name_plural = "Zástupci"
-
-
 class ContractType(NameStrMixin, models.Model):
     name = models.CharField(
         max_length=32,
@@ -510,6 +440,74 @@ class Contract(NameStrMixin, models.Model):
         ).all()
 
 
+class ContractContracteeRepresentative(RepresentativeMixin, models.Model):
+    contract = models.ForeignKey(
+        Contract,
+        on_delete=models.CASCADE,
+        related_name="contractee_representatives",
+        verbose_name="Smlouva"
+    )
+
+    contractee = models.ForeignKey(
+        Contractee,
+        on_delete=models.CASCADE,
+        related_name="contractee_representatives",
+        verbose_name="Naše smluvní strana",
+    )
+
+    name = models.CharField(
+        max_length=256,
+        verbose_name="Jméno",
+    )
+
+    function = models.CharField(
+        max_length=256,
+        blank=True,
+        null=True,
+        verbose_name="Funkce",
+    )
+
+    class Meta:
+        app_label = "contracts"
+
+        verbose_name = "Zástupce naší smluvní strany"
+        verbose_name_plural = "Zástupci naší smluvní strany"
+
+
+class ContractSigneeRepresentative(RepresentativeMixin, models.Model):
+    contract = models.ForeignKey(
+        Contract,
+        on_delete=models.CASCADE,
+        related_name="signee_representatives",
+        verbose_name="Smlouva"
+    )
+    
+    signee = models.ForeignKey(
+        Signee,
+        on_delete=models.CASCADE,
+        related_name="representatives",
+        verbose_name="Druhá smluvní strana",
+    )
+
+    name = models.CharField(
+        max_length=256,
+        verbose_name="Jméno",
+    )
+
+    function = models.CharField(
+        max_length=256,
+        blank=True,
+        null=True,
+        verbose_name="Funkce",
+    )
+
+    class Meta:
+        app_label = "contracts"
+
+        verbose_name = "Zástupce druhé smluvní strany"
+        verbose_name_plural = "Zástupci druhé smluvní strany"
+
+
 class ContractFile(NameStrMixin, models.Model):
     name = models.CharField(
         max_length=128,
@@ -567,20 +565,7 @@ class ContracteeSignature(models.Model):
         verbose_name_plural = "Podpisy našich smluvních stran"
 
     def __str__(self) -> str:
-        representative_names = []
-
-        for representative in self.contractee.representatives.all():
-            representative_names.append(representative.name)
-
-        representatives = ", ".join(representative_names)
-        result = self.contractee.name
-
-        if len(representatives) != 0:
-            result += f" - zastoupena {representatives}"
-
-        result += f", {self.date}"
-
-        return result
+        return f"{self.contractee.name} - {self.date}"
 
 
 class SigneeSignature(models.Model):
@@ -609,20 +594,7 @@ class SigneeSignature(models.Model):
         verbose_name_plural = "Podpisy ostatních smluvních stran"
 
     def __str__(self) -> str:
-        representative_names = []
-
-        for representative in self.signee.representatives.all():
-            representative_names.append(representative.name)
-
-        representatives = ", ".join(representative_names)
-        result = self.signee.name
-
-        if len(representatives) != 0:
-            result += f" - zastoupena {representatives}"
-
-        result += f", {self.date}"
-
-        return result
+        return f"{self.signee.name} - {self.date}"
 
 
 class ContractIntent(NameStrMixin, models.Model):
diff --git a/registry/templates/admin/base_site.html b/registry/templates/admin/base_site.html
index 20560f91810163da950f74064fc5c50f9580c662..e4a08e06fda7012f08de8f2ca0aabe654591ae22 100644
--- a/registry/templates/admin/base_site.html
+++ b/registry/templates/admin/base_site.html
@@ -14,7 +14,7 @@
     .index-action-buttons {
         display: flex;
         flex-direction: row;
-        row-gap: 10px;
+        column-gap: 10px;
     }
     
     .index-action-buttons button,
diff --git a/registry/templates/admin/index.html b/registry/templates/admin/index.html
index be5f8f584b9ea89b3e92aeb306b25de32b31e639..1a3722a1222423c554d102d00ae14a906680d5b2 100644
--- a/registry/templates/admin/index.html
+++ b/registry/templates/admin/index.html
@@ -2,12 +2,20 @@
 
 {% block content %}
 
-{% if request.user.can_approve_contracts %}
+{% if request.user.can_approve_contracts or request.user.can_create_contracts %}
     <div class="index-action-buttons">
-        <a
-            href="contracts/contract/?approval_state__exact=no"
-            aria-role="button"
-        >Smlouvy ke schválení ({{ request.user.contracts_to_approve_count }})</a>
+        {% if request.user.can_approve_contracts %}
+            <a
+                href="contracts/contract/?approval_state__exact=no"
+                aria-role="button"
+            >Smlouvy ke schválení ({{ request.user.contracts_to_approve_count }})</a>
+        {% endif %}
+        {% if request.user.can_create_contracts %}
+            <a
+                href="contracts/contract/add/"
+                aria-role="button"
+            >Nahrát smlouvu</a>
+        {% endif %}
     </div>
 {% endif %}
 
diff --git a/static_src/base.css b/static_src/base.css
index 44f1cb603a7646e785005d3627740563ef4fb9e4..b4c81f5cbfbb23ed74be6899482afb681fc56ddc 100644
--- a/static_src/base.css
+++ b/static_src/base.css
@@ -4,9 +4,9 @@
 
 
 @layer base {
-  html {
-    font-family: "Roboto Condensed", system-ui, sans-serif;
-  }
+    html {
+        font-family: "Roboto Condensed", system-ui, sans-serif;
+    }
 }
 
 
diff --git a/users/models.py b/users/models.py
index 52074a4ad16afef593a5d1413baecf7f4be6cc79..d08f1012e470ad97c4e241016e7870071fbc367f 100644
--- a/users/models.py
+++ b/users/models.py
@@ -19,6 +19,11 @@ class User(pirates_models.AbstractUser):
         # TODO: Do we need the superuser check?
         return self.is_superuser or self.has_perm("contracts.approve")
 
+    @property
+    def can_create_contracts(self) -> bool:
+        # TODO: Do we need the superuser check?
+        return self.is_superuser or self.has_perm("contracts.add")
+
     @property
     def contracts_to_approve_count(self) -> int:
         if not self.can_approve_contracts: