diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 8aa19612a71d77e35ed4610232250121e7e065e5..66967fe518d6495007a1968950f11fb17d3c706a 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -9,16 +9,11 @@ and this project adheres to `Semantic Versioning`_.
 Unreleased
 ----------
 
+`4.0`_ - 2025-03-29
+-------------------
+
 Notable, breaking changes
 ~~~~~~~~~~~~~~~~~~~~~~~~~
-The "managed models" feature is mandatory for all models derived from `ExtensibleModel`
-and requires creating a migration for all downstream models to add the respective
-field.
-
-The "additional fields" feature has been removed because it had design issues
-that practically made it unusable in all scenarios. No migration path away
-from the feature is defined. If you have been using additional group fields
-and need a replacement, please contact the development team.
 
 The special assignment page for groups and child groups has been removed.
 
@@ -29,111 +24,125 @@ for PostgreSQL.
 AlekSIS now uses Valkey as a drop-in replacement for Redis. Please update your configuration
 files accordingly (see docs for further instructions).
 
+To make setting names consistent, the setting ``auth.login.registration.unique_email``
+was renamed to ``auth.registration.unique_email``.
+
+The "additional fields" feature has been removed because it had design issues
+that practically made it unusable in all scenarios. No migration path away
+from the feature is defined. If you have been using additional group fields
+and need a replacement, please contact the development team.
+
+The "managed models" feature is mandatory for all models derived from `ExtensibleModel`
+and requires creating a migration for all downstream models to add the respective field.
+
 As legacy pages are no longer themed, you should update them to the new frontend as soon as possible.
 
-To make setting names consistent, the setting `auth.login.registration.unique_email`
-was renamed to `auth.registration.unique_email`.
+To prevent collisions with fields, the class variable ``name`` on ``RegistryObject`` has been renamed
+to ``_class_name``. Please update any references and subclasses.
 
-To prevent collisions with fields, the class variable `name` on `RegistryObject` has been renamed
-to `_class_name`. Please update any references and subclasses.
+Deprecated
+~~~~~~~~~~
 
-To prevent collisions with fields, the class variables `verbose_name`, `link`, `color`,
-`description` and `permission_required` on `DAVResource` have been prefixed with `dav_`.
-Please update any references and subclasses.
+* The field ``owners`` of group will be removed in the next release and will be replaced by memberships
+  using the special ownership role.
 
 Added
 ~~~~~
 
 * Global calendar system
-* Calendar for birthdays of persons
-* Holiday model to track information about holidays.
+
+  * CalDAV and CardDAV for syncing calendars and Persons read-only.
+  * Calendar for birthdays of persons
+  * Management of personal calendar events.
+  * Holiday model to track information about holidays.
+
 * Following management views were added:
+
   * Rooms
   * Holiday
-* [Dev] Components for implementing standard CRUD operations in new frontend.
-* [Dev] Options for filtering and sorting of GraphQL queries at the server.
-* [Dev] Managed models for instances handled by other apps.
-* [Dev] Upload slot sytem for out-of-band uploads in GraphQL clients
-* Generic endpoint for retrieving objects as JSON
-* [Dev] Base model for organisational entities (external companies, associations,…)
-* Management of personal calendar events.
-* [Dev] Support running of data checks before/after migrations.
-* Views can request to span the entire screen width.
-* Add option to disallow reserved usernames.
+
+* Global school term select for limiting data to a specific school term.
 * Error message when loading in incompatible browser
 * Tooltips for every information in the person page
 * New menu item "Data management" with Rooms, Announcements, Holidays, and School Terms
 * Priority to sort announcements
+* Generic Roles for describing relationships. Currently used for Person-to-Group relationships.
+* Mascot images in multiple places throughout the application.
+* Generic endpoint for retrieving objects as JSON
+* Add option to disallow reserved usernames.
 * Allow matching social accounts to local accounts by their username.
 * Support RP-initiated logout for OIDC applications
-* Mascot images in multiple places throughout the application.
 * Support native PostgreSQL connection pooling
 * Support profiling with Sentry in addition to tracing
-* Make configurable which weekdays appear in the calendar
 * Introduce .well-known urlpatterns for apps
-* Global school term select for limiting data to a specific school term.
+* [Dev] Views can request to span the entire screen width.
+* [Dev] Base model for organisational entities (external companies, associations,…)
+* [Dev] Support running of data checks before/after migrations.
 * [Dev] Notifications based on calendar alarms.
-* CalDAV and CardDAV for syncing calendars and Persons read-only.
-* Generic Roles for describing relationships. Currently used for Person-to-Group relationships.
+* [Dev] Components for implementing standard CRUD operations in new frontend.
+* [Dev] Options for filtering and sorting of GraphQL queries at the server.
+* [Dev] Managed models for instances handled by other apps.
+* [Dev] Upload slot sytem for out-of-band uploads in GraphQL clients
 
 Changed
 ~~~~~~~
 
 * Following management views were migrated to new frontend:
+
   * School Terms
   * Announcements
   * OAuth Applications
   * Persons
