diff --git a/contracts/admin.py b/contracts/admin.py
index 448b49370579948ec196cd923e8c1d328aee33de..0b72ac6e136d2b3f37db10ad2fb4f26021b0cfd0 100644
--- a/contracts/admin.py
+++ b/contracts/admin.py
@@ -53,25 +53,6 @@ class ContractIntentInline(admin.TabularInline):
 class ContractAdmin(MarkdownxGuardedModelAdmin):
     form = ContractAdminForm
 
-    fields = (
-        "created_by",
-        "types",
-        "valid_start_date",
-        "valid_end_date",
-        "legal_state",
-        "public_state",
-        "paper_form_state",
-        "publishing_rejection_comment",
-        "tender_url",
-        "identifier",
-        "issues",
-        "notes",
-        "summary",
-        "primary_contract",
-        "agreement_url",
-        "filing_area",
-    )
-
     readonly_fields = ("created_by",)
 
     inlines = (
@@ -81,6 +62,34 @@ class ContractAdmin(MarkdownxGuardedModelAdmin):
         ContractIntentInline,
     )
 
+    def get_fields(self, request, obj=None):
+        fields = [
+            "created_by",
+            "types",
+            "valid_start_date",
+            "valid_end_date",
+            "legal_state",
+            "public_state",
+            "paper_form_state",
+            "publishing_rejection_comment",
+            "tender_url",
+            "identifier",
+            "issues",
+            "notes",
+            "summary",
+            "primary_contract",
+            "agreement_url",
+            "filing_area",
+            "expected_cost_year",
+            "expected_cost_month",
+            "expected_cost_hour",
+        ]
+
+        if request.user.is_superuser or request.user.has_perm("approve", self):
+            fields.append("is_approved")
+
+        return fields
+
     def save_model(self, request, obj, form, change) -> None:
         if obj.created_by is None:
             obj.created_by = request.user
@@ -101,10 +110,7 @@ class SigneeRepresentativeInline(admin.TabularInline):
 class SigneeAdmin(MarkdownxGuardedModelAdmin):
     form = SigneeAdminForm
 
-    inlines = (
-        SigneeRepresentativeInline,
-        SigneeSignatureInline,
-    )
+    inlines = (SigneeRepresentativeInline,)
 
 
 class ContracteeRepresentativeInline(admin.TabularInline):
@@ -113,7 +119,7 @@ class ContracteeRepresentativeInline(admin.TabularInline):
 
 
 class ContracteeAdmin(MarkdownxGuardedModelAdmin):
-    inlines = (ContracteeRepresentativeInline, ContracteeSignatureInline)
+    inlines = (ContracteeRepresentativeInline,)
 
 
 # END Signing parties
diff --git a/contracts/migrations/0003_contract_expected_cost_hour_and_more.py b/contracts/migrations/0003_contract_expected_cost_hour_and_more.py
new file mode 100644
index 0000000000000000000000000000000000000000..c098ed3c5bd8cc679e1aad284c477a93ac5f574f
--- /dev/null
+++ b/contracts/migrations/0003_contract_expected_cost_hour_and_more.py
@@ -0,0 +1,28 @@
+# Generated by Django 4.1.4 on 2023-02-21 05:33
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contracts', '0002_contract_is_approved_alter_contract_valid_end_date'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='contract',
+            name='expected_cost_hour',
+            field=models.IntegerField(blank=True, null=True, verbose_name='Očekávané výdaje (hodina)'),
+        ),
+        migrations.AddField(
+            model_name='contract',
+            name='expected_cost_month',
+            field=models.IntegerField(blank=True, null=True, verbose_name='Očekávané výdaje (měsíc)'),
+        ),
+        migrations.AddField(
+            model_name='contract',
+            name='expected_cost_year',
+            field=models.IntegerField(blank=True, null=True, verbose_name='Očekávané výdaje (rok)'),
+        ),
+    ]
diff --git a/contracts/migrations/0004_alter_contract_options.py b/contracts/migrations/0004_alter_contract_options.py
new file mode 100644
index 0000000000000000000000000000000000000000..5b6fd8af549d471295c74a6f2a310f15ed37bffc
--- /dev/null
+++ b/contracts/migrations/0004_alter_contract_options.py
@@ -0,0 +1,17 @@
+# Generated by Django 4.1.4 on 2023-02-21 05:42
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contracts', '0003_contract_expected_cost_hour_and_more'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='contract',
+            options={'permissions': (('approve', 'Schválit / zrušit schválení'),), 'verbose_name': 'Smlouva', 'verbose_name_plural': 'Smlouvy'},
+        ),
+    ]
diff --git a/contracts/migrations/0005_alter_contract_primary_contract.py b/contracts/migrations/0005_alter_contract_primary_contract.py
new file mode 100644
index 0000000000000000000000000000000000000000..b777807d54ae05a27dfb107fb3079277e94b2534
--- /dev/null
+++ b/contracts/migrations/0005_alter_contract_primary_contract.py
@@ -0,0 +1,19 @@
+# Generated by Django 4.1.4 on 2023-02-21 06:07
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contracts', '0004_alter_contract_options'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='contract',
+            name='primary_contract',
+            field=models.ForeignKey(blank=True, help_text='Např. pro dodatky nebo objednávky u rámcových smluv.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subcontracts', to='contracts.contract', verbose_name='Primární smlouva'),
+        ),
+    ]
diff --git a/contracts/models.py b/contracts/models.py
index 126d358f065bd54824bde018f2838ab425f32544..7575f796be0a72235f5d580b28a47a18925ac169 100644
--- a/contracts/models.py
+++ b/contracts/models.py
@@ -1,3 +1,5 @@
+import math
+
 from django.conf import settings
 from django.db import models
 from django_countries.fields import CountryField
