diff --git a/app/controllers/admin/loginstyle.php b/app/controllers/admin/login_style.php
similarity index 57%
rename from app/controllers/admin/loginstyle.php
rename to app/controllers/admin/login_style.php
index f998b3a6a6677b648a92f1bd8a3e88844e2f3291..615e777f7a79a500f4e80d1992fe97057ca97102 100644
--- a/app/controllers/admin/loginstyle.php
+++ b/app/controllers/admin/login_style.php
@@ -11,6 +11,7 @@
 
 class Admin_LoginStyleController extends AuthenticatedController
 {
+    protected $_autobind = true;
     /**
      * common tasks for all actions
      *
@@ -21,15 +22,24 @@ class Admin_LoginStyleController extends AuthenticatedController
     {
         parent::before_filter($action, $args);
 
-        // user must have root permission
         $GLOBALS['perm']->check('root');
 
         //setting title and navigation
         PageLayout::setTitle(_('Hintergrundbilder für den Startbildschirm'));
         Navigation::activateItem('/admin/locations/loginstyle');
 
-        // Setup sidebar
-        $this->setSidebar();
+        $views = new ViewsWidget();
+        $views->addLink(
+            _('Bilder'),
+            $this->indexURL()
+        )->setActive($action === 'index');
+
+        $views->addLink(
+            _('Hinweise zum Login'),
+            $this->login_faqURL()
+        )->setActive($action === 'login_faq');
+
+        Sidebar::Get()->addWidget($views);
     }
 
     /**
@@ -37,6 +47,8 @@ class Admin_LoginStyleController extends AuthenticatedController
      */
     public function index_action()
     {
+        // Setup sidebar
+        $this->setSidebar('index');
         $this->pictures = LoginBackground::findBySQL("1 ORDER BY `background_id`");
     }
 
@@ -50,7 +62,7 @@ class Admin_LoginStyleController extends AuthenticatedController
     /**
      * Adds a new picture ass possible login background.
      */
-    public function add_action()
+    public function add_pic_action()
     {
         CSRFProtection::verifyRequest();
         $success = 0;
@@ -96,15 +108,16 @@ class Admin_LoginStyleController extends AuthenticatedController
                 $fail
             ), $fail));
         }
-        $this->relocate('admin/loginstyle');
+        $this->relocate($this->indexURL());
     }
 
     /**
      * Deletes the given picture.
-     * @param $id the picture to delete
+     * @param string $id the picture to delete
      */
-    public function delete_action($id)
+    public function delete_pic_action($id)
     {
+        CSRFProtection::verifyUnsafeRequest();
         $pic = LoginBackground::find($id);
         if ($pic->in_release) {
             PageLayout::postError(_('Dieses Bild wird vom System mitgeliefert und kann daher nicht gelöscht werden.'));
@@ -114,17 +127,22 @@ class Admin_LoginStyleController extends AuthenticatedController
             PageLayout::postError(_('Das Bild konnte nicht gelöscht werden.'));
         }
 
-        $this->relocate('admin/loginstyle');
+        $this->relocate($this->indexURL());
     }
 
     /**
      * (De-)activate the given picture for given view.
-     * @param $id the picture to change activation for
-     * @param $view one of 'desktop', 'mobile', view to (de-) activate picture for
-     * @param $newStatus new activation status for given view.
+     * @param string $id the picture to change activation for
+     * @param string $view one of 'desktop', 'mobile', view to (de-) activate picture for
+     * @param string $newStatus new activation status for given view.
      */
     public function activation_action($id, $view, $newStatus)
     {
+        CSRFProtection::verifyUnsafeRequest();
+        if (!in_array($view, ['desktop', 'mobile'])) {
+            throw new InvalidArgumentException('You may not change this attribute.');
+        }
+
         $pic = LoginBackground::find($id);
         $pic->$view = $newStatus;
         if ($pic->store()) {
@@ -132,22 +150,74 @@ class Admin_LoginStyleController extends AuthenticatedController
         } else {
             PageLayout::postSuccess(_('Der Aktivierungsstatus konnte nicht gespeichert werden.'));
         }
-        $this->relocate('admin/loginstyle');
+        $this->relocate($this->indexURL());
     }
 
+
     /**
-     * Adds the content to sidebar
+     * FAQ part of login page
      */
-    protected function setSidebar()
+    public function login_faq_action()
     {
-        $sidebar = Sidebar::get();
+        PageLayout::setTitle(_('Hinweise zum Login für den Startbildschirm'));
+
+        $this->setSidebar('login_faq');
+        $this->faq_entries = LoginFaq::findBySql('1');
+    }
+
+    public function edit_faq_action(LoginFaq $entry = null)
+    {
+        PageLayout::setTitle(
+            $entry->isNew() ? _('Hinweistext hinzufügen') : _('Hinweistext bearbeiten')
+        );
+    }
+
+    public function store_faq_action(LoginFaq $entry = null)
+    {
+        CSRFProtection::verifyRequest();
+
+        $entry->setData([
+            'title' => trim(Request::get('title')),
+            'description' => trim(Request::get('description')),
+        ]);
 
+        if ($entry->store()) {
+            PageLayout::postSuccess(_('Hinweistext wurde gespeichert.'));
+        }
+
+        $this->relocate($this->login_faqURL());
+    }
+
+    public function delete_faq_action(LoginFaq $entry)
+    {
+        CSRFProtection::verifyRequest();
+
+        if ($entry->delete()) {
+            PageLayout::postSuccess(_('Der Hinweistext wurde gelöscht.'));
+        }
+
+        $this->relocate($this->login_faqURL());
+    }
+
+    /**
+     * Adds the content to sidebar
+     */
+    protected function setSidebar($action)
+    {
         $links = new ActionsWidget();
-        $links->addLink(
-            _('Bild hinzufügen'),
-            $this->url_for('admin/loginstyle/newpic'),
-            Icon::create('add', 'clickable')
-        )->asDialog('size=auto');
-        $sidebar->addWidget($links);
+        if ($action === 'index') {
+            $links->addLink(
+                _('Bild hinzufügen'),
+                $this->newpicURL(),
+                Icon::create('add')
+            )->asDialog('size=auto');
+        } else if ($action === 'login_faq') {
+            $links->addLink(
+                _('Hinweistext hinzufügen'),
+                $this->edit_faqURL(),
+                Icon::create('add')
+            )->asDialog();
+        }
+        Sidebar::get()->addWidget($links);
     }
 }
diff --git a/app/views/admin/login_style/edit_faq.php b/app/views/admin/login_style/edit_faq.php
new file mode 100644
index 0000000000000000000000000000000000000000..66020a022749d8cf5d1066ede9cf925c1f88240b
--- /dev/null
+++ b/app/views/admin/login_style/edit_faq.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * @var Admin_LoginStyleController $controller
+ * @var LoginFaq $entry
+ */
+?>
+<form action="<?= $controller->store_faq($entry) ?>"
+      method="post"
+      enctype="multipart/form-data"
+      class="default">
+    <?= CSRFProtection::tokenTag() ?>
+
+    <label class="studiprequired">
+        <?= _('Titel') ?>
+        <span title="<?= _('Dies ist ein Pflichtfeld') ?>" aria-hidden="true" class="asterisk">*</span>
+        <input type="text" name="title" value="<?= htmlReady($entry->title) ?>" required>
+    </label>
+
+    <label class="studiprequired">
+        <?= _('Text') ?>
+        <span title="<?= _('Dies ist ein Pflichtfeld') ?>" aria-hidden="true" class="asterisk">*</span>
+        <textarea name="description"
+                  class="add_toolbar wysiwyg" data-editor="toolbar=minimal"><?= htmlReady($entry->description)?></textarea>
+    </label>
+
+    <div data-dialog-button>
+        <?= \Studip\Button::create(_('Speichern')) ?>
+    </div>
+
+</form>
diff --git a/app/views/admin/login_style/index.php b/app/views/admin/login_style/index.php
index 195cc6a9fc7c398f54168a5e60a0359ec3a65b27..24c0b703f08f8b8387aee1e6c00973e82d3b88f2 100644
--- a/app/views/admin/login_style/index.php
+++ b/app/views/admin/login_style/index.php
@@ -4,28 +4,31 @@
  * @var Admin_LoginStyleController $controller
  */
 ?>