-* [Dev] Child groups are exposed in the GraphQL type for groups.
+  
 * Content width on different screen sizes is more consistent.
 * Room model icon changed from the default to a specific one.
 * Show only short name, if available, in announcement recipients
-* [Dev] Use Django 5.
 * Move "Invite person" to persons page
-* Replace all mentions of Redis with Valkey where possible
 * Show avatars of groups in all places.
 * Use new auth rate limiting settings
-* Setting `auth.login.registration.unique_email` was renamed to `auth.registration.unique_email`
-* Bump Python version to 3.10
 * Factor out addresses in their own model and allow multiple addresses with different types
   (e. g. home, business) for one person
+* Setting ``auth.login.registration.unique_email`` was renamed to ``auth.registration.unique_email``
 * Adapt permission scheme for announcements to other permissions.
 * Use Firefox instead of Chromium for PDF creation and support external webdriver via
   `selenium.url` option, e.g. for use in containers.
-* Rename `RegistryObject`'s class var `name` to `_class_name`.
-* Prefix `DAVResource`'s class vars with `dav_`.
+* Replace all mentions of Redis with Valkey where possible
+* [Dev] Rename `RegistryObject`'s class var `name` to `_class_name`.
+* [Dev] Use Django 5.
+* [Dev] Bump Python version to 3.10
+* [Dev] Child groups are exposed in the GraphQL type for groups.
 
 Fixed
 ~~~~~
 
+* Accessibility issues with new frontend.
+* Improve error handling in frontend and show meaningful error messages.
 * GraphQL mutations did not return errors in case of exceptions.
 * Make email field unique over all persons.
 * Opening group details wasn't possible without permissions for all person details.
-* [Dev] Foreign keys to ExtensiblePolymorphicModel types were using the wrong manager.
-* [Dev] Allow activating more frequent polling for Celery task progress.
-* [Docs] An example config contained invalid values.
 * Correctly redirect to AlekSIS frontend after login with a third-party account.
 * Our own account adapter wasn't used so signup settings weren't applied correctly.
-* Improve error handling in frontend and show meaningful error messages.
-* [Dev] Integrate model validation mechanisms into GraphQL queries.
-* [Container] Database backup failed with postgres versions 15 and 16.
 * Setting images for groups did not work
 * Update and fix URLs for 3rdparty login.
 * The OpenID Connect Discovery endpoint now returns the issuer data directly
   under the URI without a trailing `/`.
 * Not-logged in users were able to access all PDF files (CVE-2025-25683).
-* Accessibility issues with new frontend.
+* [Docs] An example config contained invalid values.
+* [Container] Database backup failed with postgres versions 15 and 16.
+* [Dev] Foreign keys to ExtensiblePolymorphicModel types were using the wrong manager.
+* [Dev] Allow activating more frequent polling for Celery task progress.
+* [Dev] Integrate model validation mechanisms into GraphQL queries.
 
 Removed
 ~~~~~~~
 
 * Yubikey support (not WebAuthn) was removed
+* Additional fields.
+* Legacy pages are no longer themed.
+* [Dev] Batching of GraphQL queries.
 * [Dev] `_recursive` methods for groups have been removed.
   Developers relying on parent groups need to account for recursion themselves.
 * [Dev] Extended fields mechanism on top of django-jsonstore.
-* Additional fields.
-* Legacy pages are no longer themed.
-* Batching of GraphQL queries.
 
 `3.2.2`_ - 2025-01-18
 ---------------------
@@ -1443,3 +1452,4 @@ Fixed
 .. _3.2.0: https://edugit.org/AlekSIS/official/AlekSIS-Core/-/tags/3.2.0
 .. _3.2.1: https://edugit.org/AlekSIS/official/AlekSIS-Core/-/tags/3.2.1
 .. _3.2.2: https://edugit.org/AlekSIS/official/AlekSIS-Core/-/tags/3.2.2
+.. _4.0: https://edugit.org/AlekSIS/official/AlekSIS-Core/-/tags/4.0
diff --git a/README.rst b/README.rst
index cf6e5bb1bd9da7a3892ed873d01d592a9cd0925e..fcc8c37bae84df74f48b13712a2e0ba403dc976b 100644
--- a/README.rst
+++ b/README.rst
@@ -17,15 +17,19 @@ The AlekSIS core currently provides the following features:
 * For users:
 
  * Authentication via local account, LDAP, or social accounts
- * Two factor authentication via Yubikey, OTP or SMS
+ * Two factor authentication via WebAuthn, OTP, or SMS
  * Configurable dashboard with widgets
  * User-specific preferences
  * Global search
- * Manage announcements
- * Manage groups and types of groups
- * Manage roles and additional, informative fields per group
+ * Global calendar system
+ * CalDAV and CardDAV support
+ * Manage personal events
  * Manage persons
- * Notifications via SMS, email or dashboard
+ * Manage groups and group types
+ * Manage roles per group
+ * Manage announcements
+ * Manage holidays
+ * Notifications via SMS, email, or dashboard
  * PWA with offline caching
  * User registration, password changes and password reset
  * User invitations with invite codes and targeted invites
