diff --git a/src/servala/frontend/forms/renderers.py b/src/servala/frontend/forms/renderers.py
index b6a9995..eb50961 100644
--- a/src/servala/frontend/forms/renderers.py
+++ b/src/servala/frontend/forms/renderers.py
@@ -20,6 +20,8 @@ class VerticalFormRenderer(TemplatesSetting):
def get_class_names(self, field):
input_type = self.get_field_input_type(field)
errors = "is-invalid " if field.errors else ""
+ if input_type == "radio":
+ return f"{errors}form-check-input"
if input_type == "checkbox":
return f"{errors}form-check-input"
return f"{errors}form-control"
diff --git a/src/servala/frontend/templates/django/forms/widgets/input_option.html b/src/servala/frontend/templates/django/forms/widgets/input_option.html
new file mode 100644
index 0000000..9a7654d
--- /dev/null
+++ b/src/servala/frontend/templates/django/forms/widgets/input_option.html
@@ -0,0 +1,6 @@
+{% include "django/forms/widgets/input.html" %}
+{% if widget.wrap_label %}
+
+{% endif %}
diff --git a/src/servala/frontend/templates/django/forms/widgets/radio.html b/src/servala/frontend/templates/django/forms/widgets/radio.html
new file mode 100644
index 0000000..1f363b9
--- /dev/null
+++ b/src/servala/frontend/templates/django/forms/widgets/radio.html
@@ -0,0 +1,15 @@
+{# Change compared to Django: only render widget.attrs.class in actual option widget, not in wrapper #}
+{% with id=widget.attrs.id %}
+
+ {% for group, options, index in widget.optgroups %}
+ {% if group %}
+
+
+ {% endif %}
+ {% for option in options %}
+
{% include option.template_name with widget=option %}
+ {% endfor %}
+ {% if group %}
{% endif %}
+ {% endfor %}
+
+{% endwith %}
diff --git a/src/servala/settings.py b/src/servala/settings.py
index a8b3fbc..bb69ebb 100644
--- a/src/servala/settings.py
+++ b/src/servala/settings.py
@@ -145,11 +145,11 @@ INSTALLED_APPS = [
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
+ # The frontend app is loaded early in order to supersede some allauth views/behaviour
+ "servala.frontend",
"django.forms",
"template_partials",
"rules.apps.AutodiscoverRulesConfig",
- # The frontend app is loaded early in order to supersede some allauth views/behaviour
- "servala.frontend",
"allauth",
"allauth.account",
"allauth.socialaccount",
diff --git a/src/servala/static/css/servala.css b/src/servala/static/css/servala.css
index 1e418fb..b7a5b8b 100644
--- a/src/servala/static/css/servala.css
+++ b/src/servala/static/css/servala.css
@@ -54,6 +54,12 @@ html[data-bs-theme="dark"] .btn-outline-primary, .btn-outline-primary {
margin-bottom: 0;
}
+fieldset .form-check-input + label {
+ font-weight: normal;
+ min-height: 1.5rem;
+ margin: .125rem;
+}
+
.search-form .form-body>.row {
display: flex;
&>.col-12 {