-<? if (count($pictures) > 0) : ?>
+<form method="post">
+    <?= CSRFProtection::tokenTag(); ?>
+
+    <? if (count($pictures) > 0) : ?>
     <table class="default">
         <caption>
             <?= _('Hintergrundbilder für den Startbildschirm') ?>
         </caption>
         <colgroup>
             <col>
-            <col width="400">
-            <col width="100">
-            <col width="25">
+            <col style="width: 400px">
+            <col style="width: 100px">
+            <col style="width: 25px">
         </colgroup>
         <thead>
-            <tr>
-                <th><?= _('Info') ?></th>
-                <th><?= _('Vorschau') ?></th>
-                <th><?= _('Aktiviert für') ?></th>
-                <th><?= _('Aktionen') ?></th>
-            </tr>
+        <tr>
+            <th><?= _('Info') ?></th>
+            <th><?= _('Vorschau') ?></th>
+            <th><?= _('Aktiviert für') ?></th>
+            <th><?= _('Aktionen') ?></th>
+        </tr>
         </thead>
         <? foreach ($pictures as $pic) :
             $dim = $pic->getDimensions();
-        ?>
+            ?>
             <tr>
                 <td>
                     <?= htmlReady($pic->filename) ?>
@@ -37,34 +40,41 @@
                     <img src="<?= $pic->getURL() ?>" width="400">
                 </td>
                 <td>
-                    <a href="<?= $controller->link_for("admin/loginstyle/activation/{$pic->id}/desktop", (int) !$pic->desktop) ?>">
-                        <?= Icon::create('computer', $pic->desktop ? Icon::ROLE_CLICKABLE : Icon::ROLE_INACTIVE)->asImg(32, [
-                            'title' => $pic->desktop
-                                     ? _('Bild nicht mehr für die Desktopansicht verwenden')
-                                     : _('Bild für die Desktopansicht verwenden')
-                        ]) ?>
-                    </a>
-                    <a href="<?= $controller->link_for("admin/loginstyle/activation/{$pic->id}/mobile", (int) !$pic->mobile) ?>">
-                        <?= Icon::create('cellphone', $pic->mobile ? Icon::ROLE_CLICKABLE : Icon::ROLE_INACTIVE)->asImg(32, [
+                    <?= Icon::create('computer', $pic->desktop ? Icon::ROLE_CLICKABLE : Icon::ROLE_INACTIVE)->asInput(
+                        32,
+                        [
+                            'title' => $pic->mobile
+                                ? _('Bild nicht mehr für die Mobilansicht verwenden')
+                                : _('Bild für die Mobilansicht verwenden'),
+                            'formaction' => $controller->activationURL($pic->id, 'desktop', (int) !$pic->desktop)
+                        ]
+                    )?>
+
+                    <?= Icon::create('cellphone', $pic->mobile ? Icon::ROLE_CLICKABLE : Icon::ROLE_INACTIVE)->asInput(
+                        32,
+                        [
                             'title' => $pic->mobile
-                                     ? _('Bild nicht mehr für die Mobilansicht verwenden')
-                                     : _('Bild für die Mobilansicht verwenden')
-                        ]) ?>
-                    </a>
+                                ? _('Bild nicht mehr für die Mobilansicht verwenden')
+                                : _('Bild für die Mobilansicht verwenden'),
+                            'formaction' => $controller->activationURL($pic->id, 'mobile', (int) !$pic->mobile)
+                        ]
+                    )?>
                 </td>
                 <td class="actions">
-                <? if (!$pic->in_release): ?>
-                    <a href="<?= $controller->link_for("admin/loginstyle/delete/{$pic->id}") ?>">
-                        <?= Icon::create('trash')->asImg([
-                            'title'        => _('Bild löschen'),
-                            'data-confirm' => _('Soll das Bild wirklich gelöscht werden?'),
-                        ]) ?>
-                    </a>
-                <? endif; ?>
+                    <? if (!$pic->in_release): ?>
+                        <?= Icon::create('trash')->asInput(
+                            [
+                                'title'        => _('Bild löschen'),
+                                'data-confirm' => _('Soll das Bild wirklich gelöscht werden?'),
+                                'formaction' => $controller->delete_picURL($pic->id)
+                            ]
+                        )?>
+                    <? endif ?>
                 </td>
             </tr>
         <? endforeach ?>
     </table>
-<? else : ?>
+    <? else : ?>
     <?= MessageBox::info(_('In Ihrem System sind leider keine Bilder für den Startbildschirm hinterlegt.')) ?>
-<? endif ?>
+    <? endif ?>
+</form>
diff --git a/app/views/admin/login_style/login_faq.php b/app/views/admin/login_style/login_faq.php
new file mode 100644
index 0000000000000000000000000000000000000000..4ed19e19adc5587f2f176a54492edf3bba885edf
--- /dev/null
+++ b/app/views/admin/login_style/login_faq.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * @var Admin_LoginStyleController $controller
+ * @var LoginFaq[] $faq_entries
+ */
+?>
+<form method="post">
+    <?= CSRFProtection::tokenTag() ?>
+    <table class="default">
+        <caption><?= _('Hinweise zum Login') ?></caption>
+        <thead>
+        <tr>
+            <th><?= _('Titel') ?></th>
+            <th class="actions"><?= _('Aktionen') ?></th>
+        </tr>
+        </thead>
+        <tbody>
+        <? if (count($faq_entries) > 0) : ?>
+            <? foreach ($faq_entries as $entry) : ?>
+                <tr>
+                    <td><?= htmlReady($entry->title) ?></td>
+                    <td class="actions">
+                        <?= ActionMenu::get()
+                            ->setContext($entry->title)
+                            ->addLink(
+                                $controller->edit_faqURL($entry),
+                                _('Hinweistext bearbeiten'),
+                                Icon::create('edit'),
+                                ['data-dialog' => 'size=medium']
+                            )->addButton(
+                                'delete',
+                                _('Hinweistext löschen'),
+                                Icon::create('trash'),
+                                [
+                                    'formaction'   => $controller->delete_faqURL($entry),
+                                    'data-confirm' => sprintf(
+                                        _('Wollen Sie den Hinweistext "%s" wirklich löschen?'),
+                                        $entry->title
+                                    ),
+                                    'data-dialog'  => 'size=auto',
+                                ]
+                            )
+                        ?>
+                    </td>
+                </tr>
+            <? endforeach ?>
+        <? else : ?>
+            <tr>
+                <td colspan="3" style="text-align: center">
+                    <?= _('Keine Hinweistexte vorhanden') ?>
+                </td>
+            </tr>
+        <? endif ?>
+        </tbody>
+
+    </table>
+</form>
diff --git a/app/views/admin/login_style/newpic.php b/app/views/admin/login_style/newpic.php
index d5bc74a677c199c82538feacf30402782896de53..c5f7fbf0c4ea071cf575b04ae9394f7f8efd0c28 100644
--- a/app/views/admin/login_style/newpic.php
+++ b/app/views/admin/login_style/newpic.php
@@ -3,7 +3,8 @@
  * @var Admin_LoginStyleController $controller
  */
 ?>