@@ -33,7 +35,38 @@ class RepresentativeMixin:
         return result
 
 
-class Signee(models.Model):
+class ColorMixin(models.Model):
+    color = ColorField(
+        blank=True,
+        null=True,
+        verbose_name="Barva",
+    )
+
+    @property
+    def color_is_light(self) -> bool:
+        if self.color is None:
+            raise ValueError
+
+        # https://stackoverflow.com/a/29643643 - Thanks to John1024 and vallentin!
+        # https://stackoverflow.com/a/58270890 - Thanks to Kardi Teknomo!
+        
+        hex_color = self.color.lstrip("#")
+        rgb_color = tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
+        
+        [r, g, b] = rgb_color
+        
+        hsp = math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b))
+
+        if hsp > 127.5:
+            return True
+        else:
+            return False
+
+    class Meta:
+        abstract = True
+
+
+class Signee(ColorMixin, models.Model):
     name = models.CharField(
         max_length=256,
         verbose_name="Jméno",
@@ -85,12 +118,6 @@ class Signee(models.Model):
         verbose_name="Organizační složka",
     )
 
-    color = ColorField(
-        blank=True,
-        null=True,
-        verbose_name="Barva",
-    )
-
     class Meta:
         verbose_name = "Jiná smluvní strana"
         verbose_name_plural = "Ostatní smluvní strany"
@@ -150,7 +177,7 @@ class SigneeRepresentative(RepresentativeMixin, models.Model):
         verbose_name_plural = "Zástupci"
 
 
-class Contractee(models.Model):
+class Contractee(ColorMixin, models.Model):
     name = models.CharField(
         max_length=256,
         default=settings.DEFAULT_CONTRACTEE_NAME,
@@ -195,12 +222,6 @@ class Contractee(models.Model):
         verbose_name="Organizační složka",
     )
 
-    color = ColorField(
-        blank=True,
-        null=True,
-        verbose_name="Barva",
-    )
-
     class Meta:
         verbose_name = "Naše smluvní strana"
         verbose_name_plural = "Naše smluvní strany"
@@ -420,6 +441,7 @@ class Contract(models.Model):
         null=True,
         related_name="subcontracts",
         verbose_name="Primární smlouva",
+        help_text="Např. pro dodatky nebo objednávky u rámcových smluv."
     )  # WARNING: Dependent on the type!
 
     filing_area = models.ForeignKey(
@@ -432,12 +454,26 @@ class Contract(models.Model):
         help_text="Obsah není veřejně přístupný.",
     )  # WARNING: Dependent on the type!
 
+    # NOTE: Could we make this into expected_cost_type and expected_cost_amount?
+
     expected_cost_year = models.IntegerField(
         blank=True,
         null=True,
         verbose_name="Očekávané výdaje (rok)",
     )
     
