diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 12aff3116953b4ddd4a3b6bb2419268c49a89c99..97c64b4ee55736f3d972404a1d75d30136b9baf8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -69,15 +69,13 @@ default:
     name: gcr.io/kaniko-project/executor:debug
     entrypoint: [""]
   variables:
-    KANIKO_CACHE_ARGS:
-      --cache=true
+    KANIKO_CACHE_ARGS: --cache=true
       --cache-copy-layers=true
       --cache-run-layers=true
       --cache-ttl=24h
       --cache-dir=$CI_PROJECT_DIR/.cache/kaniko
       --cache-repo=$CI_REGISTRY_IMAGE/cache
-    KANIKO_ARGS:
-      --skip-unused-stages=true
+    KANIKO_ARGS: --skip-unused-stages=true
       --context $CI_PROJECT_DIR
       --build-arg REGISTRY=git.cccv.de/crews/hub/dependency_proxy/containers/
   before_script:
@@ -106,7 +104,6 @@ default:
       }
       EOF
 
-
 generate_css:
   extends:
     - .default-rules
@@ -130,11 +127,11 @@ meta_build:
     PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
   script:
     - /kaniko/executor
-        $KANIKO_ARGS
-        $KANIKO_CACHE_ARGS
-        --dockerfile $CI_PROJECT_DIR/Dockerfile
-        --target base
-        --destination $CI_REGISTRY_IMAGE/build_image:$CI_PIPELINE_ID
+      $KANIKO_ARGS
+      $KANIKO_CACHE_ARGS
+      --dockerfile $CI_PROJECT_DIR/Dockerfile
+      --target base
+      --destination $CI_REGISTRY_IMAGE/build_image:$CI_PIPELINE_ID
   rules:
     - when: always
 
@@ -219,10 +216,10 @@ requirements_export:
     - git diff --exit-code -- . ':!src/version.json'
   rules:
     - changes:
-      - requirements.txt
-      - requirements.dev.txt
-      - project.toml
-      - pdm.lock
+        - requirements.txt
+        - requirements.dev.txt
+        - project.toml
+        - pdm.lock
 
 django-tests:
   stage: test
@@ -258,11 +255,11 @@ build_nginx:
     - django-tests
   script:
     - /kaniko/executor
-        $KANIKO_ARGS
-        $KANIKO_CACHE_ARGS
-        --dockerfile $CI_PROJECT_DIR/Dockerfile
-        --target nginx
-        --destination $CI_REGISTRY_IMAGE/ci/nginx:ci-$CI_PIPELINE_ID
+      $KANIKO_ARGS
+      $KANIKO_CACHE_ARGS
+      --dockerfile $CI_PROJECT_DIR/Dockerfile
+      --target nginx
+      --destination $CI_REGISTRY_IMAGE/ci/nginx:ci-$CI_PIPELINE_ID
 
 build_release:
   stage: build
@@ -274,11 +271,11 @@ build_release:
     - django-tests
   script:
     - /kaniko/executor
-        $KANIKO_ARGS
-        $KANIKO_CACHE_ARGS
-        --dockerfile $CI_PROJECT_DIR/Dockerfile
-        --target webworker
-        --destination $CI_REGISTRY_IMAGE/ci/hub:ci-$CI_PIPELINE_ID
+      $KANIKO_ARGS
+      $KANIKO_CACHE_ARGS
+      --dockerfile $CI_PROJECT_DIR/Dockerfile
+      --target webworker
+      --destination $CI_REGISTRY_IMAGE/ci/hub:ci-$CI_PIPELINE_ID
 
 build_test:
   stage: build
@@ -294,10 +291,10 @@ build_test:
         EXPOSE 8000
       EOF
     - /kaniko/executor
-        --destination $CI_REGISTRY_IMAGE/ci/hub:ci-$CI_PIPELINE_ID-test
-        $KANIKO_ARGS
-        $KANIKO_CACHE_ARGS
-        --dockerfile Dockerfile_Test
+      --destination $CI_REGISTRY_IMAGE/ci/hub:ci-$CI_PIPELINE_ID-test
+      $KANIKO_ARGS
+      $KANIKO_CACHE_ARGS
+      --dockerfile Dockerfile_Test
 
 .test_image:
   extends:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index a9b46b7bbac0d0bc840c766ad5b8a98193393eeb..32301353773e8869120d20744e42843c2fae0ee5 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,48 +1,48 @@
 exclude: ^.*.min.*|migrations|yarn.lock|venv$
 
 repos:
-    - repo: https://github.com/pre-commit/pre-commit-hooks
-      rev: v2.3.0
-      hooks:
-          - id: check-yaml
-          - id: check-toml
-          - id: check-merge-conflict
-          - id: check-ast
-    - repo: https://github.com/astral-sh/ruff-pre-commit
-      rev: v0.1.5
-      hooks:
-          - id: ruff
-            args: [ --fix ]
-          - id: ruff-format
-    - repo: https://gitlab.com/bmares/check-json5
-      rev: v1.0.0
-      hooks:
-          - id: check-json5
-    - repo: https://github.com/pdm-project/pdm
-      rev: 2.19.2
-      hooks:
-          - name: check production requirements
-            id: pdm-export
-            args: ['-o', 'requirements.txt', '--without-hashes', '--prod']
-            files: ^pdm.lock$
-    - repo: https://github.com/pdm-project/pdm
-      rev: 2.19.2
-      hooks:
-          - name: check development requirements
-            id: pdm-export
-            args: ['-o', 'requirements.dev.txt', '--without-hashes', '--dev']
-            files: ^pdm.lock$
-    - repo: https://github.com/pdm-project/pdm
-      rev: 2.19.2
-      hooks:
-           - id: pdm-lock-check
-    - repo: local
-      hooks:
-          - name: Check for uncreated migrations.
-            id: migrations-check
-            language: system
-            entry: sh -c "src/manage.py makemigrations --check --dry-run"
-            files: "models/.*.py$"
-            types:
-              - python
-            stages: [pre-commit]
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v2.3.0
+    hooks:
+      - id: check-yaml
+      - id: check-toml
+      - id: check-merge-conflict
+      - id: check-ast
+  - repo: https://github.com/astral-sh/ruff-pre-commit
+    rev: v0.1.5
+    hooks:
+      - id: ruff
+        args: [--fix]
+      - id: ruff-format
+  - repo: https://gitlab.com/bmares/check-json5
+    rev: v1.0.0
+    hooks:
+      - id: check-json5
+  - repo: https://github.com/pdm-project/pdm
+    rev: 2.19.2
+    hooks:
+      - name: check production requirements
+        id: pdm-export
+        args: ["-o", "requirements.txt", "--without-hashes", "--prod"]
+        files: ^pdm.lock$
+  - repo: https://github.com/pdm-project/pdm
+    rev: 2.19.2
+    hooks:
+      - name: check development requirements
+        id: pdm-export
+        args: ["-o", "requirements.dev.txt", "--without-hashes", "--dev"]
+        files: ^pdm.lock$
+  - repo: https://github.com/pdm-project/pdm
+    rev: 2.19.2
+    hooks:
+      - id: pdm-lock-check
+  - repo: local
+    hooks:
+      - name: Check for uncreated migrations.
+        id: migrations-check
+        language: system
+        entry: sh -c "src/manage.py makemigrations --check --dry-run"
+        files: "models/.*.py$"
+        types:
+          - python
+        stages: [pre-commit]
diff --git a/Development.md b/Development.md
index 10a17bb485de96973096911cfb92baa2d53cf216..168ed9d2b2212d0680052852b01674a6e0cb38e2 100644
--- a/Development.md
+++ b/Development.md
@@ -12,14 +12,14 @@ Das Docker development image vereinfacht die initiale Einrichtung und sperrt all
    Unter Windows getestet mit WSL 2.
 2. Klonen dieses Repositories an beliebigen Ort.
 3. Image erzeugen: `docker compose build`