-<form class="default" action="<?= $controller->link_for('admin/loginstyle/add') ?>" method="post" enctype="multipart/form-data">
+<form class="default" action="<?= $controller->add_pic() ?>" method="post" enctype="multipart/form-data">
+    <?= CSRFProtection::tokenTag() ?>
     <fieldset>
         <legend>
             <?= _('Bild(er) hinzufügen') ?>
@@ -33,6 +34,6 @@
     <footer data-dialog-button>
         <?= CSRFProtection::tokenTag() ?>
         <?= Studip\Button::createAccept(_('Speichern'), 'store') ?>
-        <?= Studip\LinkButton::createCancel(_('Abbrechen'), $controller->url_for('loginstyle/index')) ?>
+        <?= Studip\LinkButton::createCancel(_('Abbrechen'), $controller->indexURL()) ?>
     </footer>
 </form>
diff --git a/app/views/new_password/index.php b/app/views/new_password/index.php
index 9cddc31719eadaf6fa8e5446ab71b4f2bd56a361..d0446291099684952a24f181ac1d40e77898c6d8 100644
--- a/app/views/new_password/index.php
+++ b/app/views/new_password/index.php
@@ -6,7 +6,7 @@
         </legend>
 
         <label>
-            <?= _('Geben sie die Mail-Adresse des Zugangs an, für den sie das Passwort zurücksetzen möchten') ?>
+            <?= _('Geben Sie die Mail-Adresse des Zugangs an, für den Sie das Passwort zurücksetzen möchten') ?>
             <input type="text" name="mail" placeholder="<?= _('Ihre Mail-Adresse') ?>" required>
         </label>
     </fieldset>
diff --git a/db/migrations/5.5.16_add_tooltip_fields_for_login.php b/db/migrations/5.5.16_add_tooltip_fields_for_login.php
new file mode 100644
index 0000000000000000000000000000000000000000..f4d536b41da6e551c7a9ece6d15bba8d655a9818
--- /dev/null
+++ b/db/migrations/5.5.16_add_tooltip_fields_for_login.php
@@ -0,0 +1,71 @@
+<?php
+
+
+class AddTooltipFieldsForLogin extends Migration
+{
+    public function description()
+    {
+        return 'Creates config for login username and password tooltip texts';
+    }
+
+    public function up()
+    {
+        $query = 'INSERT INTO `config` (`field`, `value`, `type`, `section`, `range`, `description`, `mkdate`, `chdate`)
+                  VALUES (:name, :value, :type, :section, :range, :description, UNIX_TIMESTAMP(), UNIX_TIMESTAMP())';
+        $statement = DBManager::get()->prepare($query);
+        $statement->execute([
+            'name'          => 'USERNAME_TOOLTIP_TEXT',
+            'value'         => 'Geben Sie hier Ihren Stud.IP-Benutzernamen ein.',
+            'type'          => 'i18n',
+            'section'       => 'Loginseite',
+            'range'         => 'global',
+            'description'   => 'Text für den Tooltip des Benutzernamens auf der Loginseite'
+        ]);
+
+        $statement->execute([
+            'name'          => 'PASSWORD_TOOLTIP_TEXT',
+            'value'         => 'Geben Sie hier Ihr Stud.IP-Passwort ein. Achten Sie bei der Eingabe auf Groß- und Kleinschreibung.',
+            'type'          => 'i18n',
+            'section'       => 'Loginseite',
+            'range'         => 'global',
+            'description'   => 'Text für den Tooltip des Benutzernamens auf der Loginseite'
+        ]);
+
+        $statement->execute([
+            'name'          => 'USERNAME_TOOLTIP_ACTIVATED',
+            'value'         => '1',
+            'type'          => 'boolean',
+            'section'       => 'Loginseite',
+            'range'         => 'global',
+            'description'   => 'Soll der Tooltip beim Benutzernamen auf der Loginseite sichtbar sein?'
+        ]);
+
+        $statement->execute([
+            'name'          => 'PASSWORD_TOOLTIP_ACTIVATED',
+            'value'         => '1',
+            'type'          => 'boolean',
+            'section'       => 'Loginseite',
+            'range'         => 'global',
+            'description'   => 'Soll der Tooltip beim Passwort auf der Loginseite sichtbar sein?'
+        ]);
+
+    }
+
+    public function down()
+    {
+        $query = "DELETE `config`, `config_values`, `i18n`
+                  FROM `config`
+                  LEFT JOIN `config_values` USING (`field`)
+                  LEFT JOIN `i18n`
+                    ON `table` = 'config'
+                        AND `field` = 'value'
+                        AND `object_id` = MD5(`config`.`field`)
+                  WHERE `field` IN (
+                       'USERNAME_TOOLTIP_TEXT',
+                       'PASSWORD_TOOLTIP_TEXT',
+                       'USERNAME_TOOLTIP_ACTIVATED',
+                       'PASSWORD_TOOLTIP_ACTIVATED'
+                  )";
+        DBManager::get()->exec($query);
+    }
+}
diff --git a/db/migrations/5.5.17_add_login_faq_table.php b/db/migrations/5.5.17_add_login_faq_table.php
new file mode 100644
index 0000000000000000000000000000000000000000..2a999099ddff059cf64993edc56c3b9cdb7df0df
--- /dev/null
+++ b/db/migrations/5.5.17_add_login_faq_table.php
@@ -0,0 +1,29 @@
+<?php
+
+class AddLoginFaqTable extends Migration
+{
+    public function description()
+    {
+        return 'Create table for login page FAQ';
+    }
+
+    public function up()
+    {
+        $query = "CREATE TABLE IF NOT EXISTS `login_faq` (
+                    `faq_id` int(11) NOT NULL AUTO_INCREMENT,
+                    `title` varchar(255) NOT NULL,
+                    `description` text NOT NULL,
+                    PRIMARY KEY (`faq_id`)
+                  )";
+        DBManager::get()->exec($query);
+    }
+
+    public function down()
+    {
+        DBManager::get()->exec('DROP TABLE IF EXISTS `login_faq`');
+
+        $query = "DELETE FROM `i18n`
+                  WHERE `table` = 'login_faq`";
+        DBManager::get()->exec($query);
+    }
+}
diff --git a/db/migrations/5.5.18_add_login_faq_config.php b/db/migrations/5.5.18_add_login_faq_config.php
new file mode 100644
index 0000000000000000000000000000000000000000..3196e34e6a43d71441d964b81726b6a8ce6c4bc4
--- /dev/null
+++ b/db/migrations/5.5.18_add_login_faq_config.php
@@ -0,0 +1,53 @@
+<?php
+
+
+class AddLoginFaqConfig extends Migration
+{
+    public function description()
+    {
+        return 'Creates configs for login faq: Visibility and title (eg.: Hilfe zum Login)';
+    }
+
+    public function up()
+    {
+        $query = 'INSERT INTO `config` (`field`, `value`, `type`, `section`, `range`, `description`, `mkdate`, `chdate`)
+                  VALUES (:name, :value, :type, :section, :range, :description, UNIX_TIMESTAMP(), UNIX_TIMESTAMP())';
+        $statement = DBManager::get()->prepare($query);
+        $statement->execute([
+            'name'          => 'LOGIN_FAQ_TITLE',
+            'value'         => 'Hinweise zum Login',
+            'type'          => 'i18n',
+            'section'       => 'Loginseite',
+            'range'         => 'global',
+            'description'   => 'Überschrift für den FAQ-Bereich auf der Loginseite'
+        ]);
+
+        $statement->execute([
+            'name'          => 'LOGIN_FAQ_VISIBILITY',
+            'value'         => '1',
+            'type'          => 'boolean',
+            'section'       => 'Loginseite',
+            'range'         => 'global',
+            'description'   => 'Soll der FAQ-Bereich auf der Loginseite sichtbar sein?'
+        ]);
+
+    }
+
+    public function down()
+    {
+        $query = "DELETE `config`, `config_values`, `i18n`
+                  FROM `config`
+                  LEFT JOIN `config_values` USING (`field`)
+                  LEFT JOIN `i18n`
+                    ON `table` = 'config'
+                        AND `field` = 'value'
+                        AND `object_id` = MD5(`config`.`field`)
+                  WHERE `field` IN (
+                       'LOGIN_FAQ_TITLE',
+                       'LOGIN_FAQ_VISIBILITY',
+                       'USERNAME_TOOLTIP_ACTIVATED',
+                       'PASSWORD_TOOLTIP_ACTIVATED'
+                  )";
+        DBManager::get()->exec($query);
+    }
+}
diff --git a/lib/classes/auth_plugins/CASUserDataMapping.php b/lib/classes/auth_plugins/CASUserDataMapping.php
index 03c9cd2beba9b47cee4de63a930dc971c34b7605..166df55fbf671bfb7f096d8ce42da6a6d777e964 100644
--- a/lib/classes/auth_plugins/CASUserDataMapping.php
+++ b/lib/classes/auth_plugins/CASUserDataMapping.php
@@ -1,4 +1,4 @@
-<?
+<?php
 # Lifter007: TODO
 # Lifter003: TODO
 # Lifter010: TODO