@@ -45,15 +49,15 @@ The AlekSIS core currently provides the following features:
 
 * For developers
 
- * Generic PDF generation with chromium
+ * Generic PDF generation with firefox
  * Caching with Valkey
  * Django REST framework for apps to use at own discretion
- * Injection of fields, methods, permissions and properties via custom `ExtensibleModel`
+ * Injection of fields, methods, permissions and properties via custom ``ExtensibleModel``
  * K8s compatible, read-only Docker image
- * Object-level permissions and rules with `django-guardian` and `django-rules`
- * Query caching with `django-cachalot`
- * uWSGI and Celery via `django-uwsgi` in development
+ * Object-level permissions and rules with ``django-guardian`` and ``django-rules``
+ * uWSGI and Celery via ``django-uwsgi`` in development
  * Extensible dashbaord widget system
+ * Extensible calendar system
  * Extensible OAuth/OpenID Connect scope and claims system
 
 Licence
diff --git a/aleksis/core/frontend/messages/de.json b/aleksis/core/frontend/messages/de.json
index 5d753c7ee8ce6f83b46c6a621aa48967d404bcb5..2345cc14820bc10978c95e38fb36ab1ed5b0522b 100644
--- a/aleksis/core/frontend/messages/de.json
+++ b/aleksis/core/frontend/messages/de.json
@@ -75,8 +75,10 @@
     "incompatible_selection_message": "Aktion wurde für eine inkompatible Auswahl aufgerufen."
   },
   "actions": {
+    "account_menu": "Kontomenü öffnen",
     "back": "Zurück",
     "cancel": "Abbrechen",
+    "clear": "Feld leeren",
     "clear_filters": "Filter zurücksetzen",
     "close": "Schließen",
     "confirm": "Bestätigen",
@@ -89,13 +91,21 @@
     "delete": "Löschen",
     "edit": "Bearbeiten",
     "filter": "Filter",
+    "list_notifications": "Liste der Benachrichtigungen öffnen",
+    "more_actions": "Mehr Aktionen",
     "next": "Weiter",
+    "open_details": "Details ansehen",
+    "open_in_new": "In neuem Tab öffnen",
     "save": "Speichern",
+    "scroll_next": "Zu nächsten scrollen",
+    "scroll_prev": "Zu vorherigem scrollen",
     "search": "Suchen",
     "select_action": "Aktion auswählen",
     "select_all": "Alle auswählen",
+    "select_school_term": "Auswahl für aktives Schuljahr öffnen",
     "stop_editing": "Bearbeiten beenden",
     "title": "Aktionen",
+    "toggle_sidenav": "Anzeige der Seitennavigation umschalten",
     "type_to_search": "Tippen Sie, um zu suchen",
     "update": "Aktualisieren"
   },
diff --git a/aleksis/core/frontend/messages/la.json b/aleksis/core/frontend/messages/la.json
index 80e7fdf250fe1568b4297134ef1270f6a1636ba7..990d94c6595ecfea88869dfc8ecb20ce8d48420d 100644
--- a/aleksis/core/frontend/messages/la.json
+++ b/aleksis/core/frontend/messages/la.json
@@ -52,6 +52,7 @@
       "name": "Nomen"
     }
   },
+  "people": "Personae",
   "person": {
     "birth_date": "Dies natalis",
     "date_of_birth": "Dies natalis",
diff --git a/docs/admin/10_install.rst b/docs/admin/10_install.rst
index 813cafd653c860c2dfba0165f62bf9a70fe5dd83..b7b6a8f96bcddc3aafb3c89b1a3d779cc9f4246f 100644
--- a/docs/admin/10_install.rst
+++ b/docs/admin/10_install.rst
@@ -5,7 +5,7 @@ From PyPI
 ---------
 
 In this section we will install AlekSIS with `uWSGI` and `nGINX` on Debian
-bullseye.
+bookworm.
 
 Filesystem locations
 ~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/conf.py b/docs/conf.py
index e773e2f8b24eb3cfe3a039650cf5bd66cea38525..f7e0eb6c855fc3470740edfe5ba54b1b41bf76d8 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -25,13 +25,13 @@ django.setup()
 # -- Project information -----------------------------------------------------
 
 project = "AlekSIS-Core"
-copyright = "2019-2023 The AlekSIS team"
+copyright = "2019-2025 The AlekSIS team"
 author = "The AlekSIS Team"
 
 # The short X.Y version
-version = "4.0"
+version = "4.1"
 # The full version, including alpha/beta/rc tags
-release = "4.0.0.dev4"
+release = "4.1.0.dev0"
 
 
 # -- General configuration ---------------------------------------------------
diff --git a/pyproject.toml b/pyproject.toml
index 3b7bcb3a1dbbb7332d75557fc88e51c90fcea95f..b5608714da0c59f5ceadf334d6a2c3bb640ad86c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "AlekSIS-Core"
-version = "4.0.0.dev16"
+version = "4.1.0.dev0"
 packages = [
     { include = "aleksis" }
 ]