-    - Für schnellere Builds kann [buildkit](https://docs.docker.com/build/buildkit/) verwendet werden:
-        ```bash
-        export DOCKER_BUILDKIT=1
-        ```
-    - Die Standardpasswöter für PostgreSQL und Hub Benutzer sind in der `docker-compose.yml` Datei festgelegt und können per Umgebungsvariable angepasst werden.
+   - Für schnellere Builds kann [buildkit](https://docs.docker.com/build/buildkit/) verwendet werden:
+     ```bash
+     export DOCKER_BUILDKIT=1
+     ```
+   - Die Standardpasswöter für PostgreSQL und Hub Benutzer sind in der `docker-compose.yml` Datei festgelegt und können per Umgebungsvariable angepasst werden.
 4. Container erzeugen: `docker compose up -d hub`
-    - Beim Start mittels `docker compose` wird kein HUB Admin Benutzer angelegt um ein ungewolltes anlegen von diesen Benutzern in der Produktivumgebung vorzubeugen.
-      Falls der `admin` Benutzer angelegt werden soll muss die Umgebungsvariable `DJANGO_CREATE_ADMIN_PASSWORD` für den Container gesetzt werden.
+   - Beim Start mittels `docker compose` wird kein HUB Admin Benutzer angelegt um ein ungewolltes anlegen von diesen Benutzern in der Produktivumgebung vorzubeugen.
+     Falls der `admin` Benutzer angelegt werden soll muss die Umgebungsvariable `DJANGO_CREATE_ADMIN_PASSWORD` für den Container gesetzt werden.
 5. Optional: Import von Demo-Daten: `docker compose exec -it hub python manage.py loaddata ./core/fixtures/anhalter.json`
 
 #### Debug Zugriff
@@ -36,9 +36,9 @@ Diese kann duch das anlegen einer localen compose Datei mit dem folgenden Inhalt
 version: "3.8"
 
 services:
-    hub:
-        env_file:
-            - dev.env
+  hub:
+    env_file:
+      - dev.env
 ```
 
 Diese kann durch das setzen der Umgebungsvariable `COMPOSE_FILE=docker-compose.yml:docker-compose.local.yml` automatisch beim allen `docker compose` Kommandos berücksichtigt werden.
@@ -47,18 +47,18 @@ Um eine andere Demo Datei zu laden kann die Umgebungsvariable `DJANGO_LOAD_FIXTU
 ### Lokale Einrichtung
 
 1. Installiere, falls noch nicht geschehen, Python in Version 3.13 (oder höher) und habe eine PostgreSQL-Datenbank zur Hand (z.B. aus dem docker mit exposed port). Außerdem wird unter Umständen [GNU gettext](https://www.gnu.org/software/gettext/) benötigt, wenn man Übersetzungen kompilieren will. Alternativ kann auch das [docker dev image](#docker-dev-image) verwendet werden.
-    - Linux: Pakete `python3`, `postgresql` und `gettext`
-    - Mac: `brew install python3 postgresql gettext` bzw. https://postgresapp.com/
-    - Windows: [latest stable Python 3 release](https://www.python.org/downloads/windows/) und [PostgreSQL Installer](https://www.postgresql.org/download/windows/) und [gettext binaries](https://mlocati.github.io/articles/gettext-iconv-windows.html)
-    - Python Paketmanager: `pdm`:
-      Kann mit OS Installationsmitteln oder mit `pip install pdm` installiert werden.
+   - Linux: Pakete `python3`, `postgresql` und `gettext`
+   - Mac: `brew install python3 postgresql gettext` bzw. https://postgresapp.com/
+   - Windows: [latest stable Python 3 release](https://www.python.org/downloads/windows/) und [PostgreSQL Installer](https://www.postgresql.org/download/windows/) und [gettext binaries](https://mlocati.github.io/articles/gettext-iconv-windows.html)
+   - Python Paketmanager: `pdm`:
+     Kann mit OS Installationsmitteln oder mit `pip install pdm` installiert werden.
 1. Klone dieses Repository an beliebigen Ort.
 1. Erstelle die virtuelle Umgebung mit `pdm info`
 1. Installiere die python dependencies mit `pdm install`
-6. (falls nicht bereits vorhanden) lege einen PostgreSQL-User an (`createuser -P hub_app`) sowie eine Datenbank (`createdb -O hub_app hub`) - unter Linux ggf. via `sudo -u postgres`
+1. (falls nicht bereits vorhanden) lege einen PostgreSQL-User an (`createuser -P hub_app`) sowie eine Datenbank (`createdb -O hub_app hub`) - unter Linux ggf. via `sudo -u postgres`
 1. Konfiguriere deine Instanz mittels:
-    - Umgebungsvariablen (z.B. direnv, oder env Datei)
-    - oder mittels einer `local_settings.py` in `src/hub/` an (Dokumentation zur Datenbankkonfiguration in der [Django-Dokumentation](https://docs.djangoproject.com/en/3.1/ref/settings/#databases)):
+   - Umgebungsvariablen (z.B. direnv, oder env Datei)
+   - oder mittels einer `local_settings.py` in `src/hub/` an (Dokumentation zur Datenbankkonfiguration in der [Django-Dokumentation](https://docs.djangoproject.com/en/3.1/ref/settings/#databases)):
 
 ```python
 DEBUG = True
@@ -121,7 +121,7 @@ Mittels diesem werden die `requirements.txt` und die `requirements.dev.txt` erze
 
 Um die aktuellen python Abhängigkeiten zu installieren kann das Kommando `pdm install` verwendet werden.
 Mit dem Kommando `pdm sync --clean` kann sichergestellt werden, dass genau die Versionen aus dem pdm lock file installiert werden.  
-*Achtung*: **Nicht in der Lock Datei enthaltene python Pakete werden deinstalliert!**
+_Achtung_: **Nicht in der Lock Datei enthaltene python Pakete werden deinstalliert!**
 
 #### Hinzufügen von neuen Abhängigkeiten
 
@@ -130,6 +130,7 @@ Um neue Abhängigkeiten hinzuzufügen kann das Kommando `pdm add` verwendet werd
 Anschließend müssen die `requirements.txt` und `requirements.dev.txt` angepasst werden.
 Wenn `pre-commit` verwendet wird, passiert dies automatisch beim commit.  
 Alternativ können die folgenden Kommandos verwendet werden
+
 ```bash
 pdm export --no-hashes -o requirements.txt --prod
 pdm export --no-hashes -o requirements.dev.txt --dev
@@ -154,27 +155,26 @@ oder:
 
 ### Übersetzungen extrahieren & compilieren
 
--   `pdm manage makemessages`
--   Die Übersetzungsdateien in `<app>/locale/<sprache>/LC_MESSAGES/django.po` wurden um alle neuen Übersetzungsstrings erweitert. Bearbeiten und jeweils bei `msgstr` die Übersetzungen einfügen!
--   `pdm manage compilemessages`
--   Zum Ausprobieren müsst ihr django neu starten um die neuen Übersetzungsdateien zu laden
+- `pdm manage makemessages`
+- Die Übersetzungsdateien in `<app>/locale/<sprache>/LC_MESSAGES/django.po` wurden um alle neuen Übersetzungsstrings erweitert. Bearbeiten und jeweils bei `msgstr` die Übersetzungen einfügen!
+- `pdm manage compilemessages`
+- Zum Ausprobieren müsst ihr django neu starten um die neuen Übersetzungsdateien zu laden
 
 ### Übersetzungen definineren
 
--   in Python: `gettext` wie üblich in Django, siehe [Doku](https://docs.djangoproject.com/en/3.1/topics/i18n/translation/#internationalization-in-python-code)
--   in jinja2-Templates via `_`, bspw. `{{ _("Settings") }}` oder mit Platzhalter `{{ _("Hello, %(username)s", username=user.display_name) }}`
+- in Python: `gettext` wie üblich in Django, siehe [Doku](https://docs.djangoproject.com/en/3.1/topics/i18n/translation/#internationalization-in-python-code)
+- in jinja2-Templates via `_`, bspw. `{{ _("Settings") }}` oder mit Platzhalter `{{ _("Hello, %(username)s", username=user.display_name) }}`
 
 ### Static Files einsammeln lassen
 
--   `pdm manage collectstatic`
--   ohne dies brechen u.a. Unittests mit Fehlern wie "Missing staticfiles manifest entry" ab
+- `pdm manage collectstatic`
+- ohne dies brechen u.a. Unittests mit Fehlern wie "Missing staticfiles manifest entry" ab
 
 ### Tests
 
 Es gibt Django (Unit-)Tests für die einzelnen Apps. Diese finden sich jeweils im `tests` Ordner der App.
 Außerdem gibt es im repository root unter [tests](tests) auch noch einfache Integrationstests.
 
-
 #### Test mit Übersetzten Inhalten
 
 Um sicherzustellen, dass Tests mit Übersetzungen in allen Umgebungen funktionieren,
@@ -182,6 +182,7 @@ müssen die Übersetzungsfunktionen gemocked werden.
 Dazu gibt es in `core.tests.utils` eine `mocktrans` Funktion die alle Text einfach mich `_trans` ergänzt (z.B. wird aus "Login" dann "Login_trans").
 
 Die Funktion kann dann wie folgt verwendet werden:
+
 ```python
 with patch('core.models.ticket._', side_effect=mocktrans):
     translation = funktions_aufruf()
@@ -218,8 +219,8 @@ Ab dann wird vor jedem commit ein Teil der checks (vor allem Format Tests) durch
 Um das Format und die Korrektheit der python Dateien im Hub sicherzustellen setzen wir das tool `ruff` ein.
 Dieses hat die folgenden Kommandos:
 
--   `ruff check`: Diess Kommando checkt auf häufige Fehler in python code und hat auch teilweise Möglichkeiten diese zu beheben
--   `ruff format`: Dieses Kommando re-formatiert alle python dateien nach einem voregebenen Code-Style
+- `ruff check`: Diess Kommando checkt auf häufige Fehler in python code und hat auch teilweise Möglichkeiten diese zu beheben
+- `ruff format`: Dieses Kommando re-formatiert alle python dateien nach einem voregebenen Code-Style
 
 ### djLink
 
@@ -227,7 +228,8 @@ Dieses hat die folgenden Kommandos:
 **Wenn eine Integration in einen Editor gewünscht ist, muss dies berücksichtigt werden!**
 
 Manuell kann es folgendermaßen ausgeführt werden:
-- `djlint --profile django --extension html --reformat .` um alle .html Dateien zu formatieren 
+
+- `djlint --profile django --extension html --reformat .` um alle .html Dateien zu formatieren
 - `djlint --profile jinja --extension j2 --reformat .` um alle .j2 Dateien zu formatieren
 - `djlint --lint .` um alle ein potenzielle Fehler per Linting zu finden
 
diff --git a/README.md b/README.md
index f41b0ab1aef83b9fc8499474304f35750ccb9151..2aef8db2d832d38824dce39b1aea70f4ec86e5fb 100644
--- a/README.md
+++ b/README.md
@@ -2,12 +2,12 @@
 
 Der Hub besteht aus mehreren Komponenten welche für unterschiedliche Funktionen gedacht sind
 
--   Backoffice: Erfassung und Verwaltung von Informationen inkl. Bearbeitung von Reports
--   PlainUI: Es handelt sich um eine Darstellung der Konferenz-Inhalte als simples Frontend ohne viel Schnick-Schnack.
-    -   Produktiv-Instanz: <https://events.ccc.de/congress/2024/hub/>
-    -   Test-Instanz: <https://plainui.staging.hub.c3events.de/>
--   Core: Beinhaltet die Datenmodelle und Funktionen, die sowohl im Backoffice als auch in der PlainUI verwendet werden.
--   Metanav/Navbar (not published yet): Bietet eine von allen Seiten gemeinsam einbindbare Navigationsleiste im jeweiligen Congress-Design.
+- Backoffice: Erfassung und Verwaltung von Informationen inkl. Bearbeitung von Reports
+- PlainUI: Es handelt sich um eine Darstellung der Konferenz-Inhalte als simples Frontend ohne viel Schnick-Schnack.
+  - Produktiv-Instanz: <https://events.ccc.de/congress/2024/hub/>
+  - Test-Instanz: <https://plainui.staging.hub.c3events.de/>
+- Core: Beinhaltet die Datenmodelle und Funktionen, die sowohl im Backoffice als auch in der PlainUI verwendet werden.
+- Metanav/Navbar (not published yet): Bietet eine von allen Seiten gemeinsam einbindbare Navigationsleiste im jeweiligen Congress-Design.
 
 ## Datenmodell
 
@@ -17,17 +17,17 @@ als PDF: [Grobes Datenmodell](docs/Grobes Datenmodell.pdf) und [automatisch expo
 
 ### PlainUi Structure
 
--   jinja2/plainui
-    -   components
-    -   tbd.
--   styles
-    -   components: components styles, die in `hub.scss` eingebunden werden
-    -   utils: settings, die selbst keinen output generieren (z.B. Variablen, Mixins), damit sie in unterschiedlichen files verwendet werden können
-    -   `hub.scss`: Hauptdatei, welche anschließend in CSS konvertiert wird
--   static/plainui
-    -   img: statische Bilder
-    -   fonts: importierte Schriften
-    -   das generierte CSS
+- jinja2/plainui
+  - components
+  - tbd.
+- styles
+  - components: components styles, die in `hub.scss` eingebunden werden
+  - utils: settings, die selbst keinen output generieren (z.B. Variablen, Mixins), damit sie in unterschiedlichen files verwendet werden können
+  - `hub.scss`: Hauptdatei, welche anschließend in CSS konvertiert wird
+- static/plainui
+  - img: statische Bilder
+  - fonts: importierte Schriften
+  - das generierte CSS
 
 ## REST API
 
diff --git a/deployment/README.md b/deployment/README.md
index e8ef2cd85294487770175f98cb4da4a88652b673..594421d617b2ce089746284b37ad1c3e9d46f353 100644
--- a/deployment/README.md
+++ b/deployment/README.md
@@ -1,5 +1,4 @@
-Deployment
-===========
+# Deployment
 
 # Überblick
 
@@ -12,6 +11,7 @@ Alternativ kann aich wie gehabt die Konfiguration mit einer `local_settings.py`
 Egal welche der Methden gewählt wir, muss zumindest angegeben werden welche Funktionen auszurollen sind und wie die Datenbank zu erreichen ist.
 Für die Umgebungsvariablen Konfiguration kann die `docker-compose.yml` als Beispiel zu rate gezogen werden.
 Beispiel einer `local_settings.py`:
+
 ```python
 IS_API = False
 IS_BACKOFFICE = False
@@ -30,7 +30,6 @@ DATABASES = {
 }
 ```
 
-
 # Tipps & Tricks
 
 ## Backup
@@ -40,6 +39,7 @@ Allgemein: für ein normales Backup sollte einfach die Datenbank über Bordmitte
 Django hat auch eine Funktion für den Export von Daten eingebaut, diese Variante ist allerdings nicht für den Produktiven Einsatz empfohlen.
 Das Problem liegt hier in der Struktur der Daten bei der Wiederherstellung. Diese ist mit `dumpdata`/`loadata` nicht garaniert.
 Grundsätzlich funktioniert es wie folgt:
+
 1. Docker Container mit "debug" Kommando starten
 2. `./manage.py dumpdata` mit natural keys und ohne Django-Interna laufen lassen
 
diff --git a/src/api/tests/wa_mapservice_import.json b/src/api/tests/wa_mapservice_import.json
index ce110b788c50354df545b43740890851b1ab136e..e20a522af9af5d638202bef205884ccf806ccc0e 100644
--- a/src/api/tests/wa_mapservice_import.json
+++ b/src/api/tests/wa_mapservice_import.json
@@ -30,24 +30,15 @@
             "general": [],
             "layer": {
               "set property \"jitsiTrigger\" to onaction": {
-                "in": [
-                  "jitsi4",
-                  "jitsi5",
-                  "jitsi6"
-                ],
+                "in": ["jitsi4", "jitsi5", "jitsi6"],
                 "level": "Suggestion"
               },
               "set property \"openWebsiteTrigger\" to onaction": {
-                "in": [
-                  "URLtimetable",
-                  "URLchaospost"
-                ],
+                "in": ["URLtimetable", "URLchaospost"],
                 "level": "Suggestion"
               },
               "unknown property type \"inGameConsoleMessage\"": {
-                "in": [
-                  "silent"
-                ],
+                "in": ["silent"],
                 "level": "Error"
               }
             },
@@ -71,23 +62,17 @@
             "general": [],
             "layer": {
               "map links using /_/ are disallowed. Use world:// instead.": {
-                "in": [
-                  "exit_carl"
-                ],
+                "in": ["exit_carl"],
                 "level": "Error"
               },
               "set property \"jitsiTrigger\" to onaction": {
-                "in": [
-                  "jitsi1"
-                ],
+                "in": ["jitsi1"],
                 "level": "Suggestion"
               }
             },
             "tileset": {
               "Tilesets should not be larger than 4096Ã4096 pixels in total": {
-                "in": [
-                  "ZON_DiVOC_Animation_Tileset"
-                ],
+                "in": ["ZON_DiVOC_Animation_Tileset"],
                 "level": "Warning"
               },
               "property \"copyright\" is required": {
@@ -108,18 +93,13 @@
             "general": [],
             "layer": {
               "set \"jitsiTriggerMessage\" to a custom message to overwrite the default \"press SPACE to enter in jitsi meet room\"": {
-                "in": [
-                  "jitsi"
-                ],
+                "in": ["jitsi"],
                 "level": "Suggestion"
               }
             },
             "tileset": {
               "property \"copyright\" is required": {
-                "in": [
-                  "mapUtilities",
-                  "Theater_QuartierLapin"
-                ],
+                "in": ["mapUtilities", "Theater_QuartierLapin"],
                 "level": "Error"
               }
             }
@@ -137,9 +117,7 @@
     "violation": {
       "violationCheck": 1638128989,
       "severity": "Error",
-      "errors": [
-        "authentication required"
-      ]
+      "errors": ["authentication required"]
     }
   },
   "$ROOM_4A_ID": {
@@ -150,9 +128,7 @@
       "violationCheck": 1638128683,
       "violationCommitHash": "3d12520b3c0468d93c0ccfdb5658254d4437af23",
       "severity": "Error",
-      "errors": [
-        "No main.json Map file or error."
-      ]
+      "errors": ["No main.json Map file or error."]
     }
   },
   "$ROOM_5A_ID": {
@@ -198,18 +174,11 @@
                 "level": "Error"
               },
               "set property \"jitsiTrigger\" to onaction": {
-                "in": [
-                  "jitsiBreakfast",
-                  "jitsiWorkshop",
-                  "jitsiHeaven",
-                  "jitsiInfodesk"
-                ],
+                "in": ["jitsiBreakfast", "jitsiWorkshop", "jitsiHeaven", "jitsiInfodesk"],
                 "level": "Suggestion"
               },
               "set property \"openWebsiteTrigger\" to onaction": {
-                "in": [
-                  "openChaospost"
-                ],
+                "in": ["openChaospost"],
                 "level": "Suggestion"
               }
             },
@@ -241,4 +210,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/backoffice/static/backoffice.css b/src/backoffice/static/backoffice.css
index 30c03316fbca2f5aeabea967403630de3f1ef5f5..575f11386a398a5d8d755f622f4b28e19274daee 100644
--- a/src/backoffice/static/backoffice.css
+++ b/src/backoffice/static/backoffice.css
@@ -1,63 +1,63 @@
 .wrapper {
-    display: flex;
-    width: 100%;
-    align-items: stretch;
-    min-height: calc(100vh - 56px);
-    margin-bottom: 32px;
+  display: flex;
+  width: 100%;
+  align-items: stretch;
+  min-height: calc(100vh - 56px);
+  margin-bottom: 32px;
 }
 
 .legal-footer {
-    position: fixed;
-    bottom: 0;
-    width: 100%;
-    left: 0;
-    text-align: center;
-    z-index: 1000;
-    font-size: 0.875rem;
+  position: fixed;
+  bottom: 0;
+  width: 100%;
+  left: 0;
+  text-align: center;
+  z-index: 1000;
+  font-size: 0.875rem;
 }
 
 #sidebar {
-    background: #7386D5;
-    color: #fff;
-    flex: 0 0 250px;
+  background: #7386d5;
+  color: #fff;
+  flex: 0 0 250px;
 }
 
 #sidebar .list-group-item,
 #sidebar .list-group-item > a {
-    align-items: center;
-    background: #7386D5;
-    border: none;
-    color: #fff;
-    display: flex;
+  align-items: center;
+  background: #7386d5;
+  border: none;
+  color: #fff;
+  display: flex;
 }
 
 #sidebar .list-group-item.active,
 #sidebar .list-group-item.active a {
-    color: #ff0;
-    font-weight: bold;
+  color: #ff0;
+  font-weight: bold;
 }
 
 #sidebar .list-group-item.child,
 #sidebar .list-group-item.child a {
-    background: #6d7fcc;
+  background: #6d7fcc;
 }
 
 #sidebar .list-group-item:hover,
 #sidebar .list-group-item a:hover,
 #sidebar .list-group-item:hover a {
-    background: #fff;
-    color: #7386D5;
-    cursor: pointer;
+  background: #fff;
+  color: #7386d5;
+  cursor: pointer;
 }
 
 #sidebar .list-group-item.child {
-    border: none;
-    font-size: .9em !important;
-    padding-left: 3rem;
+  border: none;
+  font-size: 0.9em !important;
+  padding-left: 3rem;
 }
 
 #sidebar a.back {
-    font-size: .75em;
+  font-size: 0.75em;
 }
 
 #sidebar a.blocked {
@@ -65,5 +65,5 @@
 }
 
 .pb-10rem {
-    padding-bottom: 10rem;
+  padding-bottom: 10rem;
 }
diff --git a/src/backoffice/static/backoffice/modal.js b/src/backoffice/static/backoffice/modal.js
index b10568d4fa684df609656493e9a1f91c7c2002fc..a372d509b3d4bd1958bbfe05dd96df385afc2467 100644
--- a/src/backoffice/static/backoffice/modal.js
+++ b/src/backoffice/static/backoffice/modal.js
@@ -1,34 +1,21 @@
 function registerModal() {
-    const myModal = bootstrap.Modal.getOrCreateInstance("#confirmationModal");
-    const confirmationModalSubmit = document.getElementById(
-        "confirmationModalSubmit"
-    );
-    let modalFunction = () => {};
-    confirmationModalSubmit.addEventListener("click", () => {
-        modalFunction();
-    });
+  const myModal = bootstrap.Modal.getOrCreateInstance("#confirmationModal");
+  const confirmationModalSubmit = document.getElementById("confirmationModalSubmit");
+  let modalFunction = () => {};
+  confirmationModalSubmit.addEventListener("click", () => {
+    modalFunction();
+  });
 
-    function showModal(
-        submitFunction,
-        cssClass,
-        header_text,
-        body_text,
-        submit_text
-    ) {
-        document
-            .getElementById("confirmationModalHeader")
-            .classList.remove("bg-warning", "bg-danger");
-        document
-            .getElementById("confirmationModalHeader")
-            .classList.add(`text-bg-${cssClass}`);
-        document.getElementById("confirmationModalLabel").innerHTML =
-            header_text;
-        document.getElementById("confirmationModalBody").innerHTML = body_text;
-        confirmationModalSubmit.innerHTML = submit_text;
-        confirmationModalSubmit.classList.remove("btn-warning", "btn-danger");
-        confirmationModalSubmit.classList.add(`btn-${cssClass}`);
-        modalFunction = submitFunction;
-        myModal.show();
-    }
-    return showModal;
+  function showModal(submitFunction, cssClass, header_text, body_text, submit_text) {
+    document.getElementById("confirmationModalHeader").classList.remove("bg-warning", "bg-danger");
+    document.getElementById("confirmationModalHeader").classList.add(`text-bg-${cssClass}`);
+    document.getElementById("confirmationModalLabel").innerHTML = header_text;
+    document.getElementById("confirmationModalBody").innerHTML = body_text;
+    confirmationModalSubmit.innerHTML = submit_text;
+    confirmationModalSubmit.classList.remove("btn-warning", "btn-danger");
+    confirmationModalSubmit.classList.add(`btn-${cssClass}`);
+    modalFunction = submitFunction;
+    myModal.show();
+  }
+  return showModal;
 }
diff --git a/src/core/fixtures/anhalter.json b/src/core/fixtures/anhalter.json
index d30635a899f113c8b41569a29495ce2e8876162b..c34a24297f28900fbc29aa553f1fadfcb80a2a09 100644
--- a/src/core/fixtures/anhalter.json
+++ b/src/core/fixtures/anhalter.json
@@ -1,196 +1,196 @@
 [
-    {
-        "fields": {
-            "end": "2042-12-30T15:00:00Z",
-            "is_public": true,
-            "name": "Vogonischer Congress",
-            "registration_deadline": null,
-            "slug": "vogc",
-            "start": "2042-12-27T09:00:00Z"
-        },
-        "model": "core.conference",
-        "pk": "017c0749-a2ea-4f86-92cd-e60b4508dd98"
+  {
+    "fields": {
+      "end": "2042-12-30T15:00:00Z",
+      "is_public": true,
+      "name": "Vogonischer Congress",
+      "registration_deadline": null,
+      "slug": "vogc",
+      "start": "2042-12-27T09:00:00Z"
     },
-    {
-        "fields": {
-            "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
-            "is_public": true,
-            "last_update": "2000-02-20T23:42:00Z",
-            "name": "Universum-Highway-Bau",
-            "slug": "spaceway"
-        },
-        "model": "core.conferencetrack",
-        "pk": 1
+    "model": "core.conference",
+    "pk": "017c0749-a2ea-4f86-92cd-e60b4508dd98"
+  },
+  {
+    "fields": {
+      "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
+      "is_public": true,
+      "last_update": "2000-02-20T23:42:00Z",
+      "name": "Universum-Highway-Bau",
+      "slug": "spaceway"
     },
-    {
-        "fields": {
-            "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
-            "is_public": true,
-            "last_update": "2000-02-20T23:42:00Z",
-            "name": "Lyrik",
-            "slug": "poetry"
-        },
-        "model": "core.conferencetrack",
-        "pk": 2
+    "model": "core.conferencetrack",
+    "pk": 1
+  },
+  {
+    "fields": {
+      "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
+      "is_public": true,
+      "last_update": "2000-02-20T23:42:00Z",
+      "name": "Lyrik",
+      "slug": "poetry"
     },
-    {
-        "fields": {
-            "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
-            "is_public": true,
-            "last_update": "2000-02-20T23:42:00Z",
-            "name": "Sonstiges",
-            "slug": "misc"
-        },
-        "model": "core.conferencetrack",
-        "pk": 3
+    "model": "core.conferencetrack",
+    "pk": 2
+  },
+  {
+    "fields": {
+      "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
+      "is_public": true,
+      "last_update": "2000-02-20T23:42:00Z",
+      "name": "Sonstiges",
+      "slug": "misc"
     },
-    {
-        "fields": {
-            "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
-            "slug": "foo",
-            "value_type": "simple",
-            "is_public": true,
-            "description": null
-        },
-        "model": "core.conferencetag",
-        "pk": 1
+    "model": "core.conferencetrack",
+    "pk": 3
+  },
+  {
+    "fields": {
+      "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
+      "slug": "foo",
+      "value_type": "simple",
+      "is_public": true,
+      "description": null
     },
-    {
-        "fields": {
-            "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
-            "slug": "bar",
-            "value_type": "simple",
-            "is_public": true,
-            "description": null
-        },
-        "model": "core.conferencetag",
-        "pk": 2
+    "model": "core.conferencetag",
+    "pk": 1
+  },
+  {
+    "fields": {
+      "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
+      "slug": "bar",
+      "value_type": "simple",
+      "is_public": true,
+      "description": null
     },
-    {
-        "fields": {
-            "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
-            "slug": "michelinstars",
-            "value_type": "int",
-            "is_public": true,
-            "description": "Sterne im Guide Michelin"
-        },
-        "model": "core.conferencetag",
-        "pk": 3
+    "model": "core.conferencetag",
+    "pk": 2
+  },
+  {
+    "fields": {
+      "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
+      "slug": "michelinstars",
+      "value_type": "int",
+      "is_public": true,
+      "description": "Sterne im Guide Michelin"
     },
-    {
-        "fields": {
-            "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
-            "slug": "guter_geschmack",
-            "value_type": "boolean",
-            "is_public": true,
-            "description": null
-        },
-        "model": "core.conferencetag",
-        "pk": 4
+    "model": "core.conferencetag",
+    "pk": 3
+  },
+  {
+    "fields": {
+      "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
+      "slug": "guter_geschmack",
+      "value_type": "boolean",
+      "is_public": true,
+      "description": null
     },
-    {
-        "fields": {
-            "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
-            "slug": "autor_des_besten_gedichts",
-            "value_type": "string",
-            "is_public": true,
-            "description": null
-        },
-        "model": "core.conferencetag",
-        "pk": 5
+    "model": "core.conferencetag",
+    "pk": 4
+  },
+  {
+    "fields": {
+      "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
+      "slug": "autor_des_besten_gedichts",
+      "value_type": "string",
+      "is_public": true,
+      "description": null
     },
-    {
-        "fields": {
-            "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
-            "name": "Heart of Gold",
-            "parent": null,
-            "slug": "heart_of_gold",
-            "state_assembly": "confirmed",
-            "assembly_link": null,
-            "assembly_location": "",
-            "is_physical": true,
-            "created": "1978-03-08T20:00:00Z"
-        },
-        "model": "core.assembly",
-        "pk": "57d13f51-790b-4032-91f5-13138cbfe1dc"
+    "model": "core.conferencetag",
+    "pk": 5
+  },
+  {
+    "fields": {
+      "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
+      "name": "Heart of Gold",
+      "parent": null,
+      "slug": "heart_of_gold",
+      "state_assembly": "confirmed",
+      "assembly_link": null,
+      "assembly_location": "",
+      "is_physical": true,
+      "created": "1978-03-08T20:00:00Z"
     },
-    {
-        "fields": {
-            "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
-            "name": "Magrathea Planet",
-            "description": "Wir haben da einen Computer gebaut. Und Planeten.",
-            "parent": null,
-            "slug": "main",
-            "state_assembly": "accepted",
-            "assembly_link": null,
-            "assembly_location": "",
-            "is_physical": true,
-            "created": "1978-03-08T20:00:00Z"
-        },
-        "model": "core.assembly",
-        "pk": "98b4c68c-1dfc-4e2a-84ae-546ef682fcf2"
+    "model": "core.assembly",
+    "pk": "57d13f51-790b-4032-91f5-13138cbfe1dc"
+  },
+  {
+    "fields": {
+      "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
+      "name": "Magrathea Planet",
+      "description": "Wir haben da einen Computer gebaut. Und Planeten.",
+      "parent": null,
+      "slug": "main",
+      "state_assembly": "accepted",
+      "assembly_link": null,
+      "assembly_location": "",
+      "is_physical": true,
+      "created": "1978-03-08T20:00:00Z"
     },
-    {
-        "fields": {
-            "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
-            "name": "Streaming",
-            "parent": null,
-            "slug": "media",
-            "state_assembly": "accepted",
-            "assembly_link": "https://streaming.media.ccc.de/",
-            "assembly_location": "",
-            "is_virtual": true,
-            "created": "1981-09-12T23:42:00Z"
-        },
-        "model": "core.assembly",
-        "pk": "5387b521-d5ae-4988-af8e-2c297cd5d15b"
+    "model": "core.assembly",
+    "pk": "98b4c68c-1dfc-4e2a-84ae-546ef682fcf2"
+  },
+  {
+    "fields": {
+      "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
+      "name": "Streaming",
+      "parent": null,
+      "slug": "media",
+      "state_assembly": "accepted",
+      "assembly_link": "https://streaming.media.ccc.de/",
+      "assembly_location": "",
+      "is_virtual": true,
+      "created": "1981-09-12T23:42:00Z"
     },
-    {
-        "fields": {
-            "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
-            "name": "BigBlueButton",
-            "parent": null,
-            "slug": "bbb",
-            "state_assembly": "accepted",
-            "assembly_link": null,
-            "assembly_location": "",
-            "is_virtual": true,
-            "created": "2009-06-12T12:34:56Z"
-        },
-        "model": "core.assembly",
-        "pk": "6750a3e0-74df-490e-9fc6-d3d35b587dd5"
+    "model": "core.assembly",
+    "pk": "5387b521-d5ae-4988-af8e-2c297cd5d15b"
+  },
+  {
+    "fields": {
+      "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
+      "name": "BigBlueButton",
+      "parent": null,
+      "slug": "bbb",
+      "state_assembly": "accepted",
+      "assembly_link": null,
+      "assembly_location": "",
+      "is_virtual": true,
+      "created": "2009-06-12T12:34:56Z"
     },
-    {
-        "fields": {
-            "backend_link": null,
-            "capacity": null,
-            "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
-            "last_update": "2000-02-20T23:42:00Z",
-            "name": "Milliways",
-            "slug": "milliways",
-            "room_type": "bbb",
-            "assembly": "6750a3e0-74df-490e-9fc6-d3d35b587dd5"
-        },
-        "model": "core.room",
-        "pk": "b489b08e-ed5a-4820-94c1-26f7019770e3"
+    "model": "core.assembly",
+    "pk": "6750a3e0-74df-490e-9fc6-d3d35b587dd5"
+  },
+  {
+    "fields": {
+      "backend_link": null,
+      "capacity": null,
+      "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
+      "last_update": "2000-02-20T23:42:00Z",
+      "name": "Milliways",
+      "slug": "milliways",
+      "room_type": "bbb",
+      "assembly": "6750a3e0-74df-490e-9fc6-d3d35b587dd5"
     },
-    {
-        "fields": {
-            "additional_data": "{}",
-            "assembly": "6750a3e0-74df-490e-9fc6-d3d35b587dd5",
-            "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
-            "description": "Sehen Sie es live: das Ende des bekannten Universums. Mit Livekommentar von Zaphod Beeblebrox!",
-            "is_public": true,
-            "language": "de",
-            "last_update": "2000-02-20T23:42:00Z",
-            "slug": "ende",
-            "name": "Weltuntergang",
-            "room": "b489b08e-ed5a-4820-94c1-26f7019770e3",
-            "schedule_duration": "02:00:00",
-            "schedule_start": "2042-12-30T11:34:56Z",
-            "track": 3
-        },
-        "model": "core.event",
-        "pk": "35e10dfc-11c2-475b-b682-da1ddd291770"
-    }
+    "model": "core.room",
+    "pk": "b489b08e-ed5a-4820-94c1-26f7019770e3"
+  },
+  {
+    "fields": {
+      "additional_data": "{}",
+      "assembly": "6750a3e0-74df-490e-9fc6-d3d35b587dd5",
+      "conference": "017c0749-a2ea-4f86-92cd-e60b4508dd98",
+      "description": "Sehen Sie es live: das Ende des bekannten Universums. Mit Livekommentar von Zaphod Beeblebrox!",
+      "is_public": true,
+      "language": "de",
+      "last_update": "2000-02-20T23:42:00Z",
+      "slug": "ende",
+      "name": "Weltuntergang",
+      "room": "b489b08e-ed5a-4820-94c1-26f7019770e3",
+      "schedule_duration": "02:00:00",
+      "schedule_start": "2042-12-30T11:34:56Z",
+      "track": 3
+    },
+    "model": "core.event",
+    "pk": "35e10dfc-11c2-475b-b682-da1ddd291770"
+  }
 ]
diff --git a/src/core/fixtures/bootstrap_auth_groups.json b/src/core/fixtures/bootstrap_auth_groups.json
index bc1cb07757307f89ee5d61bfb430cb74cc1add67..f3d3f4ed35a2a94f5c2560db7eecdea15dc00c86 100644
--- a/src/core/fixtures/bootstrap_auth_groups.json
+++ b/src/core/fixtures/bootstrap_auth_groups.json
@@ -1,143 +1,62 @@
 [
-    {
-        "model": "auth.group",
-        "fields": {
-            "name": "Assembly-Team",
-            "permissions": [
-                [
-                    "assembly_team",
-                    "core",
-                    "conferencemember"
-                ]
-            ]
-        }
-    },
-    {
-        "model": "auth.group",
-        "fields": {
-            "name": "Registration Admin",
-            "permissions": [
-                [
-                    "assembly_registration_admin",
-                    "core",
-                    "conferencemember"
-                ]
-            ]
-        }
-    },
-    {
-        "model": "auth.group",
-        "fields": {
-            "name": "Karten-Verwaltung",
-            "permissions": [
-                [
-                    "map_edit",
-                    "core",
-                    "conferencemember"
-                ]
-            ]
-        }
-    },
-    {
-        "model": "auth.group",
-        "fields": {
-            "name": "Schedule Supervisor",
-            "permissions": [
-                [
-                    "scheduleadmin",
-                    "core",
-                    "conferencemember"
-                ],
-                [
-                    "add_schedulesource",
-                    "core",
-                    "schedulesource"
-                ],
-                [
-                    "change_schedulesource",
-                    "core",
-                    "schedulesource"
-                ],
-                [
-                    "delete_schedulesource",
-                    "core",
-                    "schedulesource"
-                ],
-                [
-                    "view_schedulesource",
-                    "core",
-                    "schedulesource"
-                ],
-                [
-                    "view_schedulesourceimport",
-                    "core",
-                    "schedulesourceimport"
-                ],
-                [
-                    "add_schedulesourcemapping",
-                    "core",
-                    "schedulesourcemapping"
-                ],
-                [
-                    "change_schedulesourcemapping",
-                    "core",
-                    "schedulesourcemapping"
-                ],
-                [
-                    "delete_schedulesourcemapping",
-                    "core",
-                    "schedulesourcemapping"
-                ],
-                [
-                    "view_schedulesourcemapping",
-                    "core",
-                    "schedulesourcemapping"
-                ]
-            ]
-        }
-    },
-    {
-        "model": "auth.group",
-        "fields": {
-            "name": "PL",
-            "permissions": [
-                [
-                    "static_pages",
-                    "core",
-                    "conferencemember"
-                ],
-                [
-                    "conference_admin",
-                    "core",
-                    "conferencemember"
-                ]
-            ]
-        }
-    },
-    {
-        "model": "auth.group",
-        "fields": {
-            "name": "Wiki Team",
-            "permissions": [
-                [
-                    "static_pages",
-                    "core",
-                    "conferencemember"
-                ]
-            ]
-        }
-    },
-    {
-        "model": "auth.group",
-        "fields": {
-            "name": "Moderation",
-            "permissions": [
-                [
-                    "moderation",
-                    "core",
-                    "conferencemember"
-                ]
-            ]
-        }
+  {
+    "model": "auth.group",
+    "fields": {
+      "name": "Assembly-Team",
+      "permissions": [["assembly_team", "core", "conferencemember"]]
     }
+  },
+  {
+    "model": "auth.group",
+    "fields": {
+      "name": "Registration Admin",
+      "permissions": [["assembly_registration_admin", "core", "conferencemember"]]
+    }
+  },
+  {
+    "model": "auth.group",
+    "fields": {
+      "name": "Karten-Verwaltung",
+      "permissions": [["map_edit", "core", "conferencemember"]]
+    }
+  },
+  {
+    "model": "auth.group",
+    "fields": {
+      "name": "Schedule Supervisor",
+      "permissions": [
+        ["scheduleadmin", "core", "conferencemember"],
+        ["add_schedulesource", "core", "schedulesource"],
+        ["change_schedulesource", "core", "schedulesource"],
+        ["delete_schedulesource", "core", "schedulesource"],
+        ["view_schedulesource", "core", "schedulesource"],
+        ["view_schedulesourceimport", "core", "schedulesourceimport"],
+        ["add_schedulesourcemapping", "core", "schedulesourcemapping"],
+        ["change_schedulesourcemapping", "core", "schedulesourcemapping"],
+        ["delete_schedulesourcemapping", "core", "schedulesourcemapping"],
+        ["view_schedulesourcemapping", "core", "schedulesourcemapping"]
+      ]
+    }
+  },
+  {
+    "model": "auth.group",
+    "fields": {
+      "name": "PL",
+      "permissions": [["static_pages", "core", "conferencemember"]]
+    }
+  },
+  {
+    "model": "auth.group",
+    "fields": {
+      "name": "Wiki Team",
+      "permissions": [["static_pages", "core", "conferencemember"]]
+    }
+  },
+  {
+    "model": "auth.group",
+    "fields": {
+      "name": "Moderation",
+      "permissions": [["moderation", "core", "conferencemember"]]
+    }
+  }
 ]
diff --git a/src/core/tests/import_data/basic.json b/src/core/tests/import_data/basic.json
index e685becfe08c55492f7eba5aa26e2d3b9afd0394..d38abbe8111263640c3794e6762e8f79afb6511e 100644
--- a/src/core/tests/import_data/basic.json
+++ b/src/core/tests/import_data/basic.json
@@ -1,17 +1,17 @@
 {
-	"rooms": {
-		"eins": {
-			"name": "Saal 1",
-			"description": "Der größte Saal."
-		}
-	},
-	"events": {
-		"cej9dwoi": {
-			"slug": "minkorrekt",
-			"name": "Methodisch Inkorrekt",
-			"schedule_start": "2021-12-06T20:00:00+0100",
-			"schedule_end": "2021-12-06T21:30:00+0100",
-			"room": "eins"
-		}
-	}
-}
\ No newline at end of file
+  "rooms": {
+    "eins": {
+      "name": "Saal 1",
+      "description": "Der größte Saal."
+    }
+  },
+  "events": {
+    "cej9dwoi": {
+      "slug": "minkorrekt",
+      "name": "Methodisch Inkorrekt",
+      "schedule_start": "2021-12-06T20:00:00+0100",
+      "schedule_end": "2021-12-06T21:30:00+0100",
+      "room": "eins"
+    }
+  }
+}
diff --git a/src/core/tests/import_data/frab.speakers.json b/src/core/tests/import_data/frab.speakers.json
index 08a53c2418e8ae8adc9a36de100c22596967fef9..2bf6fbe98a033bccf1846683f00a7e2bef71f774 100644
--- a/src/core/tests/import_data/frab.speakers.json
+++ b/src/core/tests/import_data/frab.speakers.json
@@ -1,7 +1,7 @@
 {
   "schedule_speakers": {
     "speakers": [
-    {
+      {
         "guid": "a57b4a91-0621-553c-a97d-6b47df0f3f0e",
         "id": 19387,
         "image": null,
diff --git a/src/core/tests/import_data/schedule-2021.json b/src/core/tests/import_data/schedule-2021.json
index 4ad4fc8603d5adc32d1d7377dc6dcdcb4c6fcc02..b35477be46011ba616ddcf46d326829d81161ef5 100644
--- a/src/core/tests/import_data/schedule-2021.json
+++ b/src/core/tests/import_data/schedule-2021.json
@@ -1,92 +1,91 @@
 {
-    "schedule": {
-        "version": "v1.3",
-        "base_url": "https://domain.tld/democon/schedule/",
-        "conference": {
-            "acronym": "democon",
-            "title": "DemoCon",
-            "start": "2021-12-14",
-            "end": "2021-12-16",
-            "daysCount": 3,
-            "timeslot_duration": "00:15",
-            "rooms": [
-                {
-                    "name": "Gray Room",
-                    "guid": "b379c473-93b9-4eae-9a09-d482e86cede3",
-                    "description": "foo bar baz",
-                    "capacity": 1000
-                },
-                {
-                    "name": "Tan Room",
-                    "guid": "b379c473-93b9-4eae-9a09-d482e86ceda3",
-                    "description": null,
-                    "capacity": 10
-                }
-            ],
-            "days": [
-                {
-                  "index": 1,
-                  "date": "2021-12-14",
-                  "day_start": "2021-12-14T09:00:00+01:00",
-                  "day_end": "2021-12-14T04:00:00+01:00",
-                  "rooms": {
-                    "Gray Room": [
-                      {
-                        "url": "https://fahrplan.events.ccc.de/democon/fahrplan/events/12345.html",
-                        "id": 12345,
-                        "guid": "a0a0fcfe-b7fb-46e3-84b6-97a5406016b4",
-                        "logo": null,
-                        "date": "2021-12-14T11:00:00+01:00",
-                        "start": "11:00",
-                        "duration": "00:30",
-                        "room": "Gray Room",
-                        "slug": "democon-12345-opening",
-                        "title": "Opening Ceremony",
-                        "subtitle": "",
-                        "track": "CCC",
-                        "type": "lecture",
-                        "language": "en",
-                        "abstract": "A hearty welcome me lasses and lads!",
-                        "description": "",
-                        "recording_license": "",
-                        "do_not_record": false,
-                        "persons": [
-                          { "id": 7797, "public_name": "Jinxx" },
-                          {
-                            "name": "Jane",
-                            "guid": "09ab9fae-5c45-55a1-ac3b-4cff3d94547d",
-                            "email": "jane.doe@example.net",
-                            "biography": "A speaker",
-                            "avatar": "https://domain.tld/img/avatar.png"
-                          }
-                        ],
-                        "links": [],
-                        "attachments": [],
-                        "answers": [
-                            {
-                              "id": 1,
-                              "question": {
-                                "id": 1,
-                                "question": {
-                                  "en": "How much do you like green, on a scale from 1-10?"
-                                },
-                                "required": false,
-                                "target": "submission",
-                                "options": []
-                              },
-                              "answer": "11",
-                              "answer_file": null,
-                              "submission": "ABCDE",
-                              "person": null,
-                              "options": []
-                            }
-                          ]
-                      }
-                    ]
-                }
-                }
+  "schedule": {
+    "version": "v1.3",
+    "base_url": "https://domain.tld/democon/schedule/",
+    "conference": {
+      "acronym": "democon",
+      "title": "DemoCon",
+      "start": "2021-12-14",
+      "end": "2021-12-16",
+      "daysCount": 3,
+      "timeslot_duration": "00:15",
+      "rooms": [
+        {
+          "name": "Gray Room",
+          "guid": "b379c473-93b9-4eae-9a09-d482e86cede3",
+          "description": "foo bar baz",
+          "capacity": 1000
+        },
+        {
+          "name": "Tan Room",
+          "guid": "b379c473-93b9-4eae-9a09-d482e86ceda3",
+          "description": null,
+          "capacity": 10
+        }
+      ],
+      "days": [
+        {
+          "index": 1,
+          "date": "2021-12-14",
+          "day_start": "2021-12-14T09:00:00+01:00",
+          "day_end": "2021-12-14T04:00:00+01:00",
+          "rooms": {
+            "Gray Room": [
+              {
+                "url": "https://fahrplan.events.ccc.de/democon/fahrplan/events/12345.html",
+                "id": 12345,
+                "guid": "a0a0fcfe-b7fb-46e3-84b6-97a5406016b4",
+                "logo": null,
+                "date": "2021-12-14T11:00:00+01:00",
+                "start": "11:00",
+                "duration": "00:30",
+                "room": "Gray Room",
+                "slug": "democon-12345-opening",
+                "title": "Opening Ceremony",
+                "subtitle": "",
+                "track": "CCC",
+                "type": "lecture",
+                "language": "en",
+                "abstract": "A hearty welcome me lasses and lads!",
+                "description": "",
+                "recording_license": "",
+                "do_not_record": false,
+                "persons": [
+                  { "id": 7797, "public_name": "Jinxx" },
+                  {
+                    "name": "Jane",
+                    "guid": "09ab9fae-5c45-55a1-ac3b-4cff3d94547d",
+                    "email": "jane.doe@example.net",
+                    "biography": "A speaker",
+                    "avatar": "https://domain.tld/img/avatar.png"
+                  }
+                ],
+                "links": [],
+                "attachments": [],
+                "answers": [
+                  {
+                    "id": 1,
+                    "question": {
+                      "id": 1,
+                      "question": {
+                        "en": "How much do you like green, on a scale from 1-10?"
+                      },
+                      "required": false,
+                      "target": "submission",
+                      "options": []
+                    },
+                    "answer": "11",
+                    "answer_file": null,
+                    "submission": "ABCDE",
+                    "person": null,
+                    "options": []
+                  }
+                ]
+              }
             ]
+          }
         }
+      ]
     }
+  }
 }
-    
\ No newline at end of file
diff --git a/src/core/tests/import_data/wildcard.json b/src/core/tests/import_data/wildcard.json
index 34e2c09c51adc7130da3771068079f40eed68065..c3ac1b7f46fd3b79aa4ca8cfe4f1223862bce3bb 100644
--- a/src/core/tests/import_data/wildcard.json
+++ b/src/core/tests/import_data/wildcard.json
@@ -1,30 +1,30 @@
 {
-    "rooms": {
-        "alpha": {
-            "name": "Saal 1",
-            "guid": "f19b7ae0-5f2d-420c-ae4b-48e56a09ff15",
-            "description": "Der größte Saal."
-        },
-        "beta": {
-            "name": "Hackcenter",
-            "guid": "4f9c1df8-926a-49e6-aa64-515e63846c12",
-            "description": "ein anderer Saal"
-        }
+  "rooms": {
+    "alpha": {
+      "name": "Saal 1",
+      "guid": "f19b7ae0-5f2d-420c-ae4b-48e56a09ff15",
+      "description": "Der größte Saal."
     },
-    "events": {
-        "cej9dwoi": {
-            "slug": "minkorrekt",
-            "name": "Methodisch Inkorrekt",
-            "schedule_start": "2021-12-06T20:00:00+0100",
-            "schedule_end": "2021-12-06T21:30:00+0100",
-            "room": "alpha"
-        },
-        "a42fn0rd": {
-            "slug": "blubb",
-            "name": "Bla Bla",
-            "schedule_start": "2021-12-06T20:00:00+0100",
-            "schedule_end": "2021-12-06T21:30:00+0100",
-            "room": "beta"
-        }
+    "beta": {
+      "name": "Hackcenter",
+      "guid": "4f9c1df8-926a-49e6-aa64-515e63846c12",
+      "description": "ein anderer Saal"
     }
+  },
+  "events": {
+    "cej9dwoi": {
+      "slug": "minkorrekt",
+      "name": "Methodisch Inkorrekt",
+      "schedule_start": "2021-12-06T20:00:00+0100",
+      "schedule_end": "2021-12-06T21:30:00+0100",
+      "room": "alpha"
+    },
+    "a42fn0rd": {
+      "slug": "blubb",
+      "name": "Bla Bla",
+      "schedule_start": "2021-12-06T20:00:00+0100",
+      "schedule_end": "2021-12-06T21:30:00+0100",
+      "room": "beta"
+    }
+  }
 }
diff --git a/src/plainui/static/plainui/js/animations.js b/src/plainui/static/plainui/js/animations.js
index 7e84f650218235deb86fde87f3f65d1bf01c98a1..14a07f04670b801ea60e227cbd1448ca51f150a9 100644
--- a/src/plainui/static/plainui/js/animations.js
+++ b/src/plainui/static/plainui/js/animations.js
@@ -1,702 +1,621 @@
 var initParallax = (callback) => {
-    if (document.readyState != "loading") callback();
-    else document.addEventListener("DOMContentLoaded", callback);
-}
+  if (document.readyState != "loading") callback();
+  else document.addEventListener("DOMContentLoaded", callback);
+};
 
 initParallax(() => {
-    if (!('querySelector' in document)
-        || !('requestAnimationFrame' in window)) {
-        return;
+  if (!("querySelector" in document) || !("requestAnimationFrame" in window)) {
+    return;
+  }
+  const body = document.querySelector("body");
+  // Parallax only with some body classes
+  if (!body.classList.contains("eyecandy-deluxe")) {
+    return;
+  }
+
+  let lastPos;
+  const layer01 = document.querySelector(".rc3-bg-L01");
+  const layer05L = document.querySelector(".rc3-bg-L05-L");
+  const layer05R = document.querySelector(".rc3-bg-L05-R");
+  const layer06 = document.querySelector(".rc3-bg-L06");
+  const layer10 = document.querySelector(".rc3-bg-L10");
+  const main = document.querySelector(".rc3-main");
+
+  if (layer05R) {
+    layer05R.classList.add(`collage-r-` + Math.floor(Math.random() * 7 + 1));
+  }
+
+  if (layer05L) {
+    layer05L.classList.add(`collage-l-` + Math.floor(Math.random() * 6 + 1));
+  }
+
+  const setTransform = (el, factor, scale) => {
+    if (el) {
+      el.style.transform = `translate3D(0,${window.scrollY * factor}px,0) scale(${scale})`;
     }
-    const body = document.querySelector('body');
-    // Parallax only with some body classes
-    if (!body.classList.contains('eyecandy-deluxe')) {
-        return;
+  };
+  const setBgPosition = (el, factor) => {
+    if (el) {
+      el.style.backgroundPositionY = window.scrollY * factor + "px";
     }
-
-    let lastPos;
-    const layer01 = document.querySelector('.rc3-bg-L01');
-    const layer05L = document.querySelector('.rc3-bg-L05-L');
-    const layer05R = document.querySelector('.rc3-bg-L05-R');
-    const layer06 = document.querySelector('.rc3-bg-L06');
-    const layer10 = document.querySelector('.rc3-bg-L10');
-    const main = document.querySelector('.rc3-main');
-
-    if (layer05R) {
-        layer05R.classList.add(`collage-r-` + Math.floor((Math.random() * 7) + 1));
-    }
-
-    if (layer05L) {
-        layer05L.classList.add(`collage-l-` + Math.floor((Math.random() * 6) + 1));
-    }
-
-    const setTransform = (el, factor, scale) => {
-        if (el) {
-            el.style.transform = `translate3D(0,${window.scrollY * factor}px,0) scale(${scale})`;
-        }
-    }
-    const setBgPosition = (el, factor) => {
-        if (el) {
-            el.style.backgroundPositionY = window.scrollY * factor + "px"
-        }
-    }
-
-    function step() {
-        if (!lastPos)
-            lastPos = window.scrollY;
-
-        if (lastPos !== window.scrollY) {
-            setBgPosition(layer01, -1.2);
-            setTransform(layer05R, -0.1, "1");
-            setTransform(layer05L, -0.2, "1");
-            setBgPosition(layer06, 0.5);
-            setTransform(layer10, -0.02, "1");
-            // Move mask for header
-            if (main) {
-                main.style.maskPositionY = window.scrollY - 170 + "px";
-                main.style.webkitMaskPositionY = window.scrollY - 170 + "px";
-
-                if (window.scrollY < 10) {
-                    main.style.webkitMaskImage = 'none';
-                    main.style.maskImage = 'none';
-                } else {
-                    main.style.webkitMaskImage = 'linear-gradient(180deg, transparent 0em, transparent 80px, rgba(0, 0, 0, 1) 170px)';
-                    main.style.maskImage = 'linear-gradient(180deg, transparent 0em, transparent 80px, rgba(0, 0, 0, 1) 170px)';
-                }
-            }
-        }
-        lastPos = window.scrollY;
-        window.requestAnimationFrame(step);
+  };
+
+  function step() {
+    if (!lastPos) lastPos = window.scrollY;
+
+    if (lastPos !== window.scrollY) {
+      setBgPosition(layer01, -1.2);
+      setTransform(layer05R, -0.1, "1");
+      setTransform(layer05L, -0.2, "1");
+      setBgPosition(layer06, 0.5);
+      setTransform(layer10, -0.02, "1");
+      // Move mask for header
+      if (main) {
+        main.style.maskPositionY = window.scrollY - 170 + "px";
+        main.style.webkitMaskPositionY = window.scrollY - 170 + "px";
+
+        if (window.scrollY < 10) {
+          main.style.webkitMaskImage = "none";
+          main.style.maskImage = "none";
+        } else {
+          main.style.webkitMaskImage =
+            "linear-gradient(180deg, transparent 0em, transparent 80px, rgba(0, 0, 0, 1) 170px)";
+          main.style.maskImage = "linear-gradient(180deg, transparent 0em, transparent 80px, rgba(0, 0, 0, 1) 170px)";
+        }
+      }
     }
+    lastPos = window.scrollY;
     window.requestAnimationFrame(step);
+  }
+  window.requestAnimationFrame(step);
 });
 
 var initParticles = (callback) => {
-    if (document.readyState != "loading") callback();
-    else document.addEventListener("DOMContentLoaded", callback);
-}
+  if (document.readyState != "loading") callback();
+  else document.addEventListener("DOMContentLoaded", callback);
+};
 
 initParticles(() => {
-    /*
-    *  Particles.js
-    * 
-    *  Particle emitter and renderer.
-    * 
-    *  TODO: Gleichmäßige Particle verteilung
-    *  TODO: Pulse Animation anpassen (easing)
-    */
-
-    // The Fast-Memoize Library:
-    // https://github.com/caiogondim/fast-memoize.js
-    /*
-     *  Particles.js
-     * 
-     *  Particle emitter and renderer.
-     * 
-     *  TODO: Gleichmäßige Particle verteilung
-     *  TODO: Pulse Animation anpassen (easing)
-     */
-
-    // The Fast-Memoize Library:
-    // https://github.com/caiogondim/fast-memoize.js
-
-    var Memoize = (function () {
-        //
-        // Main
-        //
-
-        function memoize(fn, options) {
-            var cache = options && options.cache
-                ? options.cache
-                : cacheDefault
-
-            var serializer = options && options.serializer
-                ? options.serializer
-                : serializerDefault
-
-            var strategy = options && options.strategy
-                ? options.strategy
-                : strategyDefault
-
-            return strategy(fn, {
-                cache: cache,
-                serializer: serializer
-            })
-        }
-
-        //
-        // Strategy
-        //
-
-        function isPrimitive(value) {
-            return value == null || typeof value === 'number' || typeof value === 'boolean' // || typeof value === "string" 'unsafe' primitive for our needs
-        }
-
-        function monadic(fn, cache, serializer, arg) {
-            var cacheKey = isPrimitive(arg) ? arg : serializer(arg)
-
-            var computedValue = cache.get(cacheKey)
-            if (typeof computedValue === 'undefined') {
-                computedValue = fn.call(this, arg)
-                cache.set(cacheKey, computedValue)
-            }
-
-            return computedValue
-        }
-
-        function variadic(fn, cache, serializer) {
-            var args = Array.prototype.slice.call(arguments, 3)
-            var cacheKey = serializer(args)
-
-            var computedValue = cache.get(cacheKey)
-            if (typeof computedValue === 'undefined') {
-                computedValue = fn.apply(this, args)
-                cache.set(cacheKey, computedValue)
-            }
-
-            return computedValue
-        }
-
-        function assemble(fn, context, strategy, cache, serialize) {
-            return strategy.bind(
-                context,
-                fn,
-                cache,
-                serialize
-            )
-        }
-
-        function strategyDefault(fn, options) {
-            var strategy = fn.length === 1 ? monadic : variadic
-
-            return assemble(
-                fn,
-                this,
-                strategy,
-                options.cache.create(),
-                options.serializer
-            )
-        }
-
-        function strategyVariadic(fn, options) {
-            var strategy = variadic
-
-            return assemble(
-                fn,
-                this,
-                strategy,
-                options.cache.create(),
-                options.serializer
-            )
-        }
-
-        function strategyMonadic(fn, options) {
-            var strategy = monadic
-
-            return assemble(
-                fn,
-                this,
-                strategy,
-                options.cache.create(),
-                options.serializer
-            )
-        }
-
-        //
-        // Serializer
-        //
+  /*
+   *  Particles.js
+   *
+   *  Particle emitter and renderer.
+   *
+   *  TODO: Gleichmäßige Particle verteilung
+   *  TODO: Pulse Animation anpassen (easing)
+   */
+
+  // The Fast-Memoize Library:
+  // https://github.com/caiogondim/fast-memoize.js
+  /*
+   *  Particles.js
+   *
+   *  Particle emitter and renderer.
+   *
+   *  TODO: Gleichmäßige Particle verteilung
+   *  TODO: Pulse Animation anpassen (easing)
+   */
+
+  // The Fast-Memoize Library:
+  // https://github.com/caiogondim/fast-memoize.js
+
+  var Memoize = (function () {
+    //
+    // Main
+    //
+
+    function memoize(fn, options) {
+      var cache = options && options.cache ? options.cache : cacheDefault;
+
+      var serializer = options && options.serializer ? options.serializer : serializerDefault;
+
+      var strategy = options && options.strategy ? options.strategy : strategyDefault;
+
+      return strategy(fn, {
+        cache: cache,
+        serializer: serializer,
+      });
+    }
 
-        function serializerDefault() {
-            return JSON.stringify(arguments)
-        }
+    //
+    // Strategy
+    //
 
-        //
-        // Cache
-        //
+    function isPrimitive(value) {
+      return value == null || typeof value === "number" || typeof value === "boolean"; // || typeof value === "string" 'unsafe' primitive for our needs
+    }
 
-        function ObjectWithoutPrototypeCache() {
-            this.cache = Object.create(null)
-        }
+    function monadic(fn, cache, serializer, arg) {
+      var cacheKey = isPrimitive(arg) ? arg : serializer(arg);
 
-        ObjectWithoutPrototypeCache.prototype.has = function (key) {
-            return (key in this.cache)
-        }
+      var computedValue = cache.get(cacheKey);
+      if (typeof computedValue === "undefined") {
+        computedValue = fn.call(this, arg);
+        cache.set(cacheKey, computedValue);
+      }
 
-        ObjectWithoutPrototypeCache.prototype.get = function (key) {
-            return this.cache[key]
-        }
-
-        ObjectWithoutPrototypeCache.prototype.set = function (key, value) {
-            this.cache[key] = value
-        }
+      return computedValue;
+    }
 
-        var cacheDefault = {
-            create: function create() {
-                return new ObjectWithoutPrototypeCache()
-            }
-        }
+    function variadic(fn, cache, serializer) {
+      var args = Array.prototype.slice.call(arguments, 3);
+      var cacheKey = serializer(args);
 
-        //
-        // API
-        //
+      var computedValue = cache.get(cacheKey);
+      if (typeof computedValue === "undefined") {
+        computedValue = fn.apply(this, args);
+        cache.set(cacheKey, computedValue);
+      }
 
-        // Default export
-        var exports = memoize
-        exports.strategies = {
-            variadic: strategyVariadic,
-            monadic: strategyMonadic
-        }
+      return computedValue;
+    }
 
-        return exports
+    function assemble(fn, context, strategy, cache, serialize) {
+      return strategy.bind(context, fn, cache, serialize);
+    }
 
-    })()
+    function strategyDefault(fn, options) {
+      var strategy = fn.length === 1 ? monadic : variadic;
 
+      return assemble(fn, this, strategy, options.cache.create(), options.serializer);
+    }
 
+    function strategyVariadic(fn, options) {
+      var strategy = variadic;
 
-    // Create the Particles Module | Namespace.
-    var Particles = (function () {
+      return assemble(fn, this, strategy, options.cache.create(), options.serializer);
+    }
 
-        //
-        //  Helper
-        //
-        var MathRandom = Math.random
-        var MathAbs = Math.abs
-        var MathTrunc = Math.trunc
-        var MathPow = Math.pow
+    function strategyMonadic(fn, options) {
+      var strategy = monadic;
 
+      return assemble(fn, this, strategy, options.cache.create(), options.serializer);
+    }
 
-        function randomValue(min, max) {
-            var value = (MathRandom() * (+max - +min) + +min)
-            // Prevent values that can be possible boring
-            return (min !== 0 && max !== 0 && (value === 0 || value === 1))
-                ? randomValue(min, max)
-                : value
-        }
+    //
+    // Serializer
+    //
 
-        function getNodeYOffset(node) {
-            var dimensions = node.getBoundingClientRect()
-            return (dimensions) ? dimensions.y : 0
-        }
+    function serializerDefault() {
+      return JSON.stringify(arguments);
+    }
 
-        function getNodeHeight(node) {
-            var dimensions = node.getBoundingClientRect()
-            return (dimensions) ? dimensions.height : window.innerHeight
-        }
+    //
+    // Cache
+    //
 
-        function calcParticleCount(scene, particleDensity) {
-            var referenceArea = 100 * 100 // 100px * 100px => px^2
-            var sceneVolume = scene.width * scene.height
-            var scale = 100
-            var particleFactor = (sceneVolume / referenceArea) / scale
-            var particleCount = MathAbs(MathTrunc(
-                particleFactor * particleDensity
-            ))
-            return particleCount || 0
-        }
+    function ObjectWithoutPrototypeCache() {
+      this.cache = Object.create(null);
+    }
 
-        var normalize = Memoize(
-            function doNormalize(val) {
-                var min = 0
-                var max = 1
-                var delta = max - min
-                return (val - min) / delta
-            }
-        )
-
-        // Easing functions from: https://easings.net/
-
-        var easeOutQuint = Memoize(
-            function doEaseOutQuint(x) {
-                return 1 - MathPow(1 - x, 5);
-            }
-        )
-
-        var easeOutExpo = Memoize(
-            function easeOutExpo(x) {
-                return x >= 1 ? 1 : 1 - MathPow(2, -10 * x);
-            }
-        )
-
-
-        function easing(value) {
-            return (value < 0)
-                ? -easeOutExpo(-value)
-                : easeOutExpo(value)
-        }
+    ObjectWithoutPrototypeCache.prototype.has = function (key) {
+      return key in this.cache;
+    };
+
+    ObjectWithoutPrototypeCache.prototype.get = function (key) {
+      return this.cache[key];
+    };
+
+    ObjectWithoutPrototypeCache.prototype.set = function (key, value) {
+      this.cache[key] = value;
+    };
+
+    var cacheDefault = {
+      create: function create() {
+        return new ObjectWithoutPrototypeCache();
+      },
+    };
+
+    //
+    // API
+    //
+
+    // Default export
+    var exports = memoize;
+    exports.strategies = {
+      variadic: strategyVariadic,
+      monadic: strategyMonadic,
+    };
+
+    return exports;
+  })();
+
+  // Create the Particles Module | Namespace.
+  var Particles = (function () {
+    //
+    //  Helper
+    //
+    var MathRandom = Math.random;
+    var MathAbs = Math.abs;
+    var MathTrunc = Math.trunc;
+    var MathPow = Math.pow;
+
+    function randomValue(min, max) {
+      var value = MathRandom() * (+max - +min) + +min;
+      // Prevent values that can be possible boring
+      return min !== 0 && max !== 0 && (value === 0 || value === 1) ? randomValue(min, max) : value;
+    }
 
+    function getNodeYOffset(node) {
+      var dimensions = node.getBoundingClientRect();
+      return dimensions ? dimensions.y : 0;
+    }
 
-        //
-        //  Data
-        //
+    function getNodeHeight(node) {
+      var dimensions = node.getBoundingClientRect();
+      return dimensions ? dimensions.height : window.innerHeight;
+    }
 
+    function calcParticleCount(scene, particleDensity) {
+      var referenceArea = 100 * 100; // 100px * 100px => px^2
+      var sceneVolume = scene.width * scene.height;
+      var scale = 100;
+      var particleFactor = sceneVolume / referenceArea / scale;
+      var particleCount = MathAbs(MathTrunc(particleFactor * particleDensity));
+      return particleCount || 0;
+    }
 
-        function Point2D(x, y) {
-            return { x, y }
-        }
+    var normalize = Memoize(function doNormalize(val) {
+      var min = 0;
+      var max = 1;
+      var delta = max - min;
+      return (val - min) / delta;
+    });
 
-        function MinMax(min, max) {
-            return { min, max }
-        }
+    // Easing functions from: https://easings.net/
 
-        function RandomPoint2D(minMaxX, minMaxY) {
-            var x = randomValue(minMaxX.min, minMaxX.max)
-            var y = randomValue(minMaxY.min, minMaxY.max)
-            return Point2D(x, y)
-        }
+    var easeOutQuint = Memoize(function doEaseOutQuint(x) {
+      return 1 - MathPow(1 - x, 5);
+    });
 
+    var easeOutExpo = Memoize(function easeOutExpo(x) {
+      return x >= 1 ? 1 : 1 - MathPow(2, -10 * x);
+    });
 
-        //
-        //  Transformations | Actions
-        //
-
-
-        function Update(scene, particle) {
-            // Cache object access -> Performance
-            var width = scene.width
-            var height = scene.height
-            var color = particle.color
-            var particleSize = particle.size
-            var particleSizeStep = particleSize.step
-            var particleSizeAnimValue = particleSize.animValue
-            var particleSizeScale = particleSize.scale
-            var particleSizeDirection = particleSize.direction
-            var particlePosition = particle.position
-            var particlePositionX = particlePosition.x
-            var particlePositionY = particlePosition.y
-            var particleDirection = particle.direction
-            var particleDirectionX = particleDirection.x
-            var particleDirectionY = particleDirection.y
-
-            // Animate the pulse effect of the particle
-            //
-            // var absSizeAnimValue = particleSizeAnimValue * particleSizeDirection
-            var isMaxSize = particleSizeAnimValue > 1
-            var isMinSize = particleSizeAnimValue < -1
-            var sizeDirection =
-                (isMaxSize || isMinSize)
-                    ? -particleSizeDirection
-                    : particleSizeDirection
-            var animValue = particleSizeAnimValue + (particleSizeStep * sizeDirection)
-            // The operator ~~ is a more performant shorthand for Math.trunc()
-            var sizeValue = ~~(
-                easing(animValue) * particleSizeScale
-            )
-
-            // Animate the movement of the particle
-            // 
-            var sizeOffset = sizeValue * 0.5
-            var top = particlePositionY + sizeOffset
-            var bottom = particlePositionY - sizeOffset
-            var left = particlePositionX - sizeOffset
-            var right = particlePositionX + sizeOffset
-
-            var isRightEdge = (left > (width + 1))
-            var isLeftEdge = (right < -1)
-            var isTopEdge = (bottom < -1)
-            var isBottomEdge = (top > (height + 1))
-
-            var positionX =
-                (isRightEdge)
-                    ? -sizeOffset
-                    : (isLeftEdge)
-                        ? width + sizeOffset
-                        : particlePositionX + particleDirectionX
-            var positionY =
-                (isBottomEdge)
-                    ? -sizeOffset
-                    : (isTopEdge)
-                        ? height + sizeOffset
-                        : particlePositionY + particleDirectionY
-            return {
-                position: {
-                    x: positionX,
-                    y: positionY,
-                },
-                direction: particleDirection,
-                size: {
-                    value: sizeValue,
-                    animValue: animValue,
-                    step: particleSizeStep,
-                    scale: particleSizeScale,
-                    direction: sizeDirection,
-                    offset: sizeOffset
-                },
-                color: color
-            }
-        }
+    function easing(value) {
+      return value < 0 ? -easeOutExpo(-value) : easeOutExpo(value);
+    }
 
-        function Draw(scene, particle) {
-            // Cache object access
-            var particlePosition = particle.position
-            var particlePositionX = particlePosition.x
-            var particlePositionY = particlePosition.y
-            var particleSize = particle.size
-            var particleSizeValue = particleSize.value
-            var drawOffset = particleSize.offset
-
-            // Draw calculations -- 
-            var yOffset = scene.yOffset * scene.depthScale
-            var size = particleSizeValue
-            var x = particlePositionX - drawOffset
-            var y = yOffset + (particlePositionY - drawOffset)
-
-            var ctx = scene.ctx
-            // var isVisible = (size > 0 && y < window.innerHeight && y > 0)
-            var isVisible = (size > 0)
-
-            // Draw
-            if (isVisible) {
-                ctx.fillStyle = particle.color
-                // Round to full integer to prevent subpixel rendering
-                //  - The ~~ operator is equivalent to Math.trunc() but faster.
-                // ctx.fillRect(~~x, ~~y, size, size)
-                ctx.fillRect(x, y, size, size)
-            }
-        }
+    //
+    //  Data
+    //
 
-        function Clear(scene) {
-            scene.ctx.clearRect(0, 0, scene.width, scene.height)
-        }
+    function Point2D(x, y) {
+      return { x, y };
+    }
 
-        function Render(scene, particles) {
-            Clear(scene)
-            particles.forEach(
-                function doDraw(particle) {
-                    Draw(scene, particle)
-                }
-            )
-        }
+    function MinMax(min, max) {
+      return { min, max };
+    }
 
-        function Animate(scene, particles) {
-            var updatedParticles = [],
-                fpsInterval = scene.fpsInterval,
-                now = performance.now(),
-                then = scene.then,
-                elapsed = now - then,
-                tolerance = 0.1
-
-            // Just render when we're reaching the configured fps
-            if (elapsed >= (scene.fpsInterval - tolerance)) {
-                scene.yOffset = getNodeYOffset(scene.anchorNode)
-                scene.then = now - (elapsed % fpsInterval)
-                Render(scene, particles)
-            }
-
-            // Update particle positions for the next render call
-            updatedParticles = particles.map(function doUpdate(p) {
-                return Update(scene, p)
-            })
-
-            // Function to animate the next frame
-            return function nextFrame() {
-                return Animate(
-                    scene,
-                    updatedParticles
-                )
-            }
-        }
+    function RandomPoint2D(minMaxX, minMaxY) {
+      var x = randomValue(minMaxX.min, minMaxX.max);
+      var y = randomValue(minMaxY.min, minMaxY.max);
+      return Point2D(x, y);
+    }
 
-        function CreateScene(cfg) {
-            var canvasId = cfg.canvasId,
-                contentId = cfg.contentId,
-                depth = cfg.depth,
-                fps = cfg.fps
-
-            var contentNode = document.getElementById(contentId),
-                width = window.innerWidth,
-                fpsInterval = 1000 / fps,
-                yOffset = 0,
-                canvas = document.getElementById(canvasId),
-                height = getNodeHeight(canvas),
-                ctx = canvas.getContext('2d'),
-                depthScaledHeight = height * (depth + 1)
-
-            ctx.canvas.width = width
-            ctx.canvas.height = window.innerHeight
-
-            return {
-                width: width,
-                height: depthScaledHeight,
-                yOffset: yOffset,
-                depthScale: depth,
-                fps: fps,
-                fpsInterval: fpsInterval,
-                then: performance.now(),
-                anchorNode: contentNode,
-                ctx: ctx,
-            }
-        }
+    //
+    //  Transformations | Actions
+    //
+
+    function Update(scene, particle) {
+      // Cache object access -> Performance
+      var width = scene.width;
+      var height = scene.height;
+      var color = particle.color;
+      var particleSize = particle.size;
+      var particleSizeStep = particleSize.step;
+      var particleSizeAnimValue = particleSize.animValue;
+      var particleSizeScale = particleSize.scale;
+      var particleSizeDirection = particleSize.direction;
+      var particlePosition = particle.position;
+      var particlePositionX = particlePosition.x;
+      var particlePositionY = particlePosition.y;
+      var particleDirection = particle.direction;
+      var particleDirectionX = particleDirection.x;
+      var particleDirectionY = particleDirection.y;
+
+      // Animate the pulse effect of the particle
+      //
+      // var absSizeAnimValue = particleSizeAnimValue * particleSizeDirection
+      var isMaxSize = particleSizeAnimValue > 1;
+      var isMinSize = particleSizeAnimValue < -1;
+      var sizeDirection = isMaxSize || isMinSize ? -particleSizeDirection : particleSizeDirection;
+      var animValue = particleSizeAnimValue + particleSizeStep * sizeDirection;
+      // The operator ~~ is a more performant shorthand for Math.trunc()
+      var sizeValue = ~~(easing(animValue) * particleSizeScale);
+
+      // Animate the movement of the particle
+      //
+      var sizeOffset = sizeValue * 0.5;
+      var top = particlePositionY + sizeOffset;
+      var bottom = particlePositionY - sizeOffset;
+      var left = particlePositionX - sizeOffset;
+      var right = particlePositionX + sizeOffset;
+
+      var isRightEdge = left > width + 1;
+      var isLeftEdge = right < -1;
+      var isTopEdge = bottom < -1;
+      var isBottomEdge = top > height + 1;
+
+      var positionX = isRightEdge
+        ? -sizeOffset
+        : isLeftEdge
+          ? width + sizeOffset
+          : particlePositionX + particleDirectionX;
+      var positionY = isBottomEdge
+        ? -sizeOffset
+        : isTopEdge
+          ? height + sizeOffset
+          : particlePositionY + particleDirectionY;
+      return {
+        position: {
+          x: positionX,
+          y: positionY,
+        },
+        direction: particleDirection,
+        size: {
+          value: sizeValue,
+          animValue: animValue,
+          step: particleSizeStep,
+          scale: particleSizeScale,
+          direction: sizeDirection,
+          offset: sizeOffset,
+        },
+        color: color,
+      };
+    }
 
+    function Draw(scene, particle) {
+      // Cache object access
+      var particlePosition = particle.position;
+      var particlePositionX = particlePosition.x;
+      var particlePositionY = particlePosition.y;
+      var particleSize = particle.size;
+      var particleSizeValue = particleSize.value;
+      var drawOffset = particleSize.offset;
+
+      // Draw calculations --
+      var yOffset = scene.yOffset * scene.depthScale;
+      var size = particleSizeValue;
+      var x = particlePositionX - drawOffset;
+      var y = yOffset + (particlePositionY - drawOffset);
+
+      var ctx = scene.ctx;
+      // var isVisible = (size > 0 && y < window.innerHeight && y > 0)
+      var isVisible = size > 0;
+
+      // Draw
+      if (isVisible) {
+        ctx.fillStyle = particle.color;
+        // Round to full integer to prevent subpixel rendering
+        //  - The ~~ operator is equivalent to Math.trunc() but faster.
+        // ctx.fillRect(~~x, ~~y, size, size)
+        ctx.fillRect(x, y, size, size);
+      }
+    }
 
-        function CreateParticles(scene, cfg) {
-            var density = cfg.density,
-                color = cfg.color,
-                size = cfg.size,
-                speed = cfg.speed,
-                lifespan = cfg.lifespan
-
-            var initAnimValue = randomValue(-1, 1)
-
-            return Array.from(
-                {
-                    // length: 1
-                    length: calcParticleCount(scene, density)
-                },
-                function Particle() {
-                    const lifeLength = randomValue(lifespan.min, lifespan.max)
-                    return {
-                        position:
-                            RandomPoint2D(
-                                MinMax(0, (scene.width - (size * 2))),
-                                MinMax(0, (scene.height - (size * 2))),
-                            ),
-                        direction:
-                            RandomPoint2D(
-                                MinMax(-speed, speed),
-                                MinMax(-speed, speed)
-                            ),
-                        size: {
-                            animValue: initAnimValue,
-                            scale: size,
-                            value: size * initAnimValue,
-                            step: 1 / ((lifeLength) / scene.fps),
-                            direction:
-                                // 50% Chance for the particle floating in one
-                                // direction or the other.
-                                (randomValue(0, 100) < 50)
-                                    ? -1
-                                    : +1,
-                            // Offset is needed for boundary calculation and for
-                            // drawing the pixels. We cache it here, to prevent
-                            // double calculation of the same value.
-                            offset: size * initAnimValue * 0.5
-                        },
-                        color
-                    }
-                }
-            )
-        }
+    function Clear(scene) {
+      scene.ctx.clearRect(0, 0, scene.width, scene.height);
+    }
 
+    function Render(scene, particles) {
+      Clear(scene);
+      particles.forEach(function doDraw(particle) {
+        Draw(scene, particle);
+      });
+    }
 
-        //
-        //  Api
-        //
-
-
-        function Particles(configs) {
-
-            var particles = []
-            var isRunning = false
-            var throttled = false
-            var delay = 250 // ms
-            var rafId = undefined
-
-            function animate(rendererList) {
-                if (isRunning) {
-                    rafId = requestAnimationFrame(function doRaf() {
-                        animate(
-                            rendererList.map(function doRender(render) {
-                                return render()
-                            })
-                        )
-                    })
-                }
-            }
-
-            function init() {
-                particles = configs.map(function (particleConfig) {
-                    var scene = CreateScene(particleConfig.scene)
-                    var particles = CreateParticles(scene, particleConfig.particles)
-                    return Animate(scene, particles)
-                })
-                return particles
-            }
-
-            function run() {
-                if (particles.length === 0) {
-                    particles = init()
-                }
-                isRunning = true
-                animate(particles)
-            }
-
-            function stop() {
-                isRunning = false
-                cancelAnimationFrame(rafId)
-            }
-
-            return {
-                init: init,
-                run: run,
-                stop: stop,
-                onScreenSizeChange: function onResize() {
-                    stop()
-                    if (!throttled) {
-                        throttled = true
-                        setTimeout(function () {
-                            particles = init()
-                            run()
-                            throttled = false
-                        }, delay)
-                    }
-                }
-            }
-        }
+    function Animate(scene, particles) {
+      var updatedParticles = [],
+        fpsInterval = scene.fpsInterval,
+        now = performance.now(),
+        then = scene.then,
+        elapsed = now - then,
+        tolerance = 0.1;
+
+      // Just render when we're reaching the configured fps
+      if (elapsed >= scene.fpsInterval - tolerance) {
+        scene.yOffset = getNodeYOffset(scene.anchorNode);
+        scene.then = now - (elapsed % fpsInterval);
+        Render(scene, particles);
+      }
+
+      // Update particle positions for the next render call
+      updatedParticles = particles.map(function doUpdate(p) {
+        return Update(scene, p);
+      });
+
+      // Function to animate the next frame
+      return function nextFrame() {
+        return Animate(scene, updatedParticles);
+      };
+    }
 
+    function CreateScene(cfg) {
+      var canvasId = cfg.canvasId,
+        contentId = cfg.contentId,
+        depth = cfg.depth,
+        fps = cfg.fps;
+
+      var contentNode = document.getElementById(contentId),
+        width = window.innerWidth,
+        fpsInterval = 1000 / fps,
+        yOffset = 0,
+        canvas = document.getElementById(canvasId),
+        height = getNodeHeight(canvas),
+        ctx = canvas.getContext("2d"),
+        depthScaledHeight = height * (depth + 1);
+
+      ctx.canvas.width = width;
+      ctx.canvas.height = window.innerHeight;
+
+      return {
+        width: width,
+        height: depthScaledHeight,
+        yOffset: yOffset,
+        depthScale: depth,
+        fps: fps,
+        fpsInterval: fpsInterval,
+        then: performance.now(),
+        anchorNode: contentNode,
+        ctx: ctx,
+      };
+    }
 
-        // Default Export
-        return Particles
+    function CreateParticles(scene, cfg) {
+      var density = cfg.density,
+        color = cfg.color,
+        size = cfg.size,
+        speed = cfg.speed,
+        lifespan = cfg.lifespan;
 
-    })()
+      var initAnimValue = randomValue(-1, 1);
 
-    var fgParticleConfig = {
-        scene: {
-            // Id of the canvas to render to
-            canvasId: 'fg-particles',
-            // Id of the content container, we're using it to get the 
-            // rendering height and it's the anchor to get the y offset
-            // to simulate scrolling.
-            contentId: 'content',
-            fps: 24,
-            depth: 2.5,
+      return Array.from(
+        {
+          // length: 1
+          length: calcParticleCount(scene, density),
         },
-        particles: {
-            density: 8,
-            color: 'white',
-            size: 20,
-            speed: 0.7,
-            lifespan: { // in milliseconds
-                min: 3500,
-                max: 7000
-            }
-        }
+        function Particle() {
+          const lifeLength = randomValue(lifespan.min, lifespan.max);
+          return {
+            position: RandomPoint2D(MinMax(0, scene.width - size * 2), MinMax(0, scene.height - size * 2)),
+            direction: RandomPoint2D(MinMax(-speed, speed), MinMax(-speed, speed)),
+            size: {
+              animValue: initAnimValue,
+              scale: size,
+              value: size * initAnimValue,
+              step: 1 / (lifeLength / scene.fps),
+              direction:
+                // 50% Chance for the particle floating in one
+                // direction or the other.
+                randomValue(0, 100) < 50 ? -1 : +1,
+              // Offset is needed for boundary calculation and for
+              // drawing the pixels. We cache it here, to prevent
+              // double calculation of the same value.
+              offset: size * initAnimValue * 0.5,
+            },
+            color,
+          };
+        },
+      );
     }
-    var bgParticleConfig = {
-        scene: {
-            // Id of the canvas to render to
-            canvasId: 'bg-particles',
-            // Id of the content container, we're using it to get the 
-            // rendering height and it's the anchor to get the y offset
-            // to simulate scrolling.
-            contentId: 'content',
-            fps: 16,
-            depth: 0.08,
+
+    //
+    //  Api
+    //
+
+    function Particles(configs) {
+      var particles = [];
+      var isRunning = false;
+      var throttled = false;
+      var delay = 250; // ms
+      var rafId = undefined;
+
+      function animate(rendererList) {
+        if (isRunning) {
+          rafId = requestAnimationFrame(function doRaf() {
+            animate(
+              rendererList.map(function doRender(render) {
+                return render();
+              }),
+            );
+          });
+        }
+      }
+
+      function init() {
+        particles = configs.map(function (particleConfig) {
+          var scene = CreateScene(particleConfig.scene);
+          var particles = CreateParticles(scene, particleConfig.particles);
+          return Animate(scene, particles);
+        });
+        return particles;
+      }
+
+      function run() {
+        if (particles.length === 0) {
+          particles = init();
+        }
+        isRunning = true;
+        animate(particles);
+      }
+
+      function stop() {
+        isRunning = false;
+        cancelAnimationFrame(rafId);
+      }
+
+      return {
+        init: init,
+        run: run,
+        stop: stop,
+        onScreenSizeChange: function onResize() {
+          stop();
+          if (!throttled) {
+            throttled = true;
+            setTimeout(function () {
+              particles = init();
+              run();
+              throttled = false;
+            }, delay);
+          }
         },
-        particles: {
-            density: 110,
-            color: 'white',
-            size: 6,
-            speed: 0.4,
-            lifespan: { // in milliseconds
-                min: 2500,
-                max: 5000
-            }
-        }
+      };
     }
-    var animation = Particles([
-        fgParticleConfig,
-        bgParticleConfig,
-    ])
-    animation.run()
-    window.addEventListener('resize', animation.onScreenSizeChange)
+
+    // Default Export
+    return Particles;
+  })();
+
+  var fgParticleConfig = {
+    scene: {
+      // Id of the canvas to render to
+      canvasId: "fg-particles",
+      // Id of the content container, we're using it to get the
+      // rendering height and it's the anchor to get the y offset
+      // to simulate scrolling.
+      contentId: "content",
+      fps: 24,
+      depth: 2.5,
+    },
+    particles: {
+      density: 8,
+      color: "white",
+      size: 20,
+      speed: 0.7,
+      lifespan: {
+        // in milliseconds
+        min: 3500,
+        max: 7000,
+      },
+    },
+  };
+  var bgParticleConfig = {
+    scene: {
+      // Id of the canvas to render to
+      canvasId: "bg-particles",
+      // Id of the content container, we're using it to get the
+      // rendering height and it's the anchor to get the y offset
+      // to simulate scrolling.
+      contentId: "content",
+      fps: 16,
+      depth: 0.08,
+    },
+    particles: {
+      density: 110,
+      color: "white",
+      size: 6,
+      speed: 0.4,
+      lifespan: {
+        // in milliseconds
+        min: 2500,
+        max: 5000,
+      },
+    },
+  };
+  var animation = Particles([fgParticleConfig, bgParticleConfig]);
+  animation.run();
+  window.addEventListener("resize", animation.onScreenSizeChange);
 });
diff --git a/src/plainui/static/plainui/js/modal.js b/src/plainui/static/plainui/js/modal.js
index a27bc6259cffb46fa7932882ee751c6705dd36ee..05318baddd8514198cfd88a7456d599d902e9f64 100644
--- a/src/plainui/static/plainui/js/modal.js
+++ b/src/plainui/static/plainui/js/modal.js
@@ -1,45 +1,45 @@
 // wait until document is loaded
 var fpReady = (callback) => {
-    if (document.readyState != "loading") callback();
-    else document.addEventListener("DOMContentLoaded", callback);
-}
+  if (document.readyState != "loading") callback();
+  else document.addEventListener("DOMContentLoaded", callback);
+};
 
 fpReady(() => {
-    // one click listener to rule them all :)
-    document.addEventListener('click', function onclicked(e) {
-        documentClicked(e);
-    });
-    // check for the URL hash and open modal if hash is present
-    if (window.location.hash) {
-        showModal2(window.location.hash.substr(1));
-    }
+  // one click listener to rule them all :)
+  document.addEventListener("click", function onclicked(e) {
+    documentClicked(e);
+  });
+  // check for the URL hash and open modal if hash is present
+  if (window.location.hash) {
+    showModal2(window.location.hash.substr(1));
+  }
 });
 
-
 function documentClicked(e) {
-
-    if (e.target.dataset.eventid) {
-        e.preventDefault();
-        showModal2(e.target.dataset.eventid);
-    }
-
-    if (e.target.classList.contains('modal-close')) {
-        e.preventDefault();
-        removeFahrplanModal();
-    }
+  if (e.target.dataset.eventid) {
+    e.preventDefault();
+    showModal2(e.target.dataset.eventid);
+  }
+
+  if (e.target.classList.contains("modal-close")) {
+    e.preventDefault();
+    removeFahrplanModal();
+  }
 }
 
 function showModal2(event_id) {
-    let data_el = document.getElementById(event_id);
-    if (!data_el) {
-        return;
-    }
-    let data = JSON.parse(data_el.innerText);
-    if (!data) { return; }
-    let modal = document.createElement('div');
-    window.location.hash = event_id;
-    modal.classList.add('rc3-fahrplan__modal-box');
-    modal.innerHTML = `
+  let data_el = document.getElementById(event_id);
+  if (!data_el) {
+    return;
+  }
+  let data = JSON.parse(data_el.innerText);
+  if (!data) {
+    return;
+  }
+  let modal = document.createElement("div");
+  window.location.hash = event_id;
+  modal.classList.add("rc3-fahrplan__modal-box");
+  modal.innerHTML = `
     <div class="modal show modal-close" tabindex="-1" style="display:block;">
         <div class="modal-dialog modal-lg">
           <div class="modal-content border p-5 rc3-fahrplan__modal-content">
@@ -55,11 +55,12 @@ function showModal2(event_id) {
         </div>
     </div>
     `;
-    document.body.appendChild(modal);
+  document.body.appendChild(modal);
 }
 
 function eventContent(data) {
-    let content = `
+  let content =
+    `
     <dl class="rc3-fahrplan__modal-data">
         <dt>Start:</dt>
         <dd class=""><time datetime="${data.schedule_start}">${data.schedule_start}</time></dd>
@@ -70,9 +71,13 @@ function eventContent(data) {
         <dt>Room:</dt>
         <dd class="">${data.room_name}</dd>
 
-    ` +  (data.track_name && data.track_name != 'None' ? `
+    ` +
+    (data.track_name && data.track_name != "None"
+      ? `
         <dt>Track:</dt>
-        <dd class="">${data.track_name}</dd>` : '') + `
+        <dd class="">${data.track_name}</dd>`
+      : "") +
+    `
 
         <dt>Language:</dt>
         <dd class="">${data.language}</dd>
@@ -87,33 +92,32 @@ function eventContent(data) {
             <a class="a" href="https://media.ccc.de/v/${data.id}" title="recording" target="_blank">recording</a>
         </dd>
         `;
-    if (data.link != null) {
-        content += `
+  if (data.link != null) {
+    content += `
         <dt>Origin:</dt>
         <dd class=""><a class="a" href="${data.link}" alt="Details" target="_blank">${data.link}</a></dd>`;
-    }
+  }
 
-    content += `
+  content += `
     </dl>`;
 
-    if (data.abstract) {
-        content += `
+  if (data.abstract) {
+    content += `
         <hr class="my-4">
         <p>${data.abstract}</p>`;
-    }
+  }
 
-    content += `
+  content += `
         <hr class="my-4">
         <div class="rc3-markdown">${data.description_html}</div>`;
 
-    return content;
+  return content;
 }
 
 function removeFahrplanModal() {
-    window.location.hash = '_';
-    document.querySelectorAll('.rc3-fahrplan__modal-box').forEach(function (el) {
-        console.log('should remove');
-        el.remove();
-    });
+  window.location.hash = "_";
+  document.querySelectorAll(".rc3-fahrplan__modal-box").forEach(function (el) {
+    console.log("should remove");
+    el.remove();
+  });
 }
-
diff --git a/src/plainui/static/plainui/js/tools.js b/src/plainui/static/plainui/js/tools.js
index 5580500b19a3837b5580b90558fb43029ad9d51e..8b9b968976f8aed37ef7ef88aa0d98b6eaf1b082 100644
--- a/src/plainui/static/plainui/js/tools.js
+++ b/src/plainui/static/plainui/js/tools.js
@@ -1,42 +1,41 @@
 // wait until document is loaded
 var docReady = (callback) => {
-    if (document.readyState != "loading") callback();
-    else document.addEventListener("DOMContentLoaded", callback);
-}
+  if (document.readyState != "loading") callback();
+  else document.addEventListener("DOMContentLoaded", callback);
+};
 
 docReady(() => {
-    // one click listener to rule them all :)
-    document.addEventListener('click',function onclicked(e){
-        documentClicked(e);
-    });
+  // one click listener to rule them all :)
+  document.addEventListener("click", function onclicked(e) {
+    documentClicked(e);
+  });
 
-    // hide all possible toggle targets
-    document.querySelectorAll('[data-rc3-tog-target]').forEach(function(target){
-        target.classList.add('d-none');
-    });
+  // hide all possible toggle targets
+  document.querySelectorAll("[data-rc3-tog-target]").forEach(function (target) {
+    target.classList.add("d-none");
+  });
 
-    // show all toggle buttons
-    document.querySelectorAll('[data-rc3-tog-btn]').forEach(function(target){
-        target.classList.remove('d-none');
-    });
+  // show all toggle buttons
+  document.querySelectorAll("[data-rc3-tog-btn]").forEach(function (target) {
+    target.classList.remove("d-none");
+  });
 });
 
 // one click listener to rule them all
 function documentClicked(e) {
-
-    // toggle visibility of buttons
-    if (e.target.hasAttribute('data-rc3-tog-btn') && e.target.hasAttribute('data-rc3-tog-stat') ) {
-        e.preventDefault();
-        if (e.target.dataset.rc3TogStat == 0) {
-            document.querySelectorAll(`[data-rc3-tog-target="${e.target.dataset.rc3TogBtn}"]`).forEach(function(target){
-                target.classList.remove('d-none');
-            });
-            e.target.dataset.rc3TogStat = 1;
-        } else {
-            document.querySelectorAll(`[data-rc3-tog-target="${e.target.dataset.rc3TogBtn}"]`).forEach(function(target){
-                target.classList.add('d-none');
-            });
-            e.target.dataset.rc3TogStat = 0;
-        }
+  // toggle visibility of buttons
+  if (e.target.hasAttribute("data-rc3-tog-btn") && e.target.hasAttribute("data-rc3-tog-stat")) {
+    e.preventDefault();
+    if (e.target.dataset.rc3TogStat == 0) {
+      document.querySelectorAll(`[data-rc3-tog-target="${e.target.dataset.rc3TogBtn}"]`).forEach(function (target) {
+        target.classList.remove("d-none");
+      });
+      e.target.dataset.rc3TogStat = 1;
+    } else {
+      document.querySelectorAll(`[data-rc3-tog-target="${e.target.dataset.rc3TogBtn}"]`).forEach(function (target) {
+        target.classList.add("d-none");
+      });
+      e.target.dataset.rc3TogStat = 0;
     }
+  }
 }
diff --git a/src/plainui/styles/_bootstrap.scss b/src/plainui/styles/_bootstrap.scss
index f77c39a86f41a2f569446a4aeecfa96ab93efbd7..f8bc99ffd75fecf3e245ebe72d2fbac46ccdd937 100644
--- a/src/plainui/styles/_bootstrap.scss
+++ b/src/plainui/styles/_bootstrap.scss
@@ -3,7 +3,6 @@
 @import "bootstrap/scss/mixins/banner";
 @include bsBanner("");
 
-
 // scss-docs-start import-stack
 // Configuration
 @import "bootstrap/scss/functions";
diff --git a/src/plainui/styles/_fonts.scss b/src/plainui/styles/_fonts.scss
index 6bbae5d70983dc713528e1355b88d52530797c30..6f68e97f2f826a4b6318ba706ebc1124e38018ea 100644
--- a/src/plainui/styles/_fonts.scss
+++ b/src/plainui/styles/_fonts.scss
@@ -1,7 +1,6 @@
 @font-face {
   font-family: "Gabriella";
-  src:
-    url("fonts/GabriellaHeavy.otf") format("opentype");
+  src: url("fonts/GabriellaHeavy.otf") format("opentype");
   font-weight: 400;
 }
 
@@ -21,4 +20,3 @@
     url("fonts/VCROCDFaux.woff2") format("woff2");
   font-weight: 400;
 }
-
diff --git a/src/plainui/styles/_grid.scss b/src/plainui/styles/_grid.scss
index 0757eedc39aa07a3f7d8cbc20db9283ccfad09b7..63fb893ca013b1d2702b2147eac26e0f16d0cac4 100644
--- a/src/plainui/styles/_grid.scss
+++ b/src/plainui/styles/_grid.scss
@@ -1,7 +1,7 @@
 .hub-row {
-    display: flex;
-    flex-direction: column;
-    gap: map-get($spacers, 2);
+  display: flex;
+  flex-direction: column;
+  gap: map-get($spacers, 2);
 }
 
 .hub-row > * {
@@ -15,16 +15,16 @@
 
 /* colum that takes up the remaining space */
 .hub-col-remaining {
-    flex: 1;
+  flex: 1;
 }
 
 @include media-breakpoint-up(lg) {
-    .hub-row {
-        flex-direction: row;
-    }
+  .hub-row {
+    flex-direction: row;
+  }
 
-    /* fixed 325px width column */
-    .hub-col-325px {
-        width: 325px;
-    }
+  /* fixed 325px width column */
+  .hub-col-325px {
+    width: 325px;
+  }
 }
diff --git a/src/plainui/styles/_helpers.scss b/src/plainui/styles/_helpers.scss
index 381053503fe5e722a620a03fddafa3e15038cc11..bc64e56019b1ddd8c51dfc589f2254b02accfc67 100644
--- a/src/plainui/styles/_helpers.scss
+++ b/src/plainui/styles/_helpers.scss
@@ -2,5 +2,5 @@
  * Gets the rgb components from a hex colour.
  */
 @function rgbc($color) {
-    @return red($color) + ", " + green($color) + ", " + blue($color);
+  @return red($color) + ", " + green($color) + ", " + blue($color);
 }
diff --git a/src/plainui/styles/_layout.scss b/src/plainui/styles/_layout.scss
index 80db3d6a8d246146842cc92572c30eabefbc6f10..700695c216ee5d95e27d1a841f645ebcf077229c 100644
--- a/src/plainui/styles/_layout.scss
+++ b/src/plainui/styles/_layout.scss
@@ -52,7 +52,6 @@
   min-width: 0;
 }
 
-
 .hub-vlayout,
 .hub-vlayout-l,
 .hub-hlayout,
@@ -99,7 +98,8 @@
 
 @include media-breakpoint-up("md") {
   .hub-grid-title-buttons {
-    grid-template-areas: "title buttons"
+    grid-template-areas:
+      "title buttons"
       "tags tags";
   }
 
diff --git a/src/plainui/styles/_nav.scss b/src/plainui/styles/_nav.scss
index fe1ab945380e9a9cc87bb225162eb095a1ce4dd2..5a3e9602063258c7b744ef16090a3124032c4648 100644
--- a/src/plainui/styles/_nav.scss
+++ b/src/plainui/styles/_nav.scss
@@ -1,14 +1,14 @@
 .hub-main-navbar {
-    background-color: $body-bg-dark;
-    display: flex;
-    flex-direction: column;
-    height: 100vh;
-    left: -100%;
-    position: fixed;
-    top: $hub-mobile-navbar-height;
-    transition: left 100ms;
-    width: 100%;
-    z-index: 1000;
+  background-color: $body-bg-dark;
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+  left: -100%;
+  position: fixed;
+  top: $hub-mobile-navbar-height;
+  transition: left 100ms;
+  width: 100%;
+  z-index: 1000;
 }
 
 .hub-main-navbar-items {
@@ -16,79 +16,79 @@
 }
 
 .hub-mobile-navbar {
-    background-color: $body-bg-dark;
-    left: 0;
-    padding: 1rem .75rem;
-    position: fixed;
-    top: 0;
-    z-index: 1100;
-    width: 100%;
+  background-color: $body-bg-dark;
+  left: 0;
+  padding: 1rem 0.75rem;
+  position: fixed;
+  top: 0;
+  z-index: 1100;
+  width: 100%;
 }
 
 .hub-mobile-nav-title {
-    font-size: 1.9375rem;
-    font-weight: 200;
-    line-height: 2.5225rem;
-    margin-bottom: 0;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    white-space: nowrap;
+  font-size: 1.9375rem;
+  font-weight: 200;
+  line-height: 2.5225rem;
+  margin-bottom: 0;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
 }
 
 .hub-main-navbar__category {
-    color: var(--bs-secondary-color);
-    font-size: 0.9375rem;
-    font-weight: 300;
-    text-transform: uppercase;
+  color: var(--bs-secondary-color);
+  font-size: 0.9375rem;
+  font-weight: 300;
+  text-transform: uppercase;
 }
 
 .hub-main-navbar__items {
-    list-style: none;
-    margin-bottom: map-get($spacers, 4);
-    padding: 0;
+  list-style: none;
+  margin-bottom: map-get($spacers, 4);
+  padding: 0;
 }
 
 .hub-main-navbar__item {
-    align-items: center;
-    color: var(--bs-secondary-color) !important;
-    display: flex;
-    font-size: 0.9375rem;
-    gap: map-get($spacers, 2);
-    padding: 6px map-get($spacers, 2) 6px 0;
-    text-decoration: none;
+  align-items: center;
+  color: var(--bs-secondary-color) !important;
+  display: flex;
+  font-size: 0.9375rem;
+  gap: map-get($spacers, 2);
+  padding: 6px map-get($spacers, 2) 6px 0;
+  text-decoration: none;
 }
 
 .hub-main-navbar__item:hover {
-    color: var(--bs-tertiary-color) !important;
+  color: var(--bs-tertiary-color) !important;
 }
 
 .hub-main-navbar__item--active {
-    color: var(--bs-tertiary-color) !important;
-    font-weight: 700;
+  color: var(--bs-tertiary-color) !important;
+  font-weight: 700;
 }
 
 #hub-mobile-nav-toggle:checked ~ #hub-main-navbar {
-    left: 0;
+  left: 0;
 }
 
 .hub-mobile-nav-badge {
-    position: absolute;
-    transform: translate(25%, -25%);
-    top: 8px;
-    right: 8px;
+  position: absolute;
+  transform: translate(25%, -25%);
+  top: 8px;
+  right: 8px;
 }
 
 @include media-breakpoint-up(md) {
-    .hub-mobile-navbar {
-        display: none;
-    }
+  .hub-mobile-navbar {
+    display: none;
+  }
 
-    #hub-main-navbar {
-        position: static;
-        width: 300px;
-    }
+  #hub-main-navbar {
+    position: static;
+    width: 300px;
+  }
 
-    .hub-navbar-logo {
-        display: block;
-    }
+  .hub-navbar-logo {
+    display: block;
+  }
 }
diff --git a/src/plainui/styles/_typography.scss b/src/plainui/styles/_typography.scss
index 96555514b333b67c64910638dd50739565952bdb..4b12f173d339cf68c46b3c02b27b54d3cb7c0ed5 100644
--- a/src/plainui/styles/_typography.scss
+++ b/src/plainui/styles/_typography.scss
@@ -2,17 +2,17 @@
 
 .hub-head-category,
 .hub-head-main {
-    margin-bottom: 0;
+  margin-bottom: 0;
 }
 
 .hub-text {
-    font-size: .9375rem;
-    font-weight: 400
+  font-size: 0.9375rem;
+  font-weight: 400;
 }
 
 .hub-section-title {
-    color: var(--bs-secondary-color);
-    font: $hub-head-category-font;
+  color: var(--bs-secondary-color);
+  font: $hub-head-category-font;
 }
 
 .hub-text-list-item-title {
diff --git a/src/plainui/styles/_util-classes.scss b/src/plainui/styles/_util-classes.scss
index fd25e895eef145e47cc33096d314c22f83ac5bd0..661824296bd13485b6e9db7ab3de301da825e464 100644
--- a/src/plainui/styles/_util-classes.scss
+++ b/src/plainui/styles/_util-classes.scss
@@ -1,67 +1,67 @@
 :root {
-    --headings-font-family: #{$headings-font-family};
+  --headings-font-family: #{$headings-font-family};
 }
 
 ::selection {
-    color: $gray-900;
-    background: $primary;
+  color: $gray-900;
+  background: $primary;
 }
 
 /* Works on Firefox */
 * {
-    scrollbar-width: thin;
-    scrollbar-color: $primary transparent;
+  scrollbar-width: thin;
+  scrollbar-color: $primary transparent;
 }
 
 /* Works on Chrome, Edge, and Safari */
 *::-webkit-scrollbar {
-    width: $spacer * 0.75;
+  width: $spacer * 0.75;
 }
 
 *::-webkit-scrollbar-track {
-    background: $secondary;
+  background: $secondary;
 }
 
 *::-webkit-scrollbar-thumb {
-    background-color: $primary;
+  background-color: $primary;
 }
 
 html {
-    scroll-behavior: smooth;
+  scroll-behavior: smooth;
 }
 
 body {
-    overflow-x: hidden;
-    position: relative;
+  overflow-x: hidden;
+  position: relative;
 }
 
 .a {
+  text-decoration: underline;
+  color: $primary;
+
+  &:hover,
+  &:focus {
     text-decoration: underline;
     color: $primary;
+    text-shadow: $btn-hover-text-shadow;
+  }
 
-    &:hover,
-    &:focus {
-        text-decoration: underline;
-        color: $primary;
-        text-shadow: $btn-hover-text-shadow;
-    }
-
-    &-bold {
-        font-weight: 700;
-    }
+  &-bold {
+    font-weight: 700;
+  }
 
-    &-ital {
-        font-style: italic;
-    }
+  &-ital {
+    font-style: italic;
+  }
 }
 
 .fw-bold {
-    font-weight: 700;
+  font-weight: 700;
 }
 
 // overwrite bootstrap styles
 ul {
-    list-style: square;
+  list-style: square;
 }
 
 h1,
@@ -76,698 +76,699 @@ h5,
 .h5,
 h6,
 .h6 {
-    letter-spacing: $letter-spacing;
-    text-transform: lowercase;
-    word-spacing: $word-spacing;
+  letter-spacing: $letter-spacing;
+  text-transform: lowercase;
+  word-spacing: $word-spacing;
 }
 
 .shadow-darkmorphism {
-    box-shadow: $box-shadow-morphism;
+  box-shadow: $box-shadow-morphism;
 }
 
 #footer .nav-link {
-    font-family: $headings-font-family;
-    font-weight: 600;
-    font-size: 1rem;
-    letter-spacing: $letter-spacing;
+  font-family: $headings-font-family;
+  font-weight: 600;
+  font-size: 1rem;
+  letter-spacing: $letter-spacing;
 }
 
 .bg-transparent {
-    backdrop-filter: none;
+  backdrop-filter: none;
 }
 
 .fs-medium {
-    font-size: $medium-font-size;
+  font-size: $medium-font-size;
 }
 
 .font-headings {
-    font-family: $headings-font-family;
-    font-weight: 600;
+  font-family: $headings-font-family;
+  font-weight: 600;
 }
 
 .font-sans-serif {
-    font-family: $font-family-sans-serif;
+  font-family: $font-family-sans-serif;
 }
 
 h6,
 .h6,
 .text-transform-none {
-    text-transform: none;
+  text-transform: none;
 }
 
 .mw-664 {
-    max-width: 41.5rem;
+  max-width: 41.5rem;
 }
 
 .mw-810 {
-    max-width: 50.625rem;
+  max-width: 50.625rem;
 }
 
 .external {
-    white-space: nowrap;
-    font-weight: 700;
-    font-style: italic;
-
-    // &::after {
-    //     content: "";
-    //     display: inline-block;
-    //     width: $spacer;
-    //     height: $spacer;
-    //     margin-left: map-get($spacers, 1);
-    //     background: currentColor;
-    //     mask-size: contain;
-    //     mask-repeat: no-repeat;
-    //     mask-image: url("img/box-arrow-up-right.svg");
-    //     -webkit-mask-image: url("img/box-arrow-up-right.svg");
-    // }
+  white-space: nowrap;
+  font-weight: 700;
+  font-style: italic;
+
+  // &::after {
+  //     content: "";
+  //     display: inline-block;
+  //     width: $spacer;
+  //     height: $spacer;
+  //     margin-left: map-get($spacers, 1);
+  //     background: currentColor;
+  //     mask-size: contain;
+  //     mask-repeat: no-repeat;
+  //     mask-image: url("img/box-arrow-up-right.svg");
+  //     -webkit-mask-image: url("img/box-arrow-up-right.svg");
+  // }
 }
 
 .grid-list {
-    display: grid;
-    grid-template: auto / auto;
-    grid-gap: 0;
-
-    &__item {
-        display: flex;
-        flex-flow: row nowrap;
-        font-family: $font-family-sans-serif;
-        padding: 0;
-
-        &--title {
-            &::before {
-                content: "//";
-                margin-right: 0.5rem;
-            }
-        }
+  display: grid;
+  grid-template: auto / auto;
+  grid-gap: 0;
 
-        &--text {
-            margin-bottom: map-get($spacers, 3);
-        }
+  &__item {
+    display: flex;
+    flex-flow: row nowrap;
+    font-family: $font-family-sans-serif;
+    padding: 0;
+
+    &--title {
+      &::before {
+        content: "//";
+        margin-right: 0.5rem;
+      }
     }
+
+    &--text {
+      margin-bottom: map-get($spacers, 3);
+    }
+  }
 }
 
 .no-js .d-js-only {
-    display: none !important;
+  display: none !important;
 }
 
 // Basic Bootstrap table - only use the basic table
 // - if you need another configuration update the bootstrap variables
 .table {
-    border-collapse: separate;
-    border-spacing: $spacer * 0.5;
+  border-collapse: separate;
+  border-spacing: $spacer * 0.5;
 
-    thead th {
-        background: $info;
-        font-family: $headings-font-family;
-    }
+  thead th {
+    background: $info;
+    font-family: $headings-font-family;
+  }
 
-    td {
-        box-shadow: $box-shadow-morphism;
-    }
+  td {
+    box-shadow: $box-shadow-morphism;
+  }
 }
 
 @include media-breakpoint-down(sm) {
-    .card-deck {
-        .card {
-            margin-bottom: map-get($spacers, 3);
-        }
+  .card-deck {
+    .card {
+      margin-bottom: map-get($spacers, 3);
     }
+  }
 }
 
 .card-footer {
-    border-top: none;
-    background-color: transparent;
+  border-top: none;
+  background-color: transparent;
 }
 
 .form-check {
-    padding-left: 1.75rem;
+  padding-left: 1.75rem;
 
-    &-input {
-        position: absolute;
-        top: 0;
-        left: -9999px;
-        opacity: 0;
+  &-input {
+    position: absolute;
+    top: 0;
+    left: -9999px;
+    opacity: 0;
 
-        &:checked+.form-check-label::after {
-            opacity: 1;
-        }
+    &:checked + .form-check-label::after {
+      opacity: 1;
+    }
 
-        &:focus,
-        &:focus-within {
-            +.form-check-label::before {
-                box-shadow: $input-btn-focus-box-shadow;
-                border-color: #fff;
-            }
-        }
+    &:focus,
+    &:focus-within {
+      + .form-check-label::before {
+        box-shadow: $input-btn-focus-box-shadow;
+        border-color: #fff;
+      }
+    }
 
-        &.is-invalid+.form-check-label::before {
-            border-color: $danger;
-        }
+    &.is-invalid + .form-check-label::before {
+      border-color: $danger;
     }
+  }
 
-    &-label {
-        cursor: pointer;
+  &-label {
+    cursor: pointer;
 
-        &::before {
-            content: "";
-            display: block;
-            position: absolute;
-            top: 0;
-            left: 0;
-            border: 1px solid $primary;
-            width: 1.25rem;
-            height: 1.25rem;
-            transition: border-color .3s linear, box-shadow .3s linear;
-        }
+    &::before {
+      content: "";
+      display: block;
+      position: absolute;
+      top: 0;
+      left: 0;
+      border: 1px solid $primary;
+      width: 1.25rem;
+      height: 1.25rem;
+      transition:
+        border-color 0.3s linear,
+        box-shadow 0.3s linear;
+    }
 
-        &::after {
-            content: "";
-            display: block;
-            position: absolute;
-            top: 0.25rem;
-            left: 0.25rem;
-            background: $primary;
-            width: 0.75rem;
-            height: 0.75rem;
-            opacity: 0;
-            transition: opacity .3s linear;
-        }
+    &::after {
+      content: "";
+      display: block;
+      position: absolute;
+      top: 0.25rem;
+      left: 0.25rem;
+      background: $primary;
+      width: 0.75rem;
+      height: 0.75rem;
+      opacity: 0;
+      transition: opacity 0.3s linear;
     }
+  }
 }
 
-
-
 .form-control-selectbox {
-    position: relative;
-    color: $dark;
+  position: relative;
+  color: $dark;
 
-    &::before {
-        content: "";
-        display: block;
-        position: absolute;
-        top: 1px;
-        right: 1px;
-        width: 2.5rem;
-        height: calc(100% - 2px);
-        background: $info;
-        color: $dark;
-    }
+  &::before {
+    content: "";
+    display: block;
+    position: absolute;
+    top: 1px;
+    right: 1px;
+    width: 2.5rem;
+    height: calc(100% - 2px);
+    background: $info;
+    color: $dark;
+  }
 
-    &__icon {
-        position: absolute;
-        right: 10px;
-        top: 50%;
-        transform: translate(0, -50%);
-        display: block;
-        width: 1.25rem;
-        height: 1.25rem;
-        color: $dark;
-    }
+  &__icon {
+    position: absolute;
+    right: 10px;
+    top: 50%;
+    transform: translate(0, -50%);
+    display: block;
+    width: 1.25rem;
+    height: 1.25rem;
+    color: $dark;
+  }
 }
 
 .form-control {
-    background-color: transparent;
+  background-color: transparent;
 
-    >option {
-        background-color: #000;
-        color: $primary;
-    }
+  > option {
+    background-color: #000;
+    color: $primary;
+  }
 
-    &:focus {
-        border-color: rgb(255, 255, 255, 1);
-        background-color: transparent;
-    }
+  &:focus {
+    border-color: rgb(255, 255, 255, 1);
+    background-color: transparent;
+  }
 }
 
 .hub-spacer {
-    border: 1px solid transparent;
-    margin-top: 2rem;
-    margin-bottom: 2rem;
+  border: 1px solid transparent;
+  margin-top: 2rem;
+  margin-bottom: 2rem;
 }
 
 // here comes the eyecandy
 
 .hub-bg-L04 {
-    z-index: 0;
+  z-index: 0;
 }
 
 .hub-bg {
-    display: none;
-    visibility: hidden;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    position: fixed;
-    background-repeat: no-repeat;
-    background-size: cover;
-    background-color: transparent;
-    pointer-events: none;
-    background-attachment: fixed;
+  display: none;
+  visibility: hidden;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  position: fixed;
+  background-repeat: no-repeat;
+  background-size: cover;
+  background-color: transparent;
+  pointer-events: none;
+  background-attachment: fixed;
 }
 
 .free .hub-bg-L10 {
-    display: block;
-    visibility: visible;
+  display: block;
+  visibility: visible;
 
-    z-index: -10;
-    background-image: url($dark-bg-land);
+  z-index: -10;
+  background-image: url($dark-bg-land);
 
-    @media screen and (orientation:portrait) {
-        background-image: url($dark-bg-port);
-    }
+  @media screen and (orientation: portrait) {
+    background-image: url($dark-bg-port);
+  }
 }
 
 .eyecandy {
-    .hub-bg {
-        display: block;
-        visibility: visible;
+  .hub-bg {
+    display: block;
+    visibility: visible;
 
-        &-L03 {
-            z-index: 3;
-            background-image: url('img/03_Vignette/RC3_vignette.png');
-            background-size: 100% 100%;
-        }
+    &-L03 {
+      z-index: 3;
+      background-image: url("img/03_Vignette/RC3_vignette.png");
+      background-size: 100% 100%;
+    }
 
-        &-L07 {
-            z-index: -7;
-            background-image: url('img/07_Grid/07_Grid.png');
-            background-size: 100% 100%;
-        }
+    &-L07 {
+      z-index: -7;
+      background-image: url("img/07_Grid/07_Grid.png");
+      background-size: 100% 100%;
+    }
 
-        &-L08 {
-            z-index: -8;
-            background-image: url('img/08_VCR_Overlay/08_VCR_Overlay.png');
-            background-size: 100% 100%;
-        }
+    &-L08 {
+      z-index: -8;
+      background-image: url("img/08_VCR_Overlay/08_VCR_Overlay.png");
+      background-size: 100% 100%;
+    }
 
-        &-L09 {
-            z-index: -9;
-            background-image: linear-gradient(to bottom right, $L09-bd-start, $L09-bd-end);
-            mix-blend-mode: color;
-        }
+    &-L09 {
+      z-index: -9;
+      background-image: linear-gradient(to bottom right, $L09-bd-start, $L09-bd-end);
+      mix-blend-mode: color;
+    }
 
-        &-L10 {
-            z-index: -10;
-            background-image: url($L10-bg-land);
+    &-L10 {
+      z-index: -10;
+      background-image: url($L10-bg-land);
 
-            @media screen and (orientation:portrait) {
-                background-image: url($L10-bg-port);
-            }
-        }
+      @media screen and (orientation: portrait) {
+        background-image: url($L10-bg-port);
+      }
     }
+  }
 
-    .hub-spacer {
-        display: block;
-        border: 0px;
-        height: 120px;
-        width: 100%;
-        background-repeat: no-repeat;
-        background-position: center;
-        background-size: contain;
-        margin-top: 2rem;
-        margin-bottom: 2rem;
+  .hub-spacer {
+    display: block;
+    border: 0px;
+    height: 120px;
+    width: 100%;
+    background-repeat: no-repeat;
+    background-position: center;
+    background-size: contain;
+    margin-top: 2rem;
+    margin-bottom: 2rem;
 
-        &:nth-of-type(4n+1) {
-            background-image: url($icon-1);
-        }
+    &:nth-of-type(4n + 1) {
+      background-image: url($icon-1);
+    }
 
-        &:nth-of-type(4n+2) {
-            background-image: url($icon-2);
-        }
+    &:nth-of-type(4n + 2) {
+      background-image: url($icon-2);
+    }
 
-        &:nth-of-type(4n+3) {
-            background-image: url($icon-3);
-        }
+    &:nth-of-type(4n + 3) {
+      background-image: url($icon-3);
+    }
 
-        &:nth-of-type(4n+4) {
-            background-image: url($icon-4);
-        }
+    &:nth-of-type(4n + 4) {
+      background-image: url($icon-4);
     }
+  }
 }
 
 .hub-spacer {
-    border: 1px solid transparent;
-    margin-top: 2rem;
-    margin-bottom: 2rem;
+  border: 1px solid transparent;
+  margin-top: 2rem;
+  margin-bottom: 2rem;
 }
 
 // here comes the eyecandy
 
 .hub-bg-L04 {
-    z-index: 0;
+  z-index: 0;
 }
 
 .hub-bg {
-    display: none;
-    visibility: hidden;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    position: fixed;
-    background-repeat: no-repeat;
-    background-size: cover;
-    background-color: transparent;
-    pointer-events: none;
+  display: none;
+  visibility: hidden;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  position: fixed;
+  background-repeat: no-repeat;
+  background-size: cover;
+  background-color: transparent;
+  pointer-events: none;
 }
 
 .free .hub-bg-L10 {
-    display: block;
-    visibility: visible;
+  display: block;
+  visibility: visible;
 
-    z-index: -10;
-    background-image: url($dark-bg-land);
+  z-index: -10;
+  background-image: url($dark-bg-land);
 
-    @media screen and (orientation:portrait) {
-        background-image: url($dark-bg-port);
-    }
+  @media screen and (orientation: portrait) {
+    background-image: url($dark-bg-port);
+  }
 }
 
 .eyecandy {
-    .hub-bg {
-        display: block;
-        visibility: visible;
+  .hub-bg {
+    display: block;
+    visibility: visible;
 
-        &-L03 {
-            z-index: 3;
-            background-image: url('img/03_Vignette/RC3_vignette.png');
-            background-size: 100% 100%;
-        }
+    &-L03 {
+      z-index: 3;
+      background-image: url("img/03_Vignette/RC3_vignette.png");
+      background-size: 100% 100%;
+    }
 
-        &-L07 {
-            z-index: -7;
-            background-image: url('img/07_Grid/07_Grid.png');
-            background-size: 100% 100%;
-        }
+    &-L07 {
+      z-index: -7;
+      background-image: url("img/07_Grid/07_Grid.png");
+      background-size: 100% 100%;
+    }
 
-        &-L08 {
-            z-index: -8;
-            background-image: url('img/08_VCR_Overlay/08_VCR_Overlay.png');
-            background-size: 100% 100%;
-        }
+    &-L08 {
+      z-index: -8;
+      background-image: url("img/08_VCR_Overlay/08_VCR_Overlay.png");
+      background-size: 100% 100%;
+    }
 
-        &-L09 {
-            z-index: -9;
-            background-image: linear-gradient(to bottom right, $L09-bd-start, $L09-bd-end);
-            mix-blend-mode: color;
-            position: absolute;
-            background-attachment: scroll;
-        }
+    &-L09 {
+      z-index: -9;
+      background-image: linear-gradient(to bottom right, $L09-bd-start, $L09-bd-end);
+      mix-blend-mode: color;
+      position: absolute;
+      background-attachment: scroll;
+    }
 
-        &-L10 {
-            z-index: -10;
-            background-image: url($L10-bg-land);
+    &-L10 {
+      z-index: -10;
+      background-image: url($L10-bg-land);
 
-            @media screen and (orientation:portrait) {
-                background-image: url($L10-bg-port);
-            }
-        }
+      @media screen and (orientation: portrait) {
+        background-image: url($L10-bg-port);
+      }
     }
+  }
 
-    .hub-spacer {
-        display: block;
-        border: 0px;
-        height: 120px;
-        width: 100%;
-        background-repeat: no-repeat;
-        background-position: center;
-        background-size: contain;
-        margin-top: 2rem;
-        margin-bottom: 2rem;
+  .hub-spacer {
+    display: block;
+    border: 0px;
+    height: 120px;
+    width: 100%;
+    background-repeat: no-repeat;
+    background-position: center;
+    background-size: contain;
+    margin-top: 2rem;
+    margin-bottom: 2rem;
 
-        &:nth-of-type(4n+1) {
-            background-image: url($icon-1);
-        }
+    &:nth-of-type(4n + 1) {
+      background-image: url($icon-1);
+    }
 
-        &:nth-of-type(4n+2) {
-            background-image: url($icon-2);
-        }
+    &:nth-of-type(4n + 2) {
+      background-image: url($icon-2);
+    }
 
-        &:nth-of-type(4n+3) {
-            background-image: url($icon-3);
-        }
+    &:nth-of-type(4n + 3) {
+      background-image: url($icon-3);
+    }
 
-        &:nth-of-type(4n+4) {
-            background-image: url($icon-4);
-        }
+    &:nth-of-type(4n + 4) {
+      background-image: url($icon-4);
     }
+  }
 }
 
-.hub-bg-L01, .hub-bg-L06 {
-    display: none;
-    visibility: hidden;
+.hub-bg-L01,
+.hub-bg-L06 {
+  display: none;
+  visibility: hidden;
 }
 
 .eyecandy-deluxe {
+  .hub-main {
+    -webkit-mask-position: top center;
+    -webkit-mask-image: none;
+    -webkit-mask-origin: margin-box;
+    -webkit-mask-repeat: no-repeat;
+    -webkit-mask-mode: alpha;
+    mask-position: top center;
+    mask-image: none;
+    mask-origin: margin-box;
+    mask-repeat: no-repeat;
+    mask-mode: alpha;
+  }
+
+  .hub-header {
+    position: sticky;
+    top: 0;
+  }
 
-    .hub-main {
-        -webkit-mask-position: top center;
-        -webkit-mask-image: none;
-        -webkit-mask-origin: margin-box;
-        -webkit-mask-repeat: no-repeat;
-        -webkit-mask-mode: alpha;
-        mask-position: top center;
-        mask-image: none;
-        mask-origin: margin-box;
-        mask-repeat: no-repeat;
-        mask-mode: alpha;
+  .hub-logo img {
+    content: url("img/02a_Logo_web_400px_ani.gif");
+  }
+
+  .hub-bg {
+    display: block;
+    visibility: visible;
+
+    &-L01,
+    &-L06 {
+      display: block;
+      visibility: visible;
+      width: 100%;
+      height: 100vh;
+      background-size: 100% 100%;
+      background-repeat: no-repeat;
+      background-position: center center;
+      content: "";
+      display: block;
+      visibility: visible;
+      position: fixed;
+      top: 0;
+      right: 0;
+      left: 0;
+      bottom: 0;
+      pointer-events: none;
+    }
+
+    &-L01 {
+      z-index: 20;
+      opacity: 0.2;
+      filter: blur(1px);
     }
 
-    .hub-header {
-        position: sticky;
-        top: 0;
+    &-L06 {
+      z-index: -6;
+      opacity: 0.35;
     }
 
-    .hub-logo img {
-        content: url('img/02a_Logo_web_400px_ani.gif');
+    &-L03 {
+      z-index: 3;
+      background-image: url("img/03_Vignette/RC3_vignette.png");
+      background-size: 100% 100%;
     }
 
-    .hub-bg {
+    &-L05 {
+      z-index: -5;
+      max-width: 1120px;
+      margin: 0 auto;
+      opacity: 0.6;
+
+      &-R,
+      &-L {
         display: block;
-        visibility: visible;
-
-        &-L01, &-L06 {
-            display: block;
-            visibility: visible;
-            width: 100%;
-            height: 100vh;
-            background-size: 100% 100%;
-            background-repeat: no-repeat;
-            background-position: center center;
-            content: "";
-            display: block;
-            visibility: visible;
-            position: fixed;
-            top: 0;
-            right: 0;
-            left: 0;
-            bottom: 0;
-            pointer-events: none;
-        }
+        content: "";
+        position: absolute;
+        background-repeat: no-repeat;
+        background-size: contain;
+        background-position: center;
+        transform: scale(1);
+      }
+
+      &-R {
+        top: 28vh;
 
-        &-L01 {
-            z-index: 20;
-            opacity: 0.2;
-            filter: blur(1px);
+        &.collage-r-1 {
+          background-image: url("img/05_Collage/05_collage_1_bust_vr-goggles_R_halfres_ani_V01.gif");
+          height: 250px;
+          width: 250px;
+          right: -125px;
         }
 
-        &-L06 {
-            z-index: -6;
-            opacity: 0.35;
+        &.collage-r-2 {
+          background-image: url("img/05_Collage/05_Collage_2_robothand_nib_R_halfres_ani_V01.gif");
+          height: 200px;
+          width: 300px;
+          right: -150px;
         }
 
-        &-L03 {
-            z-index: 3;
-            background-image: url('img/03_Vignette/RC3_vignette.png');
-            background-size: 100% 100%;
+        &.collage-r-3 {
+          background-image: url("img/05_Collage/05_Collage_3_baby_ethernet_R_halfres_ani_V01.gif");
+          height: 300px;
+          width: 300px;
+          right: -150px;
         }
 
-        &-L05 {
-            z-index: -5;
-            max-width: 1120px;
-            margin: 0 auto;
-            opacity: 0.6;
-
-            &-R,
-            &-L {
-                display: block;
-                content: "";
-                position: absolute;
-                background-repeat: no-repeat;
-                background-size: contain;
-                background-position: center;
-                transform: scale(1);
-            }
-
-            &-R {
-                top: 28vh;
-
-                &.collage-r-1 {
-                    background-image: url('img/05_Collage/05_collage_1_bust_vr-goggles_R_halfres_ani_V01.gif');
-                    height: 250px;
-                    width: 250px;
-                    right: -125px;
-                }
-
-                &.collage-r-2 {
-                    background-image: url('img/05_Collage/05_Collage_2_robothand_nib_R_halfres_ani_V01.gif');
-                    height: 200px;
-                    width: 300px;
-                    right: -150px;
-                }
-
-                &.collage-r-3 {
-                    background-image: url('img/05_Collage/05_Collage_3_baby_ethernet_R_halfres_ani_V01.gif');
-                    height: 300px;
-                    width: 300px;
-                    right: -150px;
-                }
-
-                &.collage-r-4 {
-                    background-image: url('img/05_Collage/05_Collage_4_sunflower_bitcoin_R_halfres_ani_V01.gif');
-                    height: 450px;
-                    width: 350px;
-                    right: -150px;
-                }
-
-                &.collage-r-5 {
-                    background-image: url('img/05_Collage/05_Collage_7_bird_cam_R_halfres_ani_V01.gif');
-                    height: 300px;
-                    width: 600px;
-                    right: -300px;
-                }
-
-                &.collage-r-6 {
-                    background-image: url('img/05_Collage/05_Collage_6_astronaut_c64_R_halfres_ani_V01.gif');
-                    height: 500px;
-                    width: 300px;
-                    right: -150px;
-                }
-
-                &.collage-r-7 {
-                    background-image: url('img/05_Collage/05_Collage_5_smartphone_tunnel_halfres_ani_V01.gif');
-                    height: 350px;
-                    width: 250px;
-                    right: -125px;
-                }
-            }
-
-            &-L {
-                left: 0;
-                bottom: -1vh;
-
-                &.collage-l-1 {
-                    background-image: url('img/05_Collage/05_Collage_5_smartphone_tunnel_halfres_ani_V01.gif');
-                    height: 350px;
-                    width: 250px;
-                    left: -125px;
-                }
-
-                &.collage-l-2 {
-                    background-image: url('img/05_Collage/05_collage_1_bust_vr-goggles_L_halfres_ani_V01.gif');
-                    height: 250px;
-                    width: 250px;
-                    left: -125px;
-                }
-
-                &.collage-l-3 {
-                    background-image: url('img/05_Collage/05_Collage_2_robothand_nib_L_halfres_ani_V01.gif');
-                    height: 200px;
-                    width: 300px;
-                    left: -150px;
-                }
-
-                &.collage-l-4 {
-                    background-image: url('img/05_Collage/05_Collage_3_baby_ethernet_L_halfres_ani_V01.gif');
-                    height: 300px;
-                    width: 300px;
-                    left: -150px;
-                }
-
-                &.collage-l-5 {
-                    background-image: url('img/05_Collage/05_Collage_6_astronaut_c64_L_halfres_ani_V01.gif');
-                    height: 500px;
-                    width: 300px;
-                    left: -150px;
-                }
-
-                &.collage-l-6 {
-                    background-image: url('img/05_Collage/05_Collage_7_bird_cam_L_halfres_ani_V01.gif');
-                    height: 300px;
-                    width: 600px;
-                    left: -300px;
-                }
-            }
+        &.collage-r-4 {
+          background-image: url("img/05_Collage/05_Collage_4_sunflower_bitcoin_R_halfres_ani_V01.gif");
+          height: 450px;
+          width: 350px;
+          right: -150px;
         }
 
-        &-L07 {
-            z-index: -7;
-            background-image: url('img/07_Grid/07_Grid.png');
-            background-size: 100% 100%;
+        &.collage-r-5 {
+          background-image: url("img/05_Collage/05_Collage_7_bird_cam_R_halfres_ani_V01.gif");
+          height: 300px;
+          width: 600px;
+          right: -300px;
         }
 
-        &-L08 {
-            z-index: -8;
-            background-image: url('img/08_VCR_Overlay/08_VCR_Overlay.png');
-            background-size: 100% 100%;
+        &.collage-r-6 {
+          background-image: url("img/05_Collage/05_Collage_6_astronaut_c64_R_halfres_ani_V01.gif");
+          height: 500px;
+          width: 300px;
+          right: -150px;
         }
 
-        &-L09 {
-            z-index: -9;
-            background-image: linear-gradient(to bottom right, $L09-bd-start, $L09-bd-end);
-            mix-blend-mode: color;
-            position: absolute;
-            background-attachment: scroll;
+        &.collage-r-7 {
+          background-image: url("img/05_Collage/05_Collage_5_smartphone_tunnel_halfres_ani_V01.gif");
+          height: 350px;
+          width: 250px;
+          right: -125px;
         }
+      }
 
-        &-L10 {
-            background-attachment: initial;
-            background-position-y: 0;
-            top: 0;
-            position: fixed;
-            height: 105%;
-            width: 100%;
-            z-index: -10;
-            background-image: url($L10-bg-land);
-
-            @media screen and (orientation:portrait) {
-                background-image: url($L10-bg-port);
-            }
+      &-L {
+        left: 0;
+        bottom: -1vh;
+
+        &.collage-l-1 {
+          background-image: url("img/05_Collage/05_Collage_5_smartphone_tunnel_halfres_ani_V01.gif");
+          height: 350px;
+          width: 250px;
+          left: -125px;
         }
-    }
 
-    .hub-spacer {
-        display: block;
-        border: 0px;
-        height: 120px;
-        width: 100%;
-        background-repeat: no-repeat;
-        background-position: center;
-        background-size: contain;
-        margin-top: 2rem;
-        margin-bottom: 2rem;
-        opacity: 0.75;
+        &.collage-l-2 {
+          background-image: url("img/05_Collage/05_collage_1_bust_vr-goggles_L_halfres_ani_V01.gif");
+          height: 250px;
+          width: 250px;
+          left: -125px;
+        }
 
-        &:nth-of-type(4n+1) {
-            background-image: url($icon-ani-1);
+        &.collage-l-3 {
+          background-image: url("img/05_Collage/05_Collage_2_robothand_nib_L_halfres_ani_V01.gif");
+          height: 200px;
+          width: 300px;
+          left: -150px;
         }
 
-        &:nth-of-type(4n+2) {
-            background-image: url($icon-ani-2);
+        &.collage-l-4 {
+          background-image: url("img/05_Collage/05_Collage_3_baby_ethernet_L_halfres_ani_V01.gif");
+          height: 300px;
+          width: 300px;
+          left: -150px;
         }
 
-        &:nth-of-type(4n+3) {
-            background-image: url($icon-ani-3);
+        &.collage-l-5 {
+          background-image: url("img/05_Collage/05_Collage_6_astronaut_c64_L_halfres_ani_V01.gif");
+          height: 500px;
+          width: 300px;
+          left: -150px;
         }
 
-        &:nth-of-type(4n+4) {
-            background-image: url($icon-ani-4);
+        &.collage-l-6 {
+          background-image: url("img/05_Collage/05_Collage_7_bird_cam_L_halfres_ani_V01.gif");
+          height: 300px;
+          width: 600px;
+          left: -300px;
         }
+      }
+    }
+
+    &-L07 {
+      z-index: -7;
+      background-image: url("img/07_Grid/07_Grid.png");
+      background-size: 100% 100%;
+    }
+
+    &-L08 {
+      z-index: -8;
+      background-image: url("img/08_VCR_Overlay/08_VCR_Overlay.png");
+      background-size: 100% 100%;
+    }
+
+    &-L09 {
+      z-index: -9;
+      background-image: linear-gradient(to bottom right, $L09-bd-start, $L09-bd-end);
+      mix-blend-mode: color;
+      position: absolute;
+      background-attachment: scroll;
+    }
+
+    &-L10 {
+      background-attachment: initial;
+      background-position-y: 0;
+      top: 0;
+      position: fixed;
+      height: 105%;
+      width: 100%;
+      z-index: -10;
+      background-image: url($L10-bg-land);
+
+      @media screen and (orientation: portrait) {
+        background-image: url($L10-bg-port);
+      }
+    }
+  }
+
+  .hub-spacer {
+    display: block;
+    border: 0px;
+    height: 120px;
+    width: 100%;
+    background-repeat: no-repeat;
+    background-position: center;
+    background-size: contain;
+    margin-top: 2rem;
+    margin-bottom: 2rem;
+    opacity: 0.75;
+
+    &:nth-of-type(4n + 1) {
+      background-image: url($icon-ani-1);
+    }
+
+    &:nth-of-type(4n + 2) {
+      background-image: url($icon-ani-2);
+    }
+
+    &:nth-of-type(4n + 3) {
+      background-image: url($icon-ani-3);
+    }
+
+    &:nth-of-type(4n + 4) {
+      background-image: url($icon-ani-4);
     }
+  }
 }
 
 .aspect-ratio-16by9 {
-    aspect-ratio: 1;
-    object-fit: contain;
+  aspect-ratio: 1;
+  object-fit: contain;
 }
diff --git a/src/plainui/styles/_variables.scss b/src/plainui/styles/_variables.scss
index 4e7d09ccfe072672e84bc562e1d0140a73ea17cc..a1258e88a13793e04ba5370bcbeae2374b33ed09 100644
--- a/src/plainui/styles/_variables.scss
+++ b/src/plainui/styles/_variables.scss
@@ -1,5 +1,20 @@
-$font-family-sans-serif: "Mona Sans", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
-$font-family-monospace: "VCR OCD Faux", SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default;
+$font-family-sans-serif:
+  "Mona Sans",
+  system-ui,
+  -apple-system,
+  "Segoe UI",
+  Roboto,
+  "Helvetica Neue",
+  "Noto Sans",
+  "Liberation Sans",
+  Arial,
+  sans-serif,
+  "Apple Color Emoji",
+  "Segoe UI Emoji",
+  "Segoe UI Symbol",
+  "Noto Color Emoji";
+$font-family-monospace: "VCR OCD Faux", SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
+  monospace !default;
 
 @import "./design/variables";
 
@@ -55,7 +70,7 @@ $signal-secondary-border: $signal-secondary-border-dark;
 $signal-muted-bg: $signal-muted-bg-dark;
 $signal-muted-border: $signal-muted-border-dark;
 $signal-muted-text: $signal-muted-text-dark;
-$alert-border-color: #6D8589;
+$alert-border-color: #6d8589;
 
 $hub-mobile-navbar-height: 73px;
 
diff --git a/src/plainui/styles/components/_avatar.scss b/src/plainui/styles/components/_avatar.scss
index 0a8dc9ede521e72e534da9aaff727fe757805e51..353e543d0e4f59b17e0da63c9afad5cfe0e8417c 100644
--- a/src/plainui/styles/components/_avatar.scss
+++ b/src/plainui/styles/components/_avatar.scss
@@ -1,42 +1,53 @@
 .hub-avatar {
+  padding: 0;
+  margin: 0;
+
+  &__none {
     padding: 0;
     margin: 0;
+    max-width: 100%;
+  }
 
-    &__none {
-        padding: 0;
-        margin: 0;
-        max-width: 100%;
-    }
+  &__wa-stacked {
+    position: relative;
+    width: 32px;
+    height: 32px;
+  }
 
-    &__wa-stacked {
-        position: relative;
-        width: 32px;
-        height: 32px;
-    }
+  &__wa-std,
+  &__wa-multi {
+    position: relative;
+    padding: 0;
+    margin: 0;
+    width: 32px;
+    height: 32px;
+    display: block;
+    animation:
+      hub-avatar-move-x 0.4s steps(3) infinite,
+      hub-avatar-move-y 5s steps(4) infinite;
+  }
 
-    &__wa-std, &__wa-multi {
-        position: relative;
-        padding: 0;
-        margin: 0;
-        width: 32px;
-        height: 32px;
-        display: block;
-        animation: hub-avatar-move-x 0.4s steps(3) infinite, hub-avatar-move-y 5s steps(4) infinite;
-    }
+  &__wa-multi:not(:first-child) {
+    position: absolute;
+    top: 0;
+    left: 0;
+  }
 
-    &__wa-multi:not(:first-child) {
-        position: absolute;
-        top: 0;
-        left: 0;
+  @keyframes hub-avatar-move-x {
+    from {
+      background-position-x: 0px;
     }
-
-    @keyframes hub-avatar-move-x{
-        from{background-position-x:0px;}
-        to{background-position-x:-96px;}
+    to {
+      background-position-x: -96px;
     }
+  }
 
-    @keyframes hub-avatar-move-y{
-        from{background-position-y:0px;}
-        to{background-position-y:-128px;}
+  @keyframes hub-avatar-move-y {
+    from {
+      background-position-y: 0px;
+    }
+    to {
+      background-position-y: -128px;
     }
+  }
 }
diff --git a/src/plainui/styles/components/_badges.scss b/src/plainui/styles/components/_badges.scss
index a872640a32c6776f9ff268afcd87a4e24ec3249a..1745fbc93a92f6ad7828d91bb95c182bad52fa4c 100644
--- a/src/plainui/styles/components/_badges.scss
+++ b/src/plainui/styles/components/_badges.scss
@@ -54,7 +54,7 @@
 }
 
 .hub-badges-gallery {
-    display: flex;
-    flex-wrap: wrap;
-    gap: map-get($spacers, 2);
+  display: flex;
+  flex-wrap: wrap;
+  gap: map-get($spacers, 2);
 }
diff --git a/src/plainui/styles/components/_card.scss b/src/plainui/styles/components/_card.scss
index beba0fa252fd5041c66c2ce37d8dde87317c1f99..a6095d9a1ef6297060915c9fc5d8f689f7672536 100644
--- a/src/plainui/styles/components/_card.scss
+++ b/src/plainui/styles/components/_card.scss
@@ -2,8 +2,8 @@
  * Can be used to wrap hub-content.
  */
 .hub-card {
-    background-color: var(--bs-secondary-bg);
-    border-radius: var(--bs-border-radius);
-    border-top: 1px solid rgba(255, 255, 255, .03);
-    padding: map-get($spacers, 3) map-get($spacers, 4);
+  background-color: var(--bs-secondary-bg);
+  border-radius: var(--bs-border-radius);
+  border-top: 1px solid rgba(255, 255, 255, 0.03);
+  padding: map-get($spacers, 3) map-get($spacers, 4);
 }
diff --git a/src/plainui/styles/components/_event.scss b/src/plainui/styles/components/_event.scss
index 56c88f7763474bdf7112c54d4f92db9a358a1182..ae1398749b7b515f90fae738a35569225e91ed6c 100644
--- a/src/plainui/styles/components/_event.scss
+++ b/src/plainui/styles/components/_event.scss
@@ -1,119 +1,119 @@
 .hub-event {
-    /* store current class for use in nested rules */
-    $g: &;
-
-    border: 1px solid $signal-secondary-bg;
-    color: var(--event-color);
-    column-gap: map-get($spacers, 3);
-    display: grid;
-    grid-template-areas:
-        "date date"
-        "name name"
-        "tags tags"
-        "buttons buttons";
-    grid-template-columns: auto 1fr;
-    line-height: 1;
-    row-gap: map-get($spacers, 2);
-    padding: map-get($spacers, 2) map-get($spacers, 4);
-
-    &.hub-event--now {
-        background-color: $signal-primary-fill;
-        border: none;
-        --event-color: #{$signal-invert-fill};
-    }
-
-    &.hub-event--past {
-        background-color: $signal-muted-bg;
-        border: none;
-        --event-color: #{$signal-muted-text};
-
-        .hub-tag {
-            /* make all tags look grey for past events */
-            background-color: $signal-muted-text !important;
-            border: none;
-            color: $signal-invert-text !important;
-        }
-    }
-
-    &.hub-event--upcoming {
-        --event-color: #{$signal-secondary-text};
-    }
-
-    &__tags {
-      grid-area: tags;
-    }
-
-    &__date {
-        grid-area: date;
-    }
-
-    &__time {
-        font-family: $font-family-monospace;
-        font-size: 1.5rem;
-        text-transform: uppercase;
-        white-space: nowrap;
-    }
-
-    &__day {
-        font-family: $font-family-monospace;
-        font-size: 0.9375rem;
-    }
-
-    &__name-container {
-        align-items: baseline;
-        display: flex;
-        font-size: 1.5rem;
-        gap: .5rem;
-        grid-area: name;
-        /* min-width for text overflow ellipsis */
-        min-width: 0;
-    }
-
-    &__name {
-        /* imporant to override link styles */
-        color: var(--event-color) !important;
-        /* imporant to override link styles */
-        text-decoration: none !important;
-    }
-
-    &__now {
-        color: $white;
-        font-family: Gabriella, sans-serif;
-        font-weight: 900;
+  /* store current class for use in nested rules */
+  $g: &;
+
+  border: 1px solid $signal-secondary-bg;
+  color: var(--event-color);
+  column-gap: map-get($spacers, 3);
+  display: grid;
+  grid-template-areas:
+    "date date"
+    "name name"
+    "tags tags"
+    "buttons buttons";
+  grid-template-columns: auto 1fr;
+  line-height: 1;
+  row-gap: map-get($spacers, 2);
+  padding: map-get($spacers, 2) map-get($spacers, 4);
+
+  &.hub-event--now {
+    background-color: $signal-primary-fill;
+    border: none;
+    --event-color: #{$signal-invert-fill};
+  }
+
+  &.hub-event--past {
+    background-color: $signal-muted-bg;
+    border: none;
+    --event-color: #{$signal-muted-text};
+
+    .hub-tag {
+      /* make all tags look grey for past events */
+      background-color: $signal-muted-text !important;
+      border: none;
+      color: $signal-invert-text !important;
     }
+  }
+
+  &.hub-event--upcoming {
+    --event-color: #{$signal-secondary-text};
+  }
+
+  &__tags {
+    grid-area: tags;
+  }
+
+  &__date {
+    grid-area: date;
+  }
+
+  &__time {
+    font-family: $font-family-monospace;
+    font-size: 1.5rem;
+    text-transform: uppercase;
+    white-space: nowrap;
+  }
+
+  &__day {
+    font-family: $font-family-monospace;
+    font-size: 0.9375rem;
+  }
+
+  &__name-container {
+    align-items: baseline;
+    display: flex;
+    font-size: 1.5rem;
+    gap: 0.5rem;
+    grid-area: name;
+    /* min-width for text overflow ellipsis */
+    min-width: 0;
+  }
+
+  &__name {
+    /* imporant to override link styles */
+    color: var(--event-color) !important;
+    /* imporant to override link styles */
+    text-decoration: none !important;
+  }
+
+  &__now {
+    color: $white;
+    font-family: Gabriella, sans-serif;
+    font-weight: 900;
+  }
+
+  &__buttons {
+    display: flex;
+    grid-area: buttons;
+    gap: 0.5rem;
+    justify-content: flex-start;
+  }
+
+  @include media-breakpoint-up("md") {
+    grid-template-areas:
+      "date name buttons"
+      "date tags buttons";
+    grid-template-columns: auto auto 1fr;
 
     &__buttons {
-        display: flex;
-        grid-area: buttons;
-        gap: .5rem;
-        justify-content: flex-start;
+      align-items: center;
+      justify-content: flex-end;
     }
 
-    @include media-breakpoint-up("md") {
-        grid-template-areas:
-            "date name buttons"
-            "date tags buttons";
-        grid-template-columns: auto auto 1fr;
-
-        &__buttons {
-            align-items: center;
-            justify-content: flex-end;
-        }
-
-        &__date,
-        &__day {
-          text-align: right;
-        }
+    &__date,
+    &__day {
+      text-align: right;
     }
+  }
 }
 
 .hub-event--small {
-    grid-template-areas:
-        "date date"
-        "name name"
-        "tags tags"
-        "buttons buttons";
-    grid-template-columns: auto 1fr;
+  grid-template-areas:
+    "date date"
+    "name name"
+    "tags tags"
+    "buttons buttons";
+  grid-template-columns: auto 1fr;
 }
 
 .hub-event--small .hub-event__date,
@@ -126,18 +126,18 @@
 }
 
 .hub-event-details-group {
-    margin-top: map-get($spacers, 4);
+  margin-top: map-get($spacers, 4);
 }
 
 .hub-event-details-group__label {
-    color: map-get($colors, 'gray');
-    margin-bottom: map-get($spacers, 2);
+  color: map-get($colors, "gray");
+  margin-bottom: map-get($spacers, 2);
 }
 
 .hub-event-details-group__value {
-    border-radius: 8px;
-    background-color: map-get($colors, 'black');
-    padding: map-get($spacers, 3);
+  border-radius: 8px;
+  background-color: map-get($colors, "black");
+  padding: map-get($spacers, 3);
 }
 
 .hub-event-details__time {
diff --git a/src/plainui/styles/components/_fahrplan.scss b/src/plainui/styles/components/_fahrplan.scss
index e208ee2d5edc01b013c751eaf63e11b7b22d7ae5..e00976b652bd159e3344e7a9ed03a32e1a1964d6 100644
--- a/src/plainui/styles/components/_fahrplan.scss
+++ b/src/plainui/styles/components/_fahrplan.scss
@@ -1,127 +1,127 @@
-$public-fahrplan-body-padding: .7rem;
+$public-fahrplan-body-padding: 0.7rem;
 
 .hub-fahrplan {
-    display: flex;
-    overflow: auto;
-    z-index: 5;
-    font-size: 0.9em;
-    max-height: 75vh;
-    position: relative;
-
-    &__timeline-title {
-        height: 50px;
-        display: block;
-        font-weight: 400;
-        margin: 0;
-        padding: 0 0 15px 0;
-        border: none;
-    }
-
-    &__timeline {
-        position: sticky;
-        left: 0;
-        z-index: 20;
-
-        > figure {
-            position: relative;
-        }
-    }
-
-    &__room {
-        z-index: 10;
-        min-width: 14rem;
-        max-width: 18rem;
-        position: relative;
-    }
-
-    &__room-event {
-        overflow-y: auto;
-
-        p {
-          margin-bottom: map-get($spacers, 2);
-        }
-    }
-
-    &__event_title {
-        background: $primary;
-        color: $light;
-        padding: map-get($spacers, 1);
-        text-transform: none;
-    }
-
-    &__room-space {
-        visibility: hidden;
-        padding: 0;
-        margin: 0;
-    }
-
-    &__modal-title {
-        text-transform: none;
+  display: flex;
+  overflow: auto;
+  z-index: 5;
+  font-size: 0.9em;
+  max-height: 75vh;
+  position: relative;
+
+  &__timeline-title {
+    height: 50px;
+    display: block;
+    font-weight: 400;
+    margin: 0;
+    padding: 0 0 15px 0;
+    border: none;
+  }
+
+  &__timeline {
+    position: sticky;
+    left: 0;
+    z-index: 20;
+
+    > figure {
+      position: relative;
     }
+  }
 
-    &__modal-content {
-        max-height: 90vh;
-        overflow: hidden;
-        background-color: rgba(0, 0, 0, 0.95);
-    }
-
-    &__modal-body {
-        max-height: 100%;
-        overflow-x: auto;
-    }
+  &__room {
+    z-index: 10;
+    min-width: 14rem;
+    max-width: 18rem;
+    position: relative;
+  }
 
-    &__modal-data {
-        display: grid;
-        grid: auto / 1fr 5fr;
-    }
+  &__room-event {
+    overflow-y: auto;
 
-    &__modal-close * {
-        pointer-events: none;
+    p {
+      margin-bottom: map-get($spacers, 2);
     }
+  }
+
+  &__event_title {
+    background: $primary;
+    color: $light;
+    padding: map-get($spacers, 1);
+    text-transform: none;
+  }
+
+  &__room-space {
+    visibility: hidden;
+    padding: 0;
+    margin: 0;
+  }
+
+  &__modal-title {
+    text-transform: none;
+  }
+
+  &__modal-content {
+    max-height: 90vh;
+    overflow: hidden;
+    background-color: rgba(0, 0, 0, 0.95);
+  }
+
+  &__modal-body {
+    max-height: 100%;
+    overflow-x: auto;
+  }
 
-    &__filter-block {
-        .btn-transparent {
-            &:hover,
-            &.active {
-                background-color: $primary;
-                color: $dark;
-            }
-        }
+  &__modal-data {
+    display: grid;
+    grid: auto / 1fr 5fr;
+  }
+
+  &__modal-close * {
+    pointer-events: none;
+  }
+
+  &__filter-block {
+    .btn-transparent {
+      &:hover,
+      &.active {
+        background-color: $primary;
+        color: $dark;
+      }
     }
+  }
 }
 
 .hub-fahrplan__pub-body {
-    overflow: hidden !important;
-    height: 100vh;
-    width: 100vw;
-    padding: $public-fahrplan-body-padding;
-
-    footer .nav-link {
-        padding: 0.25rem 0.5rem;
-    }
+  overflow: hidden !important;
+  height: 100vh;
+  width: 100vw;
+  padding: $public-fahrplan-body-padding;
+
+  footer .nav-link {
+    padding: 0.25rem 0.5rem;
+  }
 }
 
 .hub-fahrplan__pub-body .hub-fahrplan {
-    overflow: visible;
-    max-height: none;
+  overflow: visible;
+  max-height: none;
 }
 
 .hub-fahrplan__pub-content {
-    display: grid;
-    grid: 1fr auto 2fr / auto;
-    height: 100%;
-    width: 100%;
-
-    > .h2 {
-        margin-bottom: $public-fahrplan-body-padding;
-    }
-
-    > footer {
-        margin: $public-fahrplan-body-padding 0 0;
-    }
+  display: grid;
+  grid: 1fr auto 2fr / auto;
+  height: 100%;
+  width: 100%;
+
+  > .h2 {
+    margin-bottom: $public-fahrplan-body-padding;
+  }
+
+  > footer {
+    margin: $public-fahrplan-body-padding 0 0;
+  }
 }
 
 .hub-fahrplan__pub-box {
-    max-height: 100%;
-    overflow: scroll;
+  max-height: 100%;
+  overflow: scroll;
 }
diff --git a/src/plainui/styles/components/_header.scss b/src/plainui/styles/components/_header.scss
index 8fa173e20c0ebf0639325263a3cab617d960a16a..634e930cb5fe1051e04e45022b4816bf59285965 100644
--- a/src/plainui/styles/components/_header.scss
+++ b/src/plainui/styles/components/_header.scss
@@ -1,13 +1,12 @@
 .hub-header {
-    &__badge {
-        font-family: $font-family-base;
-        bottom: .5rem;
-        font-size: .66rem;
-        position: relative;
-        background-color: $secondary;
-        padding: 0.25em 0.35em;
-    }
-
+  &__badge {
+    font-family: $font-family-base;
+    bottom: 0.5rem;
+    font-size: 0.66rem;
+    position: relative;
+    background-color: $secondary;
+    padding: 0.25em 0.35em;
+  }
 }
 
 .hub-search {
@@ -15,46 +14,46 @@
 }
 
 .hub-top-nav {
-    align-items: center;
-    display: none;
-    gap: 1rem;
-    margin-bottom: 2rem;
+  align-items: center;
+  display: none;
+  gap: 1rem;
+  margin-bottom: 2rem;
 }
 
 @include media-breakpoint-up(md) {
-    .hub-top-nav {
-        display: flex;
-    }
+  .hub-top-nav {
+    display: flex;
+  }
 }
 
 .hub-top-nav--breadcrumbs {
-    margin-bottom: .75rem;
+  margin-bottom: 0.75rem;
 }
 
 .hub-head-page {
-    flex: 1;
-    margin-bottom: 0;
+  flex: 1;
+  margin-bottom: 0;
 }
 
 .hub-top-nav__buttons {
-    align-items: center;
-    display: flex;
+  align-items: center;
+  display: flex;
 }
 
 .hub-top-nav__button {
-    align-items: center;
-    background: transparent;
-    color: $signal-secondary-border;
-    border: 0;
-    display: flex;
-    position: relative;
-    text-decoration: none;
+  align-items: center;
+  background: transparent;
+  color: $signal-secondary-border;
+  border: 0;
+  display: flex;
+  position: relative;
+  text-decoration: none;
 }
 
 .hub-top-nav__button-icon {
-    font-size: 1.5625rem;
+  font-size: 1.5625rem;
 }
 
 .hub-breadcrumbs {
-    margin-bottom: 1.5rem;
+  margin-bottom: 1.5rem;
 }
diff --git a/src/plainui/styles/components/_image.scss b/src/plainui/styles/components/_image.scss
index ece235379eedb44f508ff4a5433511cb9ca20b0c..b206fb6fb3aea11d7960d86cc92f00124239d0ec 100644
--- a/src/plainui/styles/components/_image.scss
+++ b/src/plainui/styles/components/_image.scss
@@ -1,28 +1,28 @@
 .hub-image {
-    &--cropped {
-        position: relative;
-        display: block;
-        padding-bottom: 56.25%;
-        height: 0;
-        overflow: hidden;
+  &--cropped {
+    position: relative;
+    display: block;
+    padding-bottom: 56.25%;
+    height: 0;
+    overflow: hidden;
 
-        .hub-image__img {
-            display: block;
-            position: absolute;
-            top: 50%;
-            left: 50%;
-            transform: translate(-50%, -50%);
-            width: 100%;
-            height: 100%;
-            object-fit: cover;
-        }
+    .hub-image__img {
+      display: block;
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+      width: 100%;
+      height: 100%;
+      object-fit: cover;
+    }
 
-        .hub-image__img-caption {
-            display: block;
-            position: absolute;
-            bottom: 0;
-            left: 0;
-            width: 100%;
-        }
+    .hub-image__img-caption {
+      display: block;
+      position: absolute;
+      bottom: 0;
+      left: 0;
+      width: 100%;
     }
+  }
 }
diff --git a/src/plainui/styles/components/_landingpage.scss b/src/plainui/styles/components/_landingpage.scss
index 272fcb3a56c01a2e2e0a4e081975dcd0c975eb19..8aa1dceb7f0c8f9acfad865566cd198c27a57988 100644
--- a/src/plainui/styles/components/_landingpage.scss
+++ b/src/plainui/styles/components/_landingpage.scss
@@ -1,48 +1,48 @@
 .hub-landing {
-    position: relative;
-    overflow: hidden;
-    min-height: calc(100vh - 72px);
-    max-width: 51.875rem;
-    margin: 0 auto;
-    display: flex;
-    flex-flow: column nowrap;
-    justify-content: center;
-    align-items: center;
-    padding: 1rem;
+  position: relative;
+  overflow: hidden;
+  min-height: calc(100vh - 72px);
+  max-width: 51.875rem;
+  margin: 0 auto;
+  display: flex;
+  flex-flow: column nowrap;
+  justify-content: center;
+  align-items: center;
+  padding: 1rem;
 
-    &__logo {
-        .hub-logo {
-            max-width: none;
+  &__logo {
+    .hub-logo {
+      max-width: none;
 
-            img {
-                width: 12rem;
-            }
-        }
+      img {
+        width: 12rem;
+      }
     }
+  }
 
-    &__content {
-        position: absolute;
-        top: map-get($spacers, 10);
-        left: 50%;
-        width: 100%;
-        text-align: center;
-        padding: $spacer;
-        z-index: 6;
-        transform: translate(-50%, 0);
-    }
+  &__content {
+    position: absolute;
+    top: map-get($spacers, 10);
+    left: 50%;
+    width: 100%;
+    text-align: center;
+    padding: $spacer;
+    z-index: 6;
+    transform: translate(-50%, 0);
+  }
 
-    &__title {
-        font-size: 3.5rem;
-    }
+  &__title {
+    font-size: 3.5rem;
+  }
 
-    @include media-breakpoint-up('md') {
-        width: 90%;
-        &__title {
-            font-size: 7rem;
-        }
+  @include media-breakpoint-up("md") {
+    width: 90%;
+    &__title {
+      font-size: 7rem;
     }
+  }
 
-    @include media-breakpoint-up('xxl') {
-        max-width: 59.188rem;
-    }
+  @include media-breakpoint-up("xxl") {
+    max-width: 59.188rem;
+  }
 }
diff --git a/src/plainui/styles/components/_logo.scss b/src/plainui/styles/components/_logo.scss
index de2333b08385f30668b0be5e1725c7650c87d42e..0860b9de0b4ff6ebda2d965a0f32d1309f3c5abe 100644
--- a/src/plainui/styles/components/_logo.scss
+++ b/src/plainui/styles/components/_logo.scss
@@ -1,7 +1,7 @@
 .hub-logo {
-    display: inline-block;
+  display: inline-block;
 
-    svg {
-        height: 100%;
-    }
+  svg {
+    height: 100%;
+  }
 }
diff --git a/src/plainui/styles/components/_markdown.scss b/src/plainui/styles/components/_markdown.scss
index 626f9c1f06559ababf15608e717c1f1537aa4440..018979c5e36b7c0147f450e4f5e350baba324731 100644
--- a/src/plainui/styles/components/_markdown.scss
+++ b/src/plainui/styles/components/_markdown.scss
@@ -1,70 +1,70 @@
 .hub-markdown {
-    overflow-x: auto;
-    -webkit-overflow-scrolling: touch;
+  overflow-x: auto;
+  -webkit-overflow-scrolling: touch;
 
-    p,
-    ul,
-    ol,
-    dl,
-    table {
-        font-family: $font-family-sans-serif;
-        margin-bottom: $spacer;
+  p,
+  ul,
+  ol,
+  dl,
+  table {
+    font-family: $font-family-sans-serif;
+    margin-bottom: $spacer;
 
-        &:last-child {
-            margin-bottom: 0;
-        }
+    &:last-child {
+      margin-bottom: 0;
     }
+  }
 
-    h1,
-    h2,
-    h3,
-    h4,
-    h5,
-    h6 {
-        font-family: $font-family-sans-serif;
-        margin-bottom: $spacer / 2;
+  h1,
+  h2,
+  h3,
+  h4,
+  h5,
+  h6 {
+    font-family: $font-family-sans-serif;
+    margin-bottom: $spacer / 2;
 
-        &:last-child {
-            margin-bottom: 0;
-        }
+    &:last-child {
+      margin-bottom: 0;
     }
+  }
 
-    h1 {
-        font-size: 2rem;
-    }
+  h1 {
+    font-size: 2rem;
+  }
 
-    hr {
-        border-width: 1px;
-        margin: map-get($spacers, 4) 0;
-    }
+  hr {
+    border-width: 1px;
+    margin: map-get($spacers, 4) 0;
+  }
 
-    table {
-        border-collapse: collapse;
-        border-spacing: $spacer * 0.5;
-    }
+  table {
+    border-collapse: collapse;
+    border-spacing: $spacer * 0.5;
+  }
 
-    th,
-    td {
-        padding: ($spacer * 0.5) $spacer;
-    }
+  th,
+  td {
+    padding: ($spacer * 0.5) $spacer;
+  }
 
-    th {
-        background: $primary;
-        font-family: $headings-font-family;
-        font-weight: bold;
-        color: $black;
-    }
+  th {
+    background: $primary;
+    font-family: $headings-font-family;
+    font-weight: bold;
+    color: $black;
+  }
 
-    thead,
-    td {
-      border: 1px solid $gray-500;
-    }
+  thead,
+  td {
+    border: 1px solid $gray-500;
+  }
 
-    a.userprofile {
-        text-decoration: none;
+  a.userprofile {
+    text-decoration: none;
 
-        &::before {
-            content: "@";
-        }
+    &::before {
+      content: "@";
     }
+  }
 }
diff --git a/src/plainui/styles/components/_player.scss b/src/plainui/styles/components/_player.scss
index 1d5a5330bd926ab1d22779c05362280721afb33a..fb4f772fb482fa8ebf6b2101e16683419ce90369 100644
--- a/src/plainui/styles/components/_player.scss
+++ b/src/plainui/styles/components/_player.scss
@@ -1,6 +1,6 @@
 .hub_voc_player > [data-player] {
-    padding-bottom: 56.25%;
-    height: auto !important;
+  padding-bottom: 56.25%;
+  height: auto !important;
 }
 .hub_voc_player > .fullscreen[data-player] {
   padding-bottom: 0;
diff --git a/src/plainui/styles/components/_slider.scss b/src/plainui/styles/components/_slider.scss
index e0f33616d2868143be2c5babeb2ed59b231b4cfd..625fda583f4125ba68858c240f0c3c2faa9b87da 100644
--- a/src/plainui/styles/components/_slider.scss
+++ b/src/plainui/styles/components/_slider.scss
@@ -1,13 +1,13 @@
 .hub-slider {
-    &__container {
-        overflow-x: auto;
-        overflow-y: hidden;
-        -webkit-overflow-scrolling: touch;
-        scroll-snap-type: y mandatory;
-        scroll-padding: map-get($spacers, 2);
-    }
+  &__container {
+    overflow-x: auto;
+    overflow-y: hidden;
+    -webkit-overflow-scrolling: touch;
+    scroll-snap-type: y mandatory;
+    scroll-padding: map-get($spacers, 2);
+  }
 
-    &__item {
-        scroll-snap-align: start;
-    }
+  &__item {
+    scroll-snap-align: start;
+  }
 }
diff --git a/src/plainui/styles/components/_static-pages.scss b/src/plainui/styles/components/_static-pages.scss
index 42bf0d1f98ffcde9c4d432511799818d71c185ed..eb4db78220a0196457bfe84c64b6d12a8578ba45 100644
--- a/src/plainui/styles/components/_static-pages.scss
+++ b/src/plainui/styles/components/_static-pages.scss
@@ -1,5 +1,5 @@
 .staticpage {
-  input[type=radio] {
+  input[type="radio"] {
     margin: 0.2rem;
   }
 
@@ -13,7 +13,7 @@
 }
 
 table.diff {
-  background: rgba(26, 25, 25, .9);
+  background: rgba(26, 25, 25, 0.9);
   color: $white;
   td:nth-child(3) {
     width: 50%;
@@ -27,7 +27,7 @@ table.diff {
   background-color: $black;
   color: $white;
   min-width: 1rem;
-  text-align:right
+  text-align: right;
 }
 
 .diff_next {
@@ -37,22 +37,22 @@ table.diff {
 }
 
 .diff_add {
-  background-color:$green;
+  background-color: $green;
   color: $black;
 }
 
 .diff_chg {
-  background-color:$yellow;
+  background-color: $yellow;
 }
 
 .diff_sub {
-  background-color:$red;
+  background-color: $red;
 }
 
 .diff_content {
   overflow-wrap: break-word;
   word-break: break-all;
-  width: 50%!important;
+  width: 50% !important;
   padding-left: 0.5rem;
 }
 
diff --git a/src/plainui/styles/components/_syntaxhilite.scss b/src/plainui/styles/components/_syntaxhilite.scss
index 5b72af63f3e199e0fc6c88c5b6404c5bf57e7ab6..0cc265750636e5e90cfde0617483d653976d5fda 100644
--- a/src/plainui/styles/components/_syntaxhilite.scss
+++ b/src/plainui/styles/components/_syntaxhilite.scss
@@ -1,75 +1,240 @@
-pre { line-height: 125%; margin: 0; }
-td.linenos pre { color: #000000; background-color: #f0f0f0; padding-left: 5px; padding-right: 5px; }
-span.linenos { color: #000000; background-color: #f0f0f0; padding-left: 5px; padding-right: 5px; }
-td.linenos pre.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
-span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
-.codehilite .hll { background-color: #49483e }
-.codehilite  { background: #272822; color: #f8f8f2 }
-.codehilite .c { color: #75715e } /* Comment */
-.codehilite .err { color: #960050; background-color: #1e0010 } /* Error */
-.codehilite .k { color: #66d9ef } /* Keyword */
-.codehilite .l { color: #ae81ff } /* Literal */
-.codehilite .n { color: #f8f8f2 } /* Name */
-.codehilite .o { color: #f92672 } /* Operator */
-.codehilite .p { color: #f8f8f2 } /* Punctuation */
-.codehilite .ch { color: #75715e } /* Comment.Hashbang */
-.codehilite .cm { color: #75715e } /* Comment.Multiline */
-.codehilite .cp { color: #75715e } /* Comment.Preproc */
-.codehilite .cpf { color: #75715e } /* Comment.PreprocFile */
-.codehilite .c1 { color: #75715e } /* Comment.Single */
-.codehilite .cs { color: #75715e } /* Comment.Special */
-.codehilite .gd { color: #f92672 } /* Generic.Deleted */
-.codehilite .ge { font-style: italic } /* Generic.Emph */
-.codehilite .gi { color: #a6e22e } /* Generic.Inserted */
-.codehilite .gs { font-weight: bold } /* Generic.Strong */
-.codehilite .gu { color: #75715e } /* Generic.Subheading */
-.codehilite .kc { color: #66d9ef } /* Keyword.Constant */
-.codehilite .kd { color: #66d9ef } /* Keyword.Declaration */
-.codehilite .kn { color: #f92672 } /* Keyword.Namespace */
-.codehilite .kp { color: #66d9ef } /* Keyword.Pseudo */
-.codehilite .kr { color: #66d9ef } /* Keyword.Reserved */
-.codehilite .kt { color: #66d9ef } /* Keyword.Type */
-.codehilite .ld { color: #e6db74 } /* Literal.Date */
-.codehilite .m { color: #ae81ff } /* Literal.Number */
-.codehilite .s { color: #e6db74 } /* Literal.String */
-.codehilite .na { color: #a6e22e } /* Name.Attribute */
-.codehilite .nb { color: #f8f8f2 } /* Name.Builtin */
-.codehilite .nc { color: #a6e22e } /* Name.Class */
-.codehilite .no { color: #66d9ef } /* Name.Constant */
-.codehilite .nd { color: #a6e22e } /* Name.Decorator */
-.codehilite .ni { color: #f8f8f2 } /* Name.Entity */
-.codehilite .ne { color: #a6e22e } /* Name.Exception */
-.codehilite .nf { color: #a6e22e } /* Name.Function */
-.codehilite .nl { color: #f8f8f2 } /* Name.Label */
-.codehilite .nn { color: #f8f8f2 } /* Name.Namespace */
-.codehilite .nx { color: #a6e22e } /* Name.Other */
-.codehilite .py { color: #f8f8f2 } /* Name.Property */
-.codehilite .nt { color: #f92672 } /* Name.Tag */
-.codehilite .nv { color: #f8f8f2 } /* Name.Variable */
-.codehilite .ow { color: #f92672 } /* Operator.Word */
-.codehilite .w { color: #f8f8f2 } /* Text.Whitespace */
-.codehilite .mb { color: #ae81ff } /* Literal.Number.Bin */
-.codehilite .mf { color: #ae81ff } /* Literal.Number.Float */
-.codehilite .mh { color: #ae81ff } /* Literal.Number.Hex */
-.codehilite .mi { color: #ae81ff } /* Literal.Number.Integer */
-.codehilite .mo { color: #ae81ff } /* Literal.Number.Oct */
-.codehilite .sa { color: #e6db74 } /* Literal.String.Affix */
-.codehilite .sb { color: #e6db74 } /* Literal.String.Backtick */
-.codehilite .sc { color: #e6db74 } /* Literal.String.Char */
-.codehilite .dl { color: #e6db74 } /* Literal.String.Delimiter */
-.codehilite .sd { color: #e6db74 } /* Literal.String.Doc */
-.codehilite .s2 { color: #e6db74 } /* Literal.String.Double */
-.codehilite .se { color: #ae81ff } /* Literal.String.Escape */
-.codehilite .sh { color: #e6db74 } /* Literal.String.Heredoc */
-.codehilite .si { color: #e6db74 } /* Literal.String.Interpol */
-.codehilite .sx { color: #e6db74 } /* Literal.String.Other */
-.codehilite .sr { color: #e6db74 } /* Literal.String.Regex */
-.codehilite .s1 { color: #e6db74 } /* Literal.String.Single */
-.codehilite .ss { color: #e6db74 } /* Literal.String.Symbol */
-.codehilite .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */
-.codehilite .fm { color: #a6e22e } /* Name.Function.Magic */
-.codehilite .vc { color: #f8f8f2 } /* Name.Variable.Class */
-.codehilite .vg { color: #f8f8f2 } /* Name.Variable.Global */
-.codehilite .vi { color: #f8f8f2 } /* Name.Variable.Instance */
-.codehilite .vm { color: #f8f8f2 } /* Name.Variable.Magic */
-.codehilite .il { color: #ae81ff } /* Literal.Number.Integer.Long */
+pre {
+  line-height: 125%;
+  margin: 0;
+}
+td.linenos pre {
+  color: #000000;
+  background-color: #f0f0f0;
+  padding-left: 5px;
+  padding-right: 5px;
+}
+span.linenos {
+  color: #000000;
+  background-color: #f0f0f0;
+  padding-left: 5px;
+  padding-right: 5px;
+}
+td.linenos pre.special {
+  color: #000000;
+  background-color: #ffffc0;
+  padding-left: 5px;
+  padding-right: 5px;
+}
+span.linenos.special {
+  color: #000000;
+  background-color: #ffffc0;
+  padding-left: 5px;
+  padding-right: 5px;
+}
+.codehilite .hll {
+  background-color: #49483e;
+}
+.codehilite {
+  background: #272822;
+  color: #f8f8f2;
+}
+.codehilite .c {
+  color: #75715e;
+} /* Comment */
+.codehilite .err {
+  color: #960050;
+  background-color: #1e0010;
+} /* Error */
+.codehilite .k {
+  color: #66d9ef;
+} /* Keyword */
+.codehilite .l {
+  color: #ae81ff;
+} /* Literal */
+.codehilite .n {
+  color: #f8f8f2;
+} /* Name */
+.codehilite .o {
+  color: #f92672;
+} /* Operator */
+.codehilite .p {
+  color: #f8f8f2;
+} /* Punctuation */
+.codehilite .ch {
+  color: #75715e;
+} /* Comment.Hashbang */
+.codehilite .cm {
+  color: #75715e;
+} /* Comment.Multiline */
+.codehilite .cp {
+  color: #75715e;
+} /* Comment.Preproc */
+.codehilite .cpf {
+  color: #75715e;
+} /* Comment.PreprocFile */
+.codehilite .c1 {
+  color: #75715e;
+} /* Comment.Single */
+.codehilite .cs {
+  color: #75715e;
+} /* Comment.Special */
+.codehilite .gd {
+  color: #f92672;
+} /* Generic.Deleted */
+.codehilite .ge {
+  font-style: italic;
+} /* Generic.Emph */
+.codehilite .gi {
+  color: #a6e22e;
+} /* Generic.Inserted */
+.codehilite .gs {
+  font-weight: bold;
+} /* Generic.Strong */
+.codehilite .gu {
+  color: #75715e;
+} /* Generic.Subheading */
+.codehilite .kc {
+  color: #66d9ef;
+} /* Keyword.Constant */
+.codehilite .kd {
+  color: #66d9ef;
+} /* Keyword.Declaration */
+.codehilite .kn {
+  color: #f92672;
+} /* Keyword.Namespace */
+.codehilite .kp {
+  color: #66d9ef;
+} /* Keyword.Pseudo */
+.codehilite .kr {
+  color: #66d9ef;
+} /* Keyword.Reserved */
+.codehilite .kt {
+  color: #66d9ef;
+} /* Keyword.Type */
+.codehilite .ld {
+  color: #e6db74;
+} /* Literal.Date */
+.codehilite .m {
+  color: #ae81ff;
+} /* Literal.Number */
+.codehilite .s {
+  color: #e6db74;
+} /* Literal.String */
+.codehilite .na {
+  color: #a6e22e;
+} /* Name.Attribute */
+.codehilite .nb {
+  color: #f8f8f2;
+} /* Name.Builtin */
+.codehilite .nc {
+  color: #a6e22e;
+} /* Name.Class */
+.codehilite .no {
+  color: #66d9ef;
+} /* Name.Constant */
+.codehilite .nd {
+  color: #a6e22e;
+} /* Name.Decorator */
+.codehilite .ni {
+  color: #f8f8f2;
+} /* Name.Entity */
+.codehilite .ne {
+  color: #a6e22e;
+} /* Name.Exception */
+.codehilite .nf {
+  color: #a6e22e;
+} /* Name.Function */
+.codehilite .nl {
+  color: #f8f8f2;
+} /* Name.Label */
+.codehilite .nn {
+  color: #f8f8f2;
+} /* Name.Namespace */
+.codehilite .nx {
+  color: #a6e22e;
+} /* Name.Other */
+.codehilite .py {
+  color: #f8f8f2;
+} /* Name.Property */
+.codehilite .nt {
+  color: #f92672;
+} /* Name.Tag */
+.codehilite .nv {
+  color: #f8f8f2;
+} /* Name.Variable */
+.codehilite .ow {
+  color: #f92672;
+} /* Operator.Word */
+.codehilite .w {
+  color: #f8f8f2;
+} /* Text.Whitespace */
+.codehilite .mb {
+  color: #ae81ff;
+} /* Literal.Number.Bin */
+.codehilite .mf {
+  color: #ae81ff;
+} /* Literal.Number.Float */
+.codehilite .mh {
+  color: #ae81ff;
+} /* Literal.Number.Hex */
+.codehilite .mi {
+  color: #ae81ff;
+} /* Literal.Number.Integer */
+.codehilite .mo {
+  color: #ae81ff;
+} /* Literal.Number.Oct */
+.codehilite .sa {
+  color: #e6db74;
+} /* Literal.String.Affix */
+.codehilite .sb {
+  color: #e6db74;
+} /* Literal.String.Backtick */
+.codehilite .sc {
+  color: #e6db74;
+} /* Literal.String.Char */
+.codehilite .dl {
+  color: #e6db74;
+} /* Literal.String.Delimiter */
+.codehilite .sd {
+  color: #e6db74;
+} /* Literal.String.Doc */
+.codehilite .s2 {
+  color: #e6db74;
+} /* Literal.String.Double */
+.codehilite .se {
+  color: #ae81ff;
+} /* Literal.String.Escape */
+.codehilite .sh {
+  color: #e6db74;
+} /* Literal.String.Heredoc */
+.codehilite .si {
+  color: #e6db74;
+} /* Literal.String.Interpol */
+.codehilite .sx {
+  color: #e6db74;
+} /* Literal.String.Other */
+.codehilite .sr {
+  color: #e6db74;
+} /* Literal.String.Regex */
+.codehilite .s1 {
+  color: #e6db74;
+} /* Literal.String.Single */
+.codehilite .ss {
+  color: #e6db74;
+} /* Literal.String.Symbol */
+.codehilite .bp {
+  color: #f8f8f2;
+} /* Name.Builtin.Pseudo */
+.codehilite .fm {
+  color: #a6e22e;
+} /* Name.Function.Magic */
+.codehilite .vc {
+  color: #f8f8f2;
+} /* Name.Variable.Class */
+.codehilite .vg {
+  color: #f8f8f2;
+} /* Name.Variable.Global */
+.codehilite .vi {
+  color: #f8f8f2;
+} /* Name.Variable.Instance */
+.codehilite .vm {
+  color: #f8f8f2;
+} /* Name.Variable.Magic */
+.codehilite .il {
+  color: #ae81ff;
+} /* Literal.Number.Integer.Long */
diff --git a/src/plainui/styles/components/_tags.scss b/src/plainui/styles/components/_tags.scss
index e6f5fb4e886bb6132a8e532a1048525c375282d6..aeaf501d905ea4f68f7a749a0a73e12cd46ab579 100644
--- a/src/plainui/styles/components/_tags.scss
+++ b/src/plainui/styles/components/_tags.scss
@@ -1,26 +1,26 @@
 .hub-tags {
-    align-items: center;
-    display: flex;
-    flex-wrap: wrap;
-    gap: map-get($spacers, 2);
-    /* to prevent overflow */
-    min-width: 0;
+  align-items: center;
+  display: flex;
+  flex-wrap: wrap;
+  gap: map-get($spacers, 2);
+  /* to prevent overflow */
+  min-width: 0;
 }
 
 .hub-tag {
-    background-color: var(--bs-tertiary-bg);
-    border-radius: var(--bs-border-radius) 0;
-    border: none;
-    color: var(--bs-white);
-    display: inline-flex;
-    gap: map-get($spacers, 1);
-    /* required for overflow texts */
-    min-width: 0;
-    overflow: hidden;
-    padding: 3px 5px 2px;
-    text-overflow: ellipsis;
-    text-transform: uppercase;
-    white-space: nowrap;
+  background-color: var(--bs-tertiary-bg);
+  border-radius: var(--bs-border-radius) 0;
+  border: none;
+  color: var(--bs-white);
+  display: inline-flex;
+  gap: map-get($spacers, 1);
+  /* required for overflow texts */
+  min-width: 0;
+  overflow: hidden;
+  padding: 3px 5px 2px;
+  text-overflow: ellipsis;
+  text-transform: uppercase;
+  white-space: nowrap;
 }
 
 .hub-tag--clear {
@@ -34,58 +34,58 @@
 }
 
 .hub-tag--outline {
-    background-color: transparent;
-    border: 1px solid var(--bs-tertiary-bg);
-    color: var(--bs-tertiary-bg);
+  background-color: transparent;
+  border: 1px solid var(--bs-tertiary-bg);
+  color: var(--bs-tertiary-bg);
 }
 
 .hub-tag--outline-danger {
-    background-color: transparent;
-    border: 1px solid $signal-danger-fill;
-    color: $signal-danger-text
+  background-color: transparent;
+  border: 1px solid $signal-danger-fill;
+  color: $signal-danger-text;
 }
 
 .hub-tag--secondary {
-    background-color: $signal-secondary-bg;
-    border: none;
-    color: var(--bs-white);
+  background-color: $signal-secondary-bg;
+  border: none;
+  color: var(--bs-white);
 }
 
 .hub-tag--success {
-    background-color: $signal-success-fill;
-    color: var(--bs-black);
+  background-color: $signal-success-fill;
+  color: var(--bs-black);
 }
 
 .hub-tag--danger {
-    background-color: $signal-danger-fill;
-    color: var(--bs-white);
+  background-color: $signal-danger-fill;
+  color: var(--bs-white);
 }
 
 .hub-tag--outline-danger {
-    background-color: transparent;
-    border: 1px solid $signal-danger-fill;
-    color: $signal-danger-text
+  background-color: transparent;
+  border: 1px solid $signal-danger-fill;
+  color: $signal-danger-text;
 }
 
 .hub-tag--disabled {
-    background-color: var(--bs-dark);
-    color: $signal-muted-text-dark;
+  background-color: var(--bs-dark);
+  color: $signal-muted-text-dark;
 }
 
 .hub-tag--user {
-    background-color: $secondary;
-    border-radius: 0;
-    color: $signal-invert-text;
+  background-color: $secondary;
+  border-radius: 0;
+  color: $signal-invert-text;
 }
 
 .hub-tag--secondary-outline {
-    background-color: transparent;
-    border: 1px solid $signal-secondary-border;
-    color: $signal-secondary-text;
+  background-color: transparent;
+  border: 1px solid $signal-secondary-border;
+  color: $signal-secondary-text;
 }
 
 a.hub-tag:hover {
-    text-decoration: none;
+  text-decoration: none;
 }
 
 .hub-tag__text {
@@ -98,4 +98,3 @@ a.hub-tag:hover {
   height: 1rem;
   width: 2px;
 }
-
diff --git a/src/plainui/styles/components/_tile-board.scss b/src/plainui/styles/components/_tile-board.scss
index f664089491c2bf8581f00319baf3396d093b381e..3c4072dc93033e10165326582340a6e5923128ff 100644
--- a/src/plainui/styles/components/_tile-board.scss
+++ b/src/plainui/styles/components/_tile-board.scss
@@ -1,29 +1,29 @@
 .hub-tile-board {
-    &__body {
-        overflow: hidden;
-        max-height: 6.25rem;
-    }
+  &__body {
+    overflow: hidden;
+    max-height: 6.25rem;
+  }
 
-    &__footer {
-        position: relative;
-    }
+  &__footer {
+    position: relative;
+  }
 
-    &__btn {
-        position: absolute;
-        left: 50%;
-        transform: translate(-50%);
-        display: block;
-        padding: 0 map-get($spacers, 2);
+  &__btn {
+    position: absolute;
+    left: 50%;
+    transform: translate(-50%);
+    display: block;
+    padding: 0 map-get($spacers, 2);
 
-        &:hover:not(:focus) {
-            .hub-tile-board__btn-arrow {
-                transform: translate(0, 3px);
-            }
-        }
+    &:hover:not(:focus) {
+      .hub-tile-board__btn-arrow {
+        transform: translate(0, 3px);
+      }
+    }
 
-        &:focus,
-        &.focus {
-            box-shadow: $btn-focus-box-shadow;
-        }
+    &:focus,
+    &.focus {
+      box-shadow: $btn-focus-box-shadow;
     }
+  }
 }
diff --git a/src/plainui/styles/components/_tile-message.scss b/src/plainui/styles/components/_tile-message.scss
index 45d42126414fde28f5e7000617b3e8f4a4e61fd2..496be88301b26ec9731d84d30e98853e66da6aef 100644
--- a/src/plainui/styles/components/_tile-message.scss
+++ b/src/plainui/styles/components/_tile-message.scss
@@ -1,40 +1,40 @@
 .hub-tile-message {
-    &__icon-col {
-        width: 9.375rem;
-        flex: 0 0 9.375rem;
-    }
+  &__icon-col {
+    width: 9.375rem;
+    flex: 0 0 9.375rem;
+  }
 
-    &__icon-container {
-        position: relative;
-        width: 100%;
-        height: 100%;
-        display: flex;
-        flex-flow: column nowrap;
-        align-items: center;
-        justify-content: center;
+  &__icon-container {
+    position: relative;
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-flow: column nowrap;
+    align-items: center;
+    justify-content: center;
 
-        margin-bottom: 0;
-        text-decoration: none;
-    }
+    margin-bottom: 0;
+    text-decoration: none;
+  }
 
-    &__icon {
-        &-flag {
-            margin-left: 2.5rem;
-        }
+  &__icon {
+    &-flag {
+      margin-left: 2.5rem;
     }
+  }
 
-    @include media-breakpoint-down('md') {
-        &__icon-col {
-            width: 5rem;
-            flex: 0 0 5rem;
-        }
+  @include media-breakpoint-down("md") {
+    &__icon-col {
+      width: 5rem;
+      flex: 0 0 5rem;
+    }
 
-        &__icon {
-            max-width: 2.5rem;
+    &__icon {
+      max-width: 2.5rem;
 
-            &-flag {
-                margin-left: 1.25rem;
-            }
-        }
+      &-flag {
+        margin-left: 1.25rem;
+      }
     }
+  }
 }
diff --git a/src/plainui/styles/design/_variables.scss b/src/plainui/styles/design/_variables.scss
index f1004717241ca867467fa5e85f878f3279f14055..f584dcff96fccb1247365fc76bbe3c07388b5cca 100644
--- a/src/plainui/styles/design/_variables.scss
+++ b/src/plainui/styles/design/_variables.scss
@@ -1,6 +1,6 @@
 /* Variables exported from design */
 
- /* Variables  */
+/* Variables  */
 $text-body-dark: rgba(255, 255, 255, 0.85);
 $text-body-lite: rgba(33, 37, 41, 1);
 $bg-body-dark: rgba(0, 0, 0, 1);
@@ -89,5 +89,5 @@ $signal-tertiary-border-lite: rgba(255, 255, 255, 1);
 $signal-tertiary-text-dark: rgba(222, 55, 255, 1);
 $signal-tertiary-text-lite: rgba(255, 255, 255, 1);
 
- /* Aliases  */
+/* Aliases  */
 $signal-primary-fill-lite: $ccc-orange-desktop;
diff --git a/src/plainui/styles/hub.scss b/src/plainui/styles/hub.scss
index d2265cbb20577b6743f110843302ed89866f9832..577621cb66fbcde42419a8691b1dab2f4153dc87 100644
--- a/src/plainui/styles/hub.scss
+++ b/src/plainui/styles/hub.scss
@@ -36,14 +36,16 @@ body {
   word-wrap: break-word;
 }
 
-* {-webkit-font-smoothing: antialiased;}
+* {
+  -webkit-font-smoothing: antialiased;
+}
 
 .mw-320 {
-    max-width: 20rem;
+  max-width: 20rem;
 }
 
 .w-100px {
-    width: 6.25rem;
+  width: 6.25rem;
 }
 
 .custom-popover {
@@ -53,18 +55,18 @@ body {
 }
 
 .hub-content {
-    padding: map-get($spacers, 2) map-get($spacers, 3);
-    padding-top: $hub-mobile-navbar-height;
-    height: calc(100vh - $hub-mobile-navbar-height);
-    z-index: 100;
+  padding: map-get($spacers, 2) map-get($spacers, 3);
+  padding-top: $hub-mobile-navbar-height;
+  height: calc(100vh - $hub-mobile-navbar-height);
+  z-index: 100;
 }
 
 @include media-breakpoint-up(md) {
-    .hub-content {
-        padding: map-get($spacers, 3) map-get($spacers, 5);
-    }
+  .hub-content {
+    padding: map-get($spacers, 3) map-get($spacers, 5);
+  }
 
-    .hub-main {
-        height: 100vh;
-    }
+  .hub-main {
+    height: 100vh;
+  }
 }
diff --git a/src/plainui/styles/sections/_fahrplan.scss b/src/plainui/styles/sections/_fahrplan.scss
index 0d7cfb2c656b64ed5011c763fa31aa6c896a27db..ee6b248ad0a76df2ca1166584cffd2e84cd262e3 100644
--- a/src/plainui/styles/sections/_fahrplan.scss
+++ b/src/plainui/styles/sections/_fahrplan.scss
@@ -1,154 +1,154 @@
-$public-fahrplan-body-padding: .7rem;
+$public-fahrplan-body-padding: 0.7rem;
 
 .hub-fahrplan {
-    display: flex;
-    overflow: auto;
-    z-index: 5;
-    font-size: 0.9em;
-    max-height: 75vh;
-
-    &__title {
-        font-size: 2.1875rem; // 35px
-        text-overflow: ellipsis;
-        white-space: nowrap;
-
-        .active {
-            color: $signal-secondary-text;
-        }
-
-        .inactive {
-            color: $gray-600;
-
-            &:hover {
-                color: $primary;
-            }
-        }
-    }
-
-    &__timeline-title {
-        height: 50px;
-        display: block;
-        font-weight: 400;
-        margin: 0;
-        padding: 0 0 15px 0;
-        border: none;
-    }
+  display: flex;
+  overflow: auto;
+  z-index: 5;
+  font-size: 0.9em;
+  max-height: 75vh;
 
-    &__timeline {
-        position: sticky;
-        left: 0;
-        z-index: 20;
+  &__title {
+    font-size: 2.1875rem; // 35px
+    text-overflow: ellipsis;
+    white-space: nowrap;
 
-        >figure {
-            position: relative;
-        }
+    .active {
+      color: $signal-secondary-text;
     }
 
-    &__room {
-        z-index: 10;
-        min-width: 14rem;
-        position: relative;
-    }
+    .inactive {
+      color: $gray-600;
 
-    &__room-event {
-        border-style: solid;
-        border-width: 1px;
+      &:hover {
         color: $primary;
-        font-size: 0.875rem;
-        overflow-y: auto;
-    }
-
-    &__event-body {
-      padding: map-get($spacers, 1);
-    }
-
-    &__event_title {
-        text-transform: none;
-    }
-
-    &__room-space {
-        visibility: hidden;
-        padding: 0;
-        margin: 0;
-    }
-
-    &__modal-title {
-        text-transform: none;
-    }
-
-    &__modal-content {
-        max-height: 90vh;
-        overflow: hidden;
-        background-color: rgba(0, 0, 0, 0.95);
-    }
-
-    &__modal-body {
-        max-height: 100%;
-        overflow-x: auto;
-    }
-
-    &__modal-data {
-        display: grid;
-        grid: auto / 1fr 5fr;
-    }
-
-    &__modal-close * {
-        pointer-events: none;
-    }
+      }
+    }
+  }
+
+  &__timeline-title {
+    height: 50px;
+    display: block;
+    font-weight: 400;
+    margin: 0;
+    padding: 0 0 15px 0;
+    border: none;
+  }
+
+  &__timeline {
+    position: sticky;
+    left: 0;
+    z-index: 20;
+
+    > figure {
+      position: relative;
+    }
+  }
+
+  &__room {
+    z-index: 10;
+    min-width: 14rem;
+    position: relative;
+  }
+
+  &__room-event {
+    border-style: solid;
+    border-width: 1px;
+    color: $primary;
+    font-size: 0.875rem;
+    overflow-y: auto;
+  }
+
+  &__event-body {
+    padding: map-get($spacers, 1);
+  }
+
+  &__event_title {
+    text-transform: none;
+  }
+
+  &__room-space {
+    visibility: hidden;
+    padding: 0;
+    margin: 0;
+  }
+
+  &__modal-title {
+    text-transform: none;
+  }
+
+  &__modal-content {
+    max-height: 90vh;
+    overflow: hidden;
+    background-color: rgba(0, 0, 0, 0.95);
+  }
+
+  &__modal-body {
+    max-height: 100%;
+    overflow-x: auto;
+  }
 
-    &__filter-block {
-        .btn-transparent {
-            &:hover,
-            &.active {
-                background-color: $primary;
-                color: $dark;
-            }
-        }
-    }
+  &__modal-data {
+    display: grid;
+    grid: auto / 1fr 5fr;
+  }
+
+  &__modal-close * {
+    pointer-events: none;
+  }
+
+  &__filter-block {
+    .btn-transparent {
+      &:hover,
+      &.active {
+        background-color: $primary;
+        color: $dark;
+      }
+    }
+  }
 }
 
 .hub-fahrplan__pub-body {
-    overflow: hidden !important;
-    height: 100vh;
-    width: 100vw;
-    padding: $public-fahrplan-body-padding;
-
-    footer .nav-link {
-        padding: 0.25rem 0.5rem;
-    }
+  overflow: hidden !important;
+  height: 100vh;
+  width: 100vw;
+  padding: $public-fahrplan-body-padding;
+
+  footer .nav-link {
+    padding: 0.25rem 0.5rem;
+  }
 }
 
 .hub-fahrplan__pub-body .hub-fahrplan {
-    overflow: visible;
-    max-height: none;
+  overflow: visible;
+  max-height: none;
 }
 
 .hub-fahrplan__pub-content {
-    display: grid;
-    grid: 1fr auto / auto;
-    height: 100%;
-    width: 100%;
-
-    > .h2 {
-        margin-bottom: $public-fahrplan-body-padding;
-    }
-
-    > footer {
-        margin: $public-fahrplan-body-padding 0 0;
-    }
+  display: grid;
+  grid: 1fr auto / auto;
+  height: 100%;
+  width: 100%;
+
+  > .h2 {
+    margin-bottom: $public-fahrplan-body-padding;
+  }
+
+  > footer {
+    margin: $public-fahrplan-body-padding 0 0;
+  }
 }
 
 .hub-fahrplan__pub-box {
-    max-height: 100%;
-    overflow: auto;
+  max-height: 100%;
+  overflow: auto;
 }
 
 .hub-fahrplan__view-toggle {
-    background: none;
-    border: 0;
-    color: var(--bs-body-color);
+  background: none;
+  border: 0;
+  color: var(--bs-body-color);
 }
 
 .hub-fahrplan__view-toggle--active {
-    color: var(--bs-tertiary-color);
+  color: var(--bs-tertiary-color);
 }
diff --git a/src/version.json b/src/version.json
index 5e5f5153a3625588e652349383ed0c324e86996c..00cb46486223ed56c5c10d263263398b43ac8f51 100644
--- a/src/version.json
+++ b/src/version.json
@@ -1 +1 @@
-{"tag": "DEV"}
+{ "tag": "DEV" }
diff --git a/tests/README.md b/tests/README.md
index 1698dd6e001eebfbbced8e83e5dfa3ed934fff07..055f7ac67b4b647c8e0073a7535fd3e224c4f736 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -6,9 +6,9 @@ There are more in-depth technical tests in the individual Django apps' tests fol
 The tests are done with Python's unittest framework and the requests library.
 You may assume the following environment variables:
 
-* `BASE_URL` with protocol and hostname of the testee's location, e.g. `http://hubapp`
-* `DJANGO_CREATE_ADMIN_USERNAME` with the username of a superuser
-* `DJANGO_CREATE_ADMIN_PASSWORD` with the corresponding password
-* `SERVE_API`, `SERVE_BACKOFFICE` and `SERVE_FRONTEND` as in the Docker environment (see [hub.settings.default](/src/hub/settings/default.py))
+- `BASE_URL` with protocol and hostname of the testee's location, e.g. `http://hubapp`
+- `DJANGO_CREATE_ADMIN_USERNAME` with the username of a superuser
+- `DJANGO_CREATE_ADMIN_PASSWORD` with the corresponding password
+- `SERVE_API`, `SERVE_BACKOFFICE` and `SERVE_FRONTEND` as in the Docker environment (see [hub.settings.default](/src/hub/settings/default.py))
 
 To run all tests execute `SERVE_API=yes SERVE_BACKOFFICE=yes SERVE_FRONTEND=yes python3 -m unittest -v` (in this directory).