@@ -10,4 +10,3 @@ interface CASUserDataMapping {
     // reads one attribute identified by a key of a given user
     function getUserData ($key, $username);
 }
-?>
\ No newline at end of file
diff --git a/lib/classes/auth_plugins/StudipAuthAbstract.class.php b/lib/classes/auth_plugins/StudipAuthAbstract.class.php
index d1bcfac6080340c6772afc3d49a166cb857e8615..fd2d4e9aaff48eede1462ce8cb815e2330c305dd 100644
--- a/lib/classes/auth_plugins/StudipAuthAbstract.class.php
+++ b/lib/classes/auth_plugins/StudipAuthAbstract.class.php
@@ -90,6 +90,14 @@ class StudipAuthAbstract
      */
     public $error_head;
 
+    /**
+     * toggles display of standard login
+     *
+     *
+     * @var      bool $show_login
+     */
+    public $show_login;
+
     /**
      * @var $plugin_instances
      */
@@ -120,6 +128,38 @@ class StudipAuthAbstract
         return ($plugin_name) ? self::$plugin_instances[strtoupper($plugin_name)] : self::$plugin_instances;
     }
 
+    /**
+     * static method to check if SSO login is enabled
+     *
+     * @return bool
+     */
+    public static function isSSOEnabled(): bool
+    {
+        self::getInstance();
+        foreach (self::$plugin_instances as $auth_plugin) {
+            if ($auth_plugin instanceof StudipAuthSSO) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * static method to check if standard login is enabled
+     *
+     * @return bool
+     */
+    public static function isLoginEnabled(): bool
+    {
+        self::getInstance();
+        foreach (self::$plugin_instances as $auth_plugin) {
+            if ($auth_plugin->show_login === true) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * static method to check authentication in all plugins
      *
diff --git a/lib/classes/auth_plugins/StudipAuthLdap.class.php b/lib/classes/auth_plugins/StudipAuthLdap.class.php
index 5721cf44e87980166f901dc3d85062ae80dbca32..7cb8686002852a6b67fa2f4c49bb5c9760388ff0 100644
--- a/lib/classes/auth_plugins/StudipAuthLdap.class.php
+++ b/lib/classes/auth_plugins/StudipAuthLdap.class.php
@@ -40,6 +40,7 @@ class StudipAuthLdap extends StudipAuthAbstract
     public $username_attribute = 'uid';
     public $ldap_filter;
     public $bad_char_regex = '/[^0-9_a-zA-Z]/';
+    public $show_login = true;
 
     public $conn = null;
     public $user_data = null;
diff --git a/lib/classes/auth_plugins/StudipAuthStandard.class.php b/lib/classes/auth_plugins/StudipAuthStandard.class.php
index 1a2c2bae5569f73a6d41f150ffe841e70867325d..5bb3e65f0dbb66adb6e404427da974d022f09389 100644
--- a/lib/classes/auth_plugins/StudipAuthStandard.class.php
+++ b/lib/classes/auth_plugins/StudipAuthStandard.class.php
@@ -37,6 +37,7 @@ class StudipAuthStandard extends StudipAuthAbstract
 {
 
     var $bad_char_regex =  false;
+    public $show_login = true;
 
     /**
     *
diff --git a/lib/models/LoginFaq.class.php b/lib/models/LoginFaq.class.php
new file mode 100644
index 0000000000000000000000000000000000000000..036f0f73178283b8992de27e6e3b88416c828ee1
--- /dev/null
+++ b/lib/models/LoginFaq.class.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * LoginFaq.class.php
+ * model class for table login_faq
+ *
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * @author      Michaela Brückner <brueckner@data-quest.de>
+ * @copyright   2023 data-quest
+ * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
+ * @category    Stud.IP
+ * @since       5.5
+*/
+class LoginFaq extends SimpleORMap
+{
+    /**
+     * @param array $config
+     */
+    protected static function configure($config = [])
+    {
+        $config['db_table'] = 'login_faq';
+
+    $config['i18n'] = ['title', 'description'];
+
+        parent::configure($config);
+    }
+}
diff --git a/lib/navigation/AdminNavigation.php b/lib/navigation/AdminNavigation.php
index 12bf53adfe4ffb08aebb66e5d6155ac5f1f02670..7d9cd2d391d97df911cfdbe44125a328d2f0fdca 100644
--- a/lib/navigation/AdminNavigation.php
+++ b/lib/navigation/AdminNavigation.php
@@ -110,7 +110,6 @@ class AdminNavigation extends Navigation
             }
 
             $navigation->addSubNavigation('sem_classes', new Navigation(_('Veranstaltungskategorien'), 'dispatch.php/admin/sem_classes/overview'));
-            $navigation->addSubNavigation('loginstyle', new Navigation(_('Startbildschirm'), 'dispatch.php/admin/loginstyle'));
             $navigation->addSubNavigation(
                 'content_terms_of_use',
                 new Navigation(
@@ -157,7 +156,6 @@ class AdminNavigation extends Navigation
                     'dispatch.php/admin/accessibility_info_text/index'
                 )
             );
-
         }
 
         if ($GLOBALS['perm']->have_perm('admin')) {
@@ -165,6 +163,17 @@ class AdminNavigation extends Navigation
             $navigation->addSubNavigation('stock_images', $pool);
         }
 
+        if ($perm->have_perm('root')) {
+            $navigation->addSubNavigation(
+                'loginstyle',
+                new Navigation(
+                    _('Startseite'),
+                    'dispatch.php/admin/login_style'
+                )
+            );
+
+        }
+
         $this->addSubNavigation('locations', $navigation);
 
         // global config / user administration
diff --git a/lib/navigation/LoginNavigation.php b/lib/navigation/LoginNavigation.php
index db212364ccc0141dd244624231f51318b40172f9..96ec90ed8979128d05027795ec5a8c7c4844bc84 100644
--- a/lib/navigation/LoginNavigation.php
+++ b/lib/navigation/LoginNavigation.php
@@ -23,13 +23,20 @@ class LoginNavigation extends Navigation
     {
         parent::initSubNavigation();
 
-        $navigation = new Navigation(_('Login'), 'index.php?again=yes');
-        $navigation->setDescription(_('für registrierte NutzerInnen'));
-        $this->addSubNavigation('login', $navigation);
-
+        $standard_login_active = false;
         foreach (StudipAuthAbstract::getInstance() as $auth_plugin) {
+            if ($auth_plugin->show_login && !$standard_login_active) {
+                $navigation = new Navigation(_('Login'), '');
+                $navigation->setDescription($auth_plugin->login_description ?: _('für registrierte Nutzende'));
+                $navigation->setLinkAttributes([
+                    'id' => 'toggle-login'
+                ]);
+                $navigation->setURL('#login-form');
+                $this->addSubNavigation('standard_login', $navigation);
+                $standard_login_active = true;
+            }
             if ($auth_plugin instanceof StudipAuthSSO && isset($auth_plugin->login_description)) {
-                $navigation = new Navigation($auth_plugin->plugin_fullname . ' ' . _('Login'), 'index.php?again=yes&sso=' . $auth_plugin->plugin_name);
+                $navigation = new Navigation($auth_plugin->plugin_fullname . ' ' . _('Login'), '?sso=' . $auth_plugin->plugin_name);
                 $navigation->setDescription($auth_plugin->login_description);
                 $this->addSubNavigation('login_' . $auth_plugin->plugin_name, $navigation);
             }
@@ -37,7 +44,7 @@ class LoginNavigation extends Navigation
 
         if (Config::get()->ENABLE_SELF_REGISTRATION) {
             $navigation = new Navigation(_('Registrieren'), 'register1.php');
-            $navigation->setDescription(_('um NutzerIn zu werden'));
+            $navigation->setDescription(_('um das System erstmalig zu nutzen'));
             $this->addSubNavigation('register', $navigation);
         }
 
diff --git a/lib/navigation/StartNavigation.php b/lib/navigation/StartNavigation.php
index 3d3719e818b2dcbe0de53e73a84d3c655ecc76e7..df94412420ebe5b80f836bb6d01021a52cc3dd9e 100644
--- a/lib/navigation/StartNavigation.php
+++ b/lib/navigation/StartNavigation.php
@@ -22,7 +22,7 @@ class StartNavigation extends Navigation
     {
         $url = (is_object($GLOBALS['user']) && $GLOBALS['user']->id != 'nobody')
              ? 'dispatch.php/start'
-             : 'index.php';
+             : 'index.php?again=yes';
         parent::__construct(_('Start'), $url);
     }
 
diff --git a/lib/phplib/Seminar_Auth.class.php b/lib/phplib/Seminar_Auth.class.php
index 30a6d4677198c82d83e5ecfa46a6fa1d443d61da..80f6ceaf0196ea9cc3988798399388a2474cc342 100644
--- a/lib/phplib/Seminar_Auth.class.php
+++ b/lib/phplib/Seminar_Auth.class.php
@@ -301,6 +301,27 @@ class Seminar_Auth
             throw new AccessDeniedException();
         }
 
+        // if desired, switch to high contrast stylesheet and store when user logs in
+        if (Request::get('unset_contrast')) {
+            unset($_SESSION['contrast']);
+            PageLayout::removeStylesheet('accessibility.css');
+
+        }
+        if (Request::get('set_contrast') ) {
+            $_SESSION['contrast'] = true;
+            PageLayout::addStylesheet('accessibility.css');
+
+        }
+
+        // evaluate language clicks
+        // has to be done before seminar_open to get switching back to german (no init of i18n at all))
+        if (Request::get('set_language')) {
+            if (array_key_exists(Request::get('set_language'), $GLOBALS['INSTALLED_LANGUAGES'])) {
+                $_SESSION['forced_language'] = Request::get('set_language');
+                $_SESSION['_language'] = Request::get('set_language');
+            }
+        }
+
         $this->check_environment();
 
         PageLayout::setBodyElementId('login');
@@ -322,6 +343,13 @@ class Seminar_Auth
             $login_template->set_attribute('error_msg', $this->error_msg);
             $login_template->set_attribute('uname', (isset($this->auth["uname"]) ? $this->auth["uname"] : Request::username('loginname')));
             $login_template->set_attribute('self_registration_activated', Config::get()->ENABLE_SELF_REGISTRATION);
+
+            $query = "SHOW TABLES LIKE 'login_faq'";
+            $result = DBManager::get()->query($query);
+
+            if ($result && $result->rowCount() > 0) {
+                $login_template->set_attribute('faq_entries', LoginFaq::findBySQL("1"));
+            }
         }
         PageLayout::setHelpKeyword('Basis.AnmeldungLogin');
         $header_template = $GLOBALS['template_factory']->open('header');
diff --git a/lib/seminar_open.php b/lib/seminar_open.php
index c3e15c35fbcdb496ab73882584c32170d52b4aa4..0ca99918017a24374a750c9ac62afb968618dad7 100644
--- a/lib/seminar_open.php
+++ b/lib/seminar_open.php
@@ -105,6 +105,13 @@ if ($auth->is_authenticated() && is_object($user) && $user->id != "nobody") {
             UserConfig::get($GLOBALS['user']->id)->store('USER_HIGH_CONTRAST', $_SESSION['contrast']);
             unset($_SESSION['contrast']);
         }
+        // store last language click
+        if (!empty($_SESSION['forced_language'])) {
+            User::findCurrent()->preferred_language = $_SESSION['forced_language'];
+            User::findCurrent()->store();
+            $_SESSION['_language'] = $_SESSION['forced_language'];
+        }
+        $_SESSION['forced_language'] = null;
         $user_did_login = true;
     }
 
diff --git a/locale/en/LC_MESSAGES/studip.po b/locale/en/LC_MESSAGES/studip.po
index 0ff799a8531a1098982aad72ece1d3ae5791be95..29266c919917ffc7a121508da34bdb3829fa00bc 100644
--- a/locale/en/LC_MESSAGES/studip.po
+++ b/locale/en/LC_MESSAGES/studip.po
@@ -41881,7 +41881,7 @@ msgid "Sie haben keine alten empfangenen Nachrichten"
 msgstr "You do not have any old received messages"
 
 #: lib/navigation/LoginNavigation.php:27
-msgid "für registrierte NutzerInnen"
+msgid "für registrierte Nutzende"
 msgstr "for registered users"
 
 #: lib/navigation/LoginNavigation.php:40
diff --git a/public/index.php b/public/index.php
index c32fe49d4c1c180dc4841e8fc0cfd137cb8ebfed..2a383556db865c2de2080771dcd83d3dec0055d2 100644
--- a/public/index.php
+++ b/public/index.php
@@ -59,51 +59,9 @@ if ($auth->is_authenticated() && $user->id != 'nobody') {
 closeObject();
 
 include 'lib/seminar_open.php'; // initialise Stud.IP-Session
+$auth->login_if($user->id === 'nobody');
 
 // if new start page is in use, redirect there (if logged in)
 if ($auth->is_authenticated() && $user->id != 'nobody') {
     header('Location: ' . URLHelper::getURL('dispatch.php/start'));
-    die;
 }
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * *   L O G I N - P A G E   ( N O B O D Y - U S E R )   * *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-PageLayout::setHelpKeyword("Basis.Startseite"); // set keyword for new help
-PageLayout::setTitle(_("Startseite"));
-Navigation::activateItem('/start');
-PageLayout::setTabNavigation(NULL); // disable display of tabs
-
-// Start of Output
-include 'lib/include/html_head.inc.php'; // Output of html head
-include 'lib/include/header.php';
-
-// Prüfen, ob PortalPlugins vorhanden sind.
-// TODO: Remove for Stud.IP 6.0
-/** @deprecated */
-$portalplugins = PluginEngine::getPlugins('PortalPlugin');
-$layout = $GLOBALS['template_factory']->open('shared/index_box');
-
-$plugin_contents = [];
-foreach ($portalplugins as $portalplugin) {
-    $template = $portalplugin->getPortalTemplate();
-
-    if ($template) {
-        $plugin_contents[] = $template->render(NULL, $layout);
-        $layout->clear_attributes();
-    }
-}
-
-
-$index_nobody_template = $GLOBALS['template_factory']->open('index_nobody');
-$index_nobody_template->set_attributes([
-    'plugin_contents'  => $plugin_contents,
-    'logout'           =>  Request::bool('logout'),
-]);
-
-echo $index_nobody_template->render();
-
-page_close();
-
-include 'lib/include/html_end.inc.php';
diff --git a/resources/assets/javascripts/bootstrap/application.js b/resources/assets/javascripts/bootstrap/application.js
index 1629b9baec47e6d972461069284207cc2e9fd92a..830f2c025f2a588513c6ae9a48da7d0c3c9bbdef 100644
--- a/resources/assets/javascripts/bootstrap/application.js
+++ b/resources/assets/javascripts/bootstrap/application.js
@@ -355,3 +355,68 @@ jQuery(document).on('click', 'a[data-behaviour~="ajax-toggle"]', function (event
         $('#open_variable').attr('value', $(this).parent('fieldset').data('open'));
     });
 }(jQuery));
+
+STUDIP.domReady(function () {
+    const loginForm = document.getElementById('login-form');
+    if (!loginForm) {
+        return;
+    }
+
+    const passwordInput = document.getElementById('password');
+    const usernameInput = document.getElementById('loginname');
+    const passwordCapsText = document.getElementById('password-caps');
+    const iconPasswordVisible = document.getElementById('visible-password');
+    const iconPasswordInVisible = document.getElementById('invisible-password');
+
+    [usernameInput, passwordInput].forEach((input) => {
+        input.addEventListener('keydown', (event) => {
+            if (event.getModifierState('CapsLock')) {
+                passwordCapsText.style.display = 'block';
+            } else {
+                passwordCapsText.style.display = 'none';
+            }
+        });
+    });
+
+    const toggleLogin = document.getElementById('toggle-login');
+    if (toggleLogin) {
+        loginForm.addEventListener('transitionend', (event) => {
+            if (event.propertyName !== 'max-height') {
+                return;
+            }
+
+            if (!loginForm.classList.contains('hide')) {
+                usernameInput.scrollIntoView({
+                    behavior: 'smooth'
+                });
+                usernameInput.focus();
+            } else {
+                loginForm.setAttribute('hidden', '');
+            }
+        });
+
+        toggleLogin.addEventListener('click', (event) => {
+            if (loginForm.classList.contains('hide')) {
+                loginForm.removeAttribute('hidden');
+            }
+
+            setTimeout(() => {
+                loginForm.classList.toggle('hide');
+            }, 0);
+
+            event.preventDefault();
+        });
+    }
+
+    document.getElementById('password-toggle').addEventListener('click', () => {
+        if (passwordInput.type === 'password') {
+            passwordInput.type = 'text';
+            iconPasswordVisible.style.display = 'none';
+            iconPasswordInVisible.style.display = '';
+        } else {
+            passwordInput.type = 'password';
+            iconPasswordVisible.style.display = '';
+            iconPasswordInVisible.style.display = 'none';
+        }
+    });
+});
diff --git a/resources/assets/stylesheets/scss/index.scss b/resources/assets/stylesheets/scss/index.scss
index 2ecda5c36d4999835c741955075aa814612a3ef8..e9234de30b0c9826f1df8ed34bb2d82a50daf671 100644
--- a/resources/assets/stylesheets/scss/index.scss
+++ b/resources/assets/stylesheets/scss/index.scss
@@ -13,6 +13,16 @@ $gap-between-boxes: calc($login-page-margin / 2);
 #content {
     grid-column: 1 / 3;
     grid-row: 2 / 2;
+
+    &.loginpage {
+        display: flex;
+        flex-direction: row;
+        flex-wrap: wrap;
+        column-gap: 20px;
+        row-gap: 20px;
+        align-items: flex-start;
+        flex-basis: 450px;
+    }
 }
 
 #background-desktop {