+    expected_cost_month = models.IntegerField(
+        blank=True,
+        null=True,
+        verbose_name="Očekávané výdaje (měsíc)",
+    )
+    
+    expected_cost_hour = models.IntegerField(
+        blank=True,
+        null=True,
+        verbose_name="Očekávané výdaje (hodina)",
+    )
+    
     is_approved = models.BooleanField(
         verbose_name="Je schválená",
         help_text=(
@@ -449,6 +485,10 @@ class Contract(models.Model):
     class Meta:
         verbose_name = "Smlouva"
         verbose_name_plural = "Smlouvy"
+        
+        permissions = (
+            ("approve", "Schválit / zrušit schválení"),
+        )
 
     def __str__(self) -> str:
         return self.identifier
diff --git a/contracts/templates/contracts/index.html b/contracts/templates/contracts/index.html
index f868502e1a8105da495b457da712361986f33d02..9771b74f01162ed9d8a75f76c4dc9bb704a288ec 100644
--- a/contracts/templates/contracts/index.html
+++ b/contracts/templates/contracts/index.html
@@ -7,7 +7,7 @@
         <thead>
             <tr>
                 <td class="font-bold">Identifikace</td>
-                <td>Typ</td>
+                <td>Typy</td>
                 <td>Právní stav</td>
                 <td>Účinná od</td>
                 <td>Účinná do</td>
@@ -37,7 +37,7 @@
                         <ul class="flex flex-wrap gap-1.5">
                             {% for signature in contract.signee_signatures.all %}
                                 <li
-                                    class="p-1.5 rounded-sm whitespace-nowrap cursor-pointer {% if not signature.signee.color %}bg-gray-200 duration-100 hover:bg-gray-300{% endif %}"
+                                    class="p-1.5 rounded-sm whitespace-nowrap cursor-pointer {% if not signature.signee.color %}bg-gray-200 duration-100 hover:bg-gray-300{% endif %}{% if signature.signee.color and not signature.signee.color_is_light %} text-white{% endif %}"
                                     {% if signature.signee.color %}style="background-color:{{ signature.signee.color }}"{% endif %}
                                 >{{ signature.signee.name }}</li>
                             {% endfor %}
diff --git a/contracts/templates/contracts/view_contract.html b/contracts/templates/contracts/view_contract.html
index f6b0481e83e4d9f9f805c6e40d57e735f8b53795..5e99e8416408f42d90d3a218ce9d45b51edf1a1a 100644
--- a/contracts/templates/contracts/view_contract.html
+++ b/contracts/templates/contracts/view_contract.html
@@ -143,7 +143,8 @@
                         <address class="mb-3">
                             <div class="mb-1">
                                 <a
-                                    class="inline-block p-1.5 mb-1 rounded-sm whitespace-nowrap cursor-pointer not-italic hover:no-underline bg-gray-200 duration-100 hover:bg-gray-300"
+                                    class="inline-block p-1.5 mb-1 rounded-sm whitespace-nowrap cursor-pointer not-italic hover:no-underline {% if not signature.contractee.color %}bg-gray-200 duration-100 hover:bg-gray-300{% endif %}{% if signature.contractee.color and not signature.contractee.color_is_light %} text-white{% endif %}"
+                                    {% if signature.contractee.color %}style="background-color:{{ signature.contractee.color }}"{% endif %}
                                 >
                                     <strong>{{ signature.contractee.name }}</strong>
                                     {% if signature.contractee.department %}
@@ -192,7 +193,8 @@
                         <address class="mb-3">
                             <div class="mb-1">
                                 <a
-                                    class="inline-block p-1.5 mb-1 rounded-sm whitespace-nowrap cursor-pointer not-italic hover:no-underline bg-gray-200 duration-100 hover:bg-gray-300"
+                                    class="inline-block p-1.5 mb-1 rounded-sm whitespace-nowrap cursor-pointer not-italic hover:no-underline {% if not signature.signee.color %}bg-gray-200 duration-100 hover:bg-gray-300{% endif %}{% if signature.signee.color and not signature.signee.color_is_light %} text-white{% endif %}"
+                                    {% if signature.signee.color %}style="background-color:{{ signature.signee.color }}"{% endif %}
                                 >
                                     <strong>{{ signature.signee.name }}</strong>
                                     {% if signature.signee.department %}
@@ -201,7 +203,7 @@
                                 </a>
                             </div>
                             
-                            {% if signee.is_legal_entity %}
+                            {% if signature.signee.is_legal_entity %}
                                 {{ signature.signee.address_street_with_number }}<br>
                                 {{ signature.signee.address_zip }} {{ signature.signee.address_district }}<br>
                                 {{ signature.signee.get_address_country_display }}<br>
@@ -213,7 +215,7 @@
                                 IČO: {{ signature.signee.ico_number }}<br>
                             {% endif %}
                             
-                            {% if not signee.is_legal_entity %}
+                            {% if not signature.signee.is_legal_entity %}
                                 <span class="block mt-2">
                                     <small class="font-thin">(Fyzická osoba, ukazujeme pouze obec.)</small><br>
                                 </span>
diff --git a/contracts/views.py b/contracts/views.py
index d9f31264e8b557cbaf9966ea56bfdc1c5a86d963..79b58145a3f61db1296289e99ed88291fc4f6606 100644
--- a/contracts/views.py
+++ b/contracts/views.py
@@ -9,7 +9,7 @@ from .models import Contract
 
 def index(request):
     contracts = Contract.objects.filter(
-        is_approved__is=True,
+        is_approved=True,
         public_state=Contract.PublicStates.YES,  
     ).order_by("valid_start_date").all()
     paginator = Paginator(contracts, 25)
@@ -36,7 +36,7 @@ def index(request):
 
 def view_contract(request, id: int):
     contract = Contract.objects.filter(
-        is_approved__is=True,
+        is_approved=True,
         public_state=Contract.PublicStates.YES,
     ).get(id=id)