@@ -36,14 +46,24 @@ $gap-between-boxes: calc($login-page-margin / 2);
     }
 }
 
+#login_flex {
+    display: flex;
+    flex-direction: row;
+    column-gap: 20px;
+    flex-wrap: wrap;
+    row-gap: 20px;
+    align-items: flex-start;
+}
+
 #loginbox {
-    background-color: rgba(255, 255, 255, 0.8);
-    box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.5);
+    background-color: var(--white);
+    box-shadow: 0 0 8px rgba(0, 0, 0, 0.5);
     padding: 20px;
     width: 450px;
+    float: left;
 
     header {
-        margin: 10px 0 0 10px;
+        margin: 0 0 0 0;
 
         h1 {
             border-bottom: 0;
@@ -56,7 +76,7 @@ $gap-between-boxes: calc($login-page-margin / 2);
             list-style-type: none;
             margin: 0;
             width: 450px;
-            padding: 0 10px;
+            padding-inline-start: 0;
 
             .login_link {
                 display: inline-block;
@@ -93,6 +113,10 @@ $gap-between-boxes: calc($login-page-margin / 2);
             }
         }
 
+        #contrast {
+            padding-bottom: 0;
+        }
+
         div.login_info {
             border-top: 1px solid var(--light-gray-color);
             font-size: 0.8em;
@@ -110,6 +134,38 @@ $gap-between-boxes: calc($login-page-margin / 2);
             margin-left: 12px;
         }
     }
+
+
+    input#loginname,
+    input#password {
+        display: initial;
+    }
+
+    input#password {
+        padding-right: 28px;
+    }
+
+    #password-toggle {
+        position: absolute;
+        right: 7px;
+        bottom: 0;
+        cursor: pointer;
+
+        #visible-password,
+        #invisible-password {
+        }
+    }
+}
+
+#faq_box {
+    background-color: var(--white);
+    box-shadow: 0 0 8px rgba(0, 0, 0, 0.5);
+    padding: 20px;
+    width: 450px;
+    float: left;
+    > header {
+        margin: 0 0 0 0;
+    }
 }
 
 #login-plugin-contents {
@@ -128,3 +184,24 @@ $gap-between-boxes: calc($login-page-margin / 2);
         width: 418px;
     }
 }
+
+::-ms-reveal {
+    display: none;
+}
+
+
+#login-form {
+    max-height: 300px;
+    overflow: hidden;
+    transition: max-height var(--transition-duration-slow) linear;
+
+    &.hide {
+        max-height: 0px;
+    }
+
+    #submit_login {
+        margin-top: 0 !important;
+        float: left !important;
+
+    }
+}
diff --git a/resources/assets/stylesheets/scss/responsive.scss b/resources/assets/stylesheets/scss/responsive.scss
index a1f2a6750795cbc5ab59c6b0a4b7e8181f245721..01c7403017802befae0a3700d27abaadc9af8150 100644
--- a/resources/assets/stylesheets/scss/responsive.scss
+++ b/resources/assets/stylesheets/scss/responsive.scss
@@ -897,7 +897,8 @@ html:not(.responsive-display):not(.fullscreen-mode) {
             left: 0;
         }
 
-        #loginbox {
+        #loginbox,
+        #faq_box {
             box-shadow: unset;
             margin: 0;
             width: calc(100vw - 40px);
@@ -912,6 +913,10 @@ html:not(.responsive-display):not(.fullscreen-mode) {
                 }
             }
         }
+
+        #faq_box {
+            margin: -20px 0 0 0;
+        }
     }
 }
 
diff --git a/resources/assets/stylesheets/scss/variables.scss b/resources/assets/stylesheets/scss/variables.scss
index ef5329eb9b21c247ad9253a664c1b101283dbb98..a915e766f6a0b25edc8fc2e1653f052d132b6c20 100644
--- a/resources/assets/stylesheets/scss/variables.scss
+++ b/resources/assets/stylesheets/scss/variables.scss
@@ -43,6 +43,7 @@ $drag_and_drop_z_index: 1000;
 $drag_and_drop_border: 1px solid $base-color;
 
 $transition-duration: .3s;
+$transition-duration-slow: .5s;
 
 // Layout
 $page-margin: 15px;
@@ -171,8 +172,10 @@ $grid-gap: 0;
     #{"--"}group-color-8: $brown;
 
     #{"--"}transition-duration: $transition-duration;
+    #{"--"}transition-duration-slow: $transition-duration-slow;
 
     @media (prefers-reduced-motion) {
         #{"--"}transition-duration: 0s;
+        #{"--"}transition-duration-slow: 0s;
     }
 }
diff --git a/templates/_standard_loginform.php b/templates/_standard_loginform.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a8be593313c208aac6d9b5e349df3acd982617d
--- /dev/null
+++ b/templates/_standard_loginform.php
@@ -0,0 +1,76 @@
+<?php
+
+use Studip\Button;
+
+/**
+ * @var bool $hidden
+ * @var string $uname;
+ */
+?>
+
+<form class="default <?= $hidden ? 'hide' : '' ?>"
+      name="login_form"
+      id="login-form"
+      method="post"
+      action="<?= URLHelper::getLink(Request::url(), ['cancel_login' => null]) ?>"
+      <? if ($hidden) echo 'hidden'; ?>
+>
+    <section>
+        <label>
+            <span class="required"><?= _('Benutzername') ?></span>
+            <? if (Config::get()->USERNAME_TOOLTIP_ACTIVATED) : ?>
+                <?= tooltipIcon(htmlReady((string)Config::get()->USERNAME_TOOLTIP_TEXT)) ?>
+            <? endif ?>
+            <input type="text" <?= (mb_strlen($uname) || $hidden) ? '' : 'autofocus' ?>
+                   id="loginname"
+                   name="loginname"
+                   value="<?= htmlReady($uname) ?>"
+                   size="20"
+                   spellcheck="false"
+                   autocapitalize="off"
+                   title="<?= _('Der Benutzername entspricht nicht den Anforderungen') ?>"
+                   required>
+        </label>
+        <label for="password" style="position: relative">
+            <span class="required"><?= _('Passwort') ?></span>
+            <? if (Config::get()->PASSWORD_TOOLTIP_ACTIVATED) : ?>
+                <?= tooltipIcon(htmlReady((string)Config::get()->PASSWORD_TOOLTIP_TEXT)) ?>
+            <? endif ?>
+            <input type="password" <?= mb_strlen($uname) && !$hidden ? 'autofocus' : '' ?>
+                   id="password"
+                   name="password"
+                   size="20"
+                   required>
+
+            <i id="password-toggle" tabindex="0" aria-role="button" class="enter-accessible">
+                <?= Icon::create('visibility-checked')->asImg(20, [
+                    'id   ' => 'visible-password',
+                    'title' => _('Passwort anzeigen'),
+                ]) ?>
+                <?= Icon::create('visibility-invisible')->asImg(20, [
+                    'id'    => 'invisible-password',
+                    'style' => 'display: none',
+                    'title' => _('Passwort verstecken'),
+                ]) ?>
+            </i>
+
+        </label>
+        <p id="password-caps" style="display: none"><?= _('Feststelltaste ist aktiviert!') ?></p>
+    </section>
+
+    <?= CSRFProtection::tokenTag() ?>
+    <input type="hidden" name="login_ticket" value="<?= Seminar_Session::get_ticket() ?>">
+    <input type="hidden" name="resolution"  value="">
+
+    <div style="display: flex; align-items: flex-start; justify-content: space-between; height: 70px;">
+        <?= Button::createAccept(_('Anmelden'), _('Login'), ['id' => 'submit_login']); ?>
+
+        <? if (Config::get()->ENABLE_REQUEST_NEW_PASSWORD_BY_USER && in_array('Standard', $GLOBALS['STUDIP_AUTH_PLUGIN'])): ?>
+            <a style="line-height: 1 !important" href="<?= URLHelper::getLink('dispatch.php/new_password?cancel_login=1') ?>">
+            <? else: ?>
+            <a style="line-height: 1 !important" href="mailto:<?= $GLOBALS['UNI_CONTACT'] ?>?subject=<?= rawurlencode('Stud.IP Passwort vergessen - '.Config::get()->UNI_NAME_CLEAN) ?>&amp;body=<?= rawurlencode('Ich habe mein Passwort vergessen. Bitte senden Sie mir ein Neues.\nMein Nutzername: ' . htmlReady($uname) . "\n") ?>">
+                <? endif; ?>
+                <?= _('Passwort vergessen?') ?>
+            </a>
+    </div>
+</form>
diff --git a/templates/loginform.php b/templates/loginform.php
index 348cceea607880338694b14c4cafeeaa90e7a76c..deb9768b05ff0c9ec60ef17228a970a86e63978d 100644
--- a/templates/loginform.php
+++ b/templates/loginform.php
@@ -1,6 +1,8 @@
 <?php
-# Lifter010: TODO
-use Studip\Button, Studip\LinkButton;
+/**
+ * @var array $loginerror
+ * @var string $error_msg
+ */
 
 // Get background images (this should be resolved differently since mobile
 // browsers might still download the desktop background)
@@ -21,70 +23,122 @@ if (!match_route('web_migrate.php')) {
     $bg_desktop = URLHelper::getURL('pictures/loginbackgrounds/1.jpg');
     $bg_mobile = URLHelper::getURL('pictures/loginbackgrounds/2.jpg');
 }
+$show_hidden_login = false;
 ?>
-<main id="content">
+<main id="content" class="loginpage">
     <div id="background-desktop" style="background: url(<?= $bg_desktop ?>) no-repeat top left/cover;"></div>
     <div id="background-mobile" style="background: url(<?= $bg_mobile ?>) no-repeat top left/cover;"></div>
-    <? if ($loginerror): ?>
-        <!-- failed login code -->
-        <?= MessageBox::error(_('Bei der Anmeldung trat ein Fehler auf!'), [
-            $error_msg,
-            sprintf(
-                _('Bitte wenden Sie sich bei Problemen an: <a href="mailto:%1$s">%1$s</a>'),
-                $GLOBALS['UNI_CONTACT']
-            )
-        ]) ?>
-    <? endif; ?>
 
-    <?= implode('', PageLayout::getMessages()); ?>
+    <div id="login_flex">
+        <? if ($loginerror): ?>
+            <!-- failed login code -->
+            <?= MessageBox::error(_('Bei der Anmeldung trat ein Fehler auf!'), [
+                $error_msg,
+                sprintf(
+                    _('Bitte wenden Sie sich bei Problemen an: <a href="mailto:%1$s">%1$s</a>'),
+                    $GLOBALS['UNI_CONTACT']
+                )
+            ]) ?>
+        <? endif ?>
 
-    <div id="loginbox">
-        <form class="default" name="login" method="post" action="<?= URLHelper::getLink(Request::url(), ['cancel_login' => NULL]) ?>">
+        <?= implode('', PageLayout::getMessages()); ?>
+
+        <div id="loginbox">
             <header>
-                <h1 style="margin: 0; padding-bottom:10px;">
-                    <?=_('Herzlich willkommen!')?>
-                </h1>
+                <h1><?= htmlReady(Config::get()->UNI_NAME_CLEAN) ?></h1>
             </header>
-            <section>
-                <label>
-                    <?= _('Benutzername:') ?>
-                    <input type="text" <?= mb_strlen($uname) ? '' : 'autofocus' ?>
-                           id="loginname" name="loginname"
-                           value="<?= htmlReady($uname) ?>"
-                           size="20"
-                           autocorrect="off" autocapitalize="off">
-                </label>
-            </section>
-            <section>
-                <label for="password">
-                    <?= _('Passwort:') ?>
-                    <input type="password" <?= mb_strlen($uname) ? 'autofocus' : '' ?>
-                           id="password" name="password" size="20">
-                </label>
-            </section>
-                <?= CSRFProtection::tokenTag() ?>
-                <input type="hidden" name="login_ticket" value="<?=Seminar_Session::get_ticket();?>">
-                <input type="hidden" name="resolution"  value="">
-                <?= Button::createAccept(_('Anmelden'), _('Login')); ?>
-                <?= LinkButton::create(_('Abbrechen'), URLHelper::getURL('index.php', ['cancel_login' => 1], true)) ?>
-        </form>
 
-        <div>
-            <? if (Config::get()->ENABLE_REQUEST_NEW_PASSWORD_BY_USER && in_array('Standard', $GLOBALS['STUDIP_AUTH_PLUGIN'])): ?>
-                <a href="<?= URLHelper::getLink('dispatch.php/new_password?cancel_login=1') ?>">
-            <? else: ?>
-                <a href="mailto:<?= $GLOBALS['UNI_CONTACT'] ?>?subject=<?= rawurlencode('Stud.IP Passwort vergessen - '.Config::get()->UNI_NAME_CLEAN) ?>&amp;body=<?= rawurlencode('Ich habe mein Passwort vergessen. Bitte senden Sie mir ein Neues.\nMein Nutzername: ' . htmlReady($uname) . "\n") ?>">
-            <? endif; ?>
-                    <?= _('Passwort vergessen') ?>
-                </a>
-            <? if ($self_registration_activated): ?>
-                /
-                <a href="<?= URLHelper::getLink('register1.php?cancel_login=1') ?>">
-                    <?= _('Registrieren') ?>
-                </a>
-            <? endif; ?>
+            <? if (count($GLOBALS['STUDIP_AUTH_PLUGIN']) === 1 && StudipAuthAbstract::isLoginEnabled()) : ?>
+                <?= $this->render_partial('_standard_loginform', [
+                    'hidden' => false,
+                ]) ?>
+            <? endif ?>
+            <nav>
+                <ul>
+                    <? foreach (Navigation::getItem('/login') as $key => $nav) : ?>
+                        <? if ($nav->isVisible()) : ?>
+                        <? if ($key === 'standard_login') {
+                                if (count($GLOBALS['STUDIP_AUTH_PLUGIN']) === 1 && StudipAuthAbstract::isLoginEnabled()) {
+                                    continue;
+                                } else {
+                                    $show_hidden_login = true;
+                                }
+                            }
+                            ?>
+                            <? $name_and_title = explode(' - ', $nav->getTitle()) ?>
+                            <li class="login_link">
+                                <? if (is_internal_url($url = $nav->getURL())) : ?>
+                                <? SkipLinks::addLink($name_and_title[0], $url) ?>
+                                <a href="<?= URLHelper::getLink($url, ['cancel_login' => 1]) ?>" id="<?= $nav->getLinkAttributes()['id'] ?>">
+                                <? else : ?>
+                                <a href="<?= htmlReady($url) ?>" target="_blank" rel="noopener noreferrer">
+                                <? endif ?>
+                                <?= htmlReady($name_and_title[0]) ?>
+                                <p>
+                                    <?= htmlReady(!empty($name_and_title[1]) ? $name_and_title[1] : $nav->getDescription()) ?>
+                                </p>
+                                </a>
+                            </li>
+                        <? endif ?>
+                    <? endforeach ?>
+                </ul>
+            </nav>
+
+            <? if ($show_hidden_login) : ?>
+                <?= $this->render_partial('_standard_loginform', [
+                    'hidden' => empty($loginerror),
+                ]) ?>
+            <? endif ?>
+
+            <footer>
+                <? if ($GLOBALS['UNI_LOGIN_ADD']) : ?>
+                    <div class="uni_login_add">
+                        <?= $GLOBALS['UNI_LOGIN_ADD'] ?>
+                    </div>
+                <? endif ?>
+
+                <div id="languages">
+                    <? foreach ($GLOBALS['INSTALLED_LANGUAGES'] as $temp_language_key => $temp_language): ?>
+                        <?= Assets::img('languages/' . $temp_language['picture'], ['alt' => $temp_language['name'], 'size' => '24']) ?>
+                        <a href="<?= URLHelper::getLink('index.php', ['set_language' =>$temp_language_key ]) ?>">
+                            <?= htmlReady($temp_language['name']) ?>
+                        </a>
+                    <? endforeach ?>
+                </div>
+
+                <div id="contrast">
+                    <? if (isset($_SESSION['contrast'])) : ?>
+                        <?= Icon::create('accessibility')->asImg(24) ?>
+                        <a href="<?= URLHelper::getLink('index.php', ['unset_contrast' => 1, 'cancel_login' => 1]) ?>"><?= _('Normalen Kontrast aktivieren') ?></a>
+                        <?= tooltipIcon(_('Aktiviert standardmäßige, nicht barrierefreie Kontraste.')); ?>
+                    <? else : ?>
+                        <?= Icon::create('accessibility')->asImg(24) ?>
+                        <a href="<?= URLHelper::getLink('index.php', ['set_contrast' => 1, 'cancel_login' => 1]) ?>" id="highcontrastlink"><?= _('Hohen Kontrast aktivieren')?></a>
+                        <?= tooltipIcon(_('Aktiviert einen hohen Kontrast gemäß WCAG 2.1. Diese Einstellung wird nach dem Login übernommen.'
+                        . 'Sie können sie in Ihren persönlichen Einstellungen ändern.')); ?>
+                    <? endif ?>
+                </div>
+
+            </footer>
         </div>
+        <? if (Config::get()->LOGIN_FAQ_VISIBILITY && count($faq_entries) > 0) : ?>
+            <div id="faq_box">
+                <header><h1><?= htmlReady(Config::get()->LOGIN_FAQ_TITLE) ?></h1></header>
+                <? foreach ($faq_entries as $entry) : ?>
+                    <article class="studip toggle">
+                        <header>
+                            <h1><a href="#"><?= htmlReady($entry->title) ?></a></h1>
+                        </header>
+                        <section><?= formatReady($entry->description) ?>
+                        </section>
+                    </article>
+                <? endforeach ?>
+            </div>
+        <? endif ?>
+
     </div>
+
+
 </main>
 
 <script type="text/javascript" language="javascript">
@@ -92,6 +146,7 @@ if (!match_route('web_migrate.php')) {
 $(function () {
     $('form[name=login]').submit(function () {
         $('input[name=resolution]', this).val( screen.width + 'x' + screen.height );
+        $('input[name=device_pixel_ratio]').val(window.devicePixelRatio || 1);
     });
 });
 // -->
diff --git a/tests/e2e/login.spec.ts b/tests/e2e/login.spec.ts
index 95e44a6bf140c770c109db44bd7d7d7aa1d0aa25..2e859dd1bba1b32c3b1e904d5fa477a57fa421a4 100644
--- a/tests/e2e/login.spec.ts
+++ b/tests/e2e/login.spec.ts
@@ -8,7 +8,7 @@ test.describe('Loggin In - HTML Web Form @auth', () => {
 
             await expect(page.locator('#loginbox')).toBeVisible();
 
-            const loginLink = page.getByRole('link', { name: 'Login für registrierte NutzerInnen' });
+            const loginLink = page.getByRole('link', { name: 'Login für registrierte Nutzende' });
             await expect(loginLink).toBeVisible();
             await loginLink.click();