diff --git a/keycloak-templates/themes/README.md b/keycloak-templates/themes/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..eeadc58a84fdf924c629b1b28ddaba37b36231b8
--- /dev/null
+++ b/keycloak-templates/themes/README.md
@@ -0,0 +1,24 @@
+Creating Themes
+===============
+
+Themes are used to configure the look and feel of login pages and the account management console.
+
+Custom themes packaged in a JAR file should be deployed to the `${kc.home.dir}/providers` directory. After that, run
+the `build` command to install them before starting the server.
+
+You are also able to create your custom themes in this directory, directly. Themes within this directory do not require
+the `build` command to be installed.
+
+When running the server in development mode using `start-dev`, themes are not cached so that you can easily work on them without a need to restart
+the server when making changes.
+
+See the theme section in the [Server Developer Guide](https://www.keycloak.org/docs/latest/server_development/#_themes) for more details about how to create custom themes.
+
+Overriding the built-in templates
+---------------------------------
+
+While creating custom themes, especially when overriding templates, it may be useful to use the built-in templates as
+a reference. These can be found within the theme directory of `../lib/lib/main/org.keycloak.keycloak-themes-24.0.5.jar`, which can be opened using any
+standard ZIP archive tool.
+
+**Built-in themes should not be modified directly, instead a custom theme should be created.**
\ No newline at end of file
diff --git a/keycloak-templates/themes/ozg-by/login/footer-links.ftl b/keycloak-templates/themes/ozg-by/login/footer-links.ftl
new file mode 100644
index 0000000000000000000000000000000000000000..16572fcda5000f4874b3e73c1098eeba6939c3b5
--- /dev/null
+++ b/keycloak-templates/themes/ozg-by/login/footer-links.ftl
@@ -0,0 +1,3 @@
+<#macro content>
+  <li class="ozg-login-footer__item"><a href="${properties.staticUrlBarrierefreiheit}/barrierefreiheit" target="_blank" rel="noopener noreferrer">Barrierefreiheit</a></li>
+</#macro>
\ No newline at end of file
diff --git a/keycloak-templates/themes/ozg-by/login/theme.properties b/keycloak-templates/themes/ozg-by/login/theme.properties
new file mode 100644
index 0000000000000000000000000000000000000000..8a1b5d6b0e63ea054d7089791aabcc6907e16c5b
--- /dev/null
+++ b/keycloak-templates/themes/ozg-by/login/theme.properties
@@ -0,0 +1,2 @@
+parent=ozg
+staticUrlBarrierefreiheit=https://by-static.dev.by.ozg-cloud.de/barrierefreiheit
\ No newline at end of file
diff --git a/keycloak-templates/themes/ozg-sh/login/footer-links.ftl b/keycloak-templates/themes/ozg-sh/login/footer-links.ftl
new file mode 100644
index 0000000000000000000000000000000000000000..16572fcda5000f4874b3e73c1098eeba6939c3b5
--- /dev/null
+++ b/keycloak-templates/themes/ozg-sh/login/footer-links.ftl
@@ -0,0 +1,3 @@
+<#macro content>
+  <li class="ozg-login-footer__item"><a href="${properties.staticUrlBarrierefreiheit}/barrierefreiheit" target="_blank" rel="noopener noreferrer">Barrierefreiheit</a></li>
+</#macro>
\ No newline at end of file
diff --git a/keycloak-templates/themes/ozg-sh/login/theme.properties b/keycloak-templates/themes/ozg-sh/login/theme.properties
new file mode 100644
index 0000000000000000000000000000000000000000..ded1d12072958e9cbfe0c2538bc8faf342eaf81b
--- /dev/null
+++ b/keycloak-templates/themes/ozg-sh/login/theme.properties
@@ -0,0 +1,2 @@
+parent=ozg
+staticUrlBarrierefreiheit=https://sh-static.dev.by.ozg-cloud.de/barrierefreiheit
\ No newline at end of file
diff --git a/keycloak-templates/themes/ozg/login/footer-links.ftl b/keycloak-templates/themes/ozg/login/footer-links.ftl
new file mode 100644
index 0000000000000000000000000000000000000000..f200a87c1549019f8dceb93ce73059e8d8a73a18
--- /dev/null
+++ b/keycloak-templates/themes/ozg/login/footer-links.ftl
@@ -0,0 +1,5 @@
+<#macro content>
+  <li class="ozg-login-footer__item"><a href="${properties.staticUrlBarrierefreiheit}/barrierefreiheit" target="_blank" rel="noopener noreferrer">Barrierefreiheit</a></li>
+  <!-- li class="ozg-login-footer__item" target="_blank"><a href="${properties.staticUrlDatenschutz}/datenschutz" rel="noopener noreferrer">Datenschutz</a></li> 
+  <li class="ozg-login-footer__item" target="_blank"><a href="${properties.staticUrlImpressum}/impressum" rel="noopener noreferrer">Impressum</a></li> -->
+</#macro>
\ No newline at end of file
diff --git a/keycloak-templates/themes/ozg/login/resources/css/styles.css b/keycloak-templates/themes/ozg/login/resources/css/styles.css
new file mode 100644
index 0000000000000000000000000000000000000000..d9ef288f4596dc05a21eb09b199b59ae7c0b8014
--- /dev/null
+++ b/keycloak-templates/themes/ozg/login/resources/css/styles.css
@@ -0,0 +1,155 @@
+a {
+  color: #1565c0;
+  text-decoration: none;
+}
+
+a:hover {
+  color: #1565c0;
+  text-decoration: underline;
+}
+
+a:focus {
+  color: #1565c0;
+  outline: 2px solid #1565c0;
+  outline-offset: 4px;
+  border-radius: 6px;
+  text-decoration: none;
+}
+
+.login-pf a:hover {
+  color: #1565c0;
+}
+
+.login-pf body {
+  background-image: none;
+  background-color: #f9f9f9;
+  font-size: 16px;
+  font-family: Roboto, "Helvetica Neue", sans-serif;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.ozg-login-h1 {
+  font-size: 24px;
+  font-weight: 500;
+  color: #1565c0;
+  padding: 32px 0 0 0;
+  margin-top: 0;
+  margin-bottom: 0;
+  text-align: center;
+}
+
+.ozg-login-h2 {
+  font-size: 20px;
+  font-weight: 500;
+  color: #1565c0;
+  padding: 12px 0;
+  margin-top: 0;
+  margin-bottom: 0;
+  text-align: center;
+}
+
+.ozg-login-logo {
+  background-image: url(../img/OZG_Cloud_logo.png);
+  background-repeat: no-repeat;
+  background-size: contain;
+  aspect-ratio: 1.3;
+  height: 110px;
+  margin: 0 auto;
+}
+
+.login-pf-page .card-pf {
+  border-radius: 6px;
+}
+
+.pf-c-form__label-text {
+  font-weight: 500;
+  font-size: 16px;
+  margin-bottom: 8px;
+}
+
+.pf-c-form-control {
+  border-radius: 6px;
+  border-color: #4678c2;
+  padding: 8px 12px;
+}
+
+.pf-c-form-control:focus {
+  padding: 8px 12px;
+  border-color: #e0e0e0;
+  outline: 2px solid #4678c2;
+  outline-offset: 2px;
+}
+
+.pf-c-form-control[aria-invalid="true"] {
+  border-color: #d62424;
+  border-color: #e0e0e0;
+  border-bottom-width: 1px;
+}
+
+.pf-c-form-control[aria-invalid="true"]:focus {
+  border-color: #e0e0e0;
+  outline: 2px solid #d62424;
+  outline-offset: 2px;
+}
+
+.pf-c-button.pf-m-control {
+  border-color: #4678c2;
+  margin-left: 0;
+}
+
+.pf-c-form__helper-text {
+  font-size: 14px;
+}
+
+.required {
+  color: #d62424;
+}
+
+.pf-c-button:after {
+  border: none;
+}
+
+.pf-c-alert {
+  background-color: white;
+  border-top: none;
+  padding: 0 0 16px 0;
+  color: #d62424;
+}
+
+.pf-c-alert__title {
+  font-size: 14px;
+  color: #d62424;
+}
+
+.btn-lg {
+  border-radius: 6px;
+  font-size: 14px;
+  color: white;
+  font-weight: 500;
+  padding: 8px 32px;
+  min-width: 126px;
+  width: auto;
+}
+
+.btn-lg:focus-visible {
+  outline: 2px solid #4678c2;
+  outline-offset: 2px;
+}
+
+.ozg-login-footer {
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  flex-wrap: wrap;
+  padding: 60px 0;
+}
+
+.ozg-login-footer__item {
+  padding: 0 12px;
+  font-size: 16px;
+}
+
+#kc-info-wrapper {
+  font-size: 16px;
+}
diff --git a/keycloak-templates/themes/ozg/login/resources/img/OZG_Cloud_Logo.png b/keycloak-templates/themes/ozg/login/resources/img/OZG_Cloud_Logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..124440050006f888cd60276dbb9a6b8d779475bd
Binary files /dev/null and b/keycloak-templates/themes/ozg/login/resources/img/OZG_Cloud_Logo.png differ
diff --git a/keycloak-templates/themes/ozg/login/template.ftl b/keycloak-templates/themes/ozg/login/template.ftl
new file mode 100644
index 0000000000000000000000000000000000000000..50129607f2fcc973cbc9a5f441c502f2300710ef
--- /dev/null
+++ b/keycloak-templates/themes/ozg/login/template.ftl
@@ -0,0 +1,174 @@
+<#macro registrationLayout bodyClass="" displayInfo=false displayMessage=true displayRequiredFields=false>
+<!DOCTYPE html>
+<html class="${properties.kcHtmlClass!}"<#if realm.internationalizationEnabled> lang="${locale.currentLanguageTag}"</#if>>
+
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta name="robots" content="noindex, nofollow">
+
+    <#if properties.meta?has_content>
+        <#list properties.meta?split(' ') as meta>
+            <meta name="${meta?split('==')[0]}" content="${meta?split('==')[1]}"/>
+        </#list>
+    </#if>
+    <title>${msg("loginTitle",(realm.displayName!''))}</title>
+    <link rel="icon" href="${url.resourcesPath}/img/favicon.ico" />
+    <#if properties.stylesCommon?has_content>
+        <#list properties.stylesCommon?split(' ') as style>
+            <link href="${url.resourcesCommonPath}/${style}" rel="stylesheet" />
+        </#list>
+    </#if>
+    <#if properties.styles?has_content>
+        <#list properties.styles?split(' ') as style>
+            <link href="${url.resourcesPath}/${style}" rel="stylesheet" />
+        </#list>
+    </#if>
+    <#if properties.scripts?has_content>
+        <#list properties.scripts?split(' ') as script>
+            <script src="${url.resourcesPath}/${script}" type="text/javascript"></script>
+        </#list>
+    </#if>
+    <script src="${url.resourcesPath}/js/menu-button-links.js" type="module"></script>
+    <#if scripts??>
+        <#list scripts as script>
+            <script src="${script}" type="text/javascript"></script>
+        </#list>
+    </#if>
+    <#if authenticationSession??>
+        <script type="module">
+            import { checkCookiesAndSetTimer } from "${url.resourcesPath}/js/authChecker.js";
+
+            checkCookiesAndSetTimer(
+              "${authenticationSession.authSessionId}",
+              "${authenticationSession.tabId}",
+              "${url.ssoLoginInOtherTabsUrl?no_esc}"
+            );
+        </script>
+    </#if>
+</head>
+
+<body class="${properties.kcBodyClass!}">
+<div class="${properties.kcLoginClass!}">
+    <header id="kc-header" class="${properties.kcHeaderClass!}">
+        <div class="ozg-login-logo" role="img" aria-label="OZG-Cloud Logo"></div>
+        <h1 class="ozg-login-h1">${kcSanitize(msg("loginTitleHtml",(realm.displayNameHtml!'')))?no_esc}</h1>
+    </header>
+    <main class="${properties.kcFormCardClass!}">
+        <div class="${properties.kcFormHeaderClass!}">
+            <#if realm.internationalizationEnabled  && locale.supported?size gt 1>
+                <div class="${properties.kcLocaleMainClass!}" id="kc-locale">
+                    <div id="kc-locale-wrapper" class="${properties.kcLocaleWrapperClass!}">
+                        <div id="kc-locale-dropdown" class="menu-button-links ${properties.kcLocaleDropDownClass!}">
+                            <button tabindex="1" id="kc-current-locale-link" aria-label="${msg("languages")}" aria-haspopup="true" aria-expanded="false" aria-controls="language-switch1">${locale.current}</button>
+                            <ul role="menu" tabindex="-1" aria-labelledby="kc-current-locale-link" aria-activedescendant="" id="language-switch1" class="${properties.kcLocaleListClass!}">
+                                <#assign i = 1>
+                                <#list locale.supported as l>
+                                    <li class="${properties.kcLocaleListItemClass!}" role="none">
+                                        <a role="menuitem" id="language-${i}" class="${properties.kcLocaleItemClass!}" href="${l.url}">${l.label}</a>
+                                    </li>
+                                    <#assign i++>
+                                </#list>
+                            </ul>
+                        </div>
+                    </div>
+                </div>
+            </#if>
+        <#if !(auth?has_content && auth.showUsername() && !auth.showResetCredentials())>
+            <#if displayRequiredFields>
+                <div class="${properties.kcContentWrapperClass!}">
+                    <div class="${properties.kcLabelWrapperClass!} subtitle">
+                        <span class="subtitle"><span class="required">*</span> ${msg("requiredFields")}</span>
+                    </div>
+                    <div class="col-md-10">
+                        <h2 class="ozg-login-h2" id="kc-page-title"><#nested "header"></h2>
+                    </div>
+                </div>
+            <#else>
+                <h2 class="ozg-login-h2" id="kc-page-title"><#nested "header"></h2>
+            </#if>
+        <#else>
+            <#if displayRequiredFields>
+                <div class="${properties.kcContentWrapperClass!}">
+                    <div class="${properties.kcLabelWrapperClass!} subtitle">
+                        <span class="subtitle"><span class="required">*</span> ${msg("requiredFields")}</span>
+                    </div>
+                    <div class="col-md-10">
+                        <#nested "show-username">
+                        <div id="kc-username" class="${properties.kcFormGroupClass!}">
+                            <label id="kc-attempted-username">${auth.attemptedUsername}</label>
+                            <a id="reset-login" href="${url.loginRestartFlowUrl}" aria-label="${msg("restartLoginTooltip")}">
+                                <div class="kc-login-tooltip">
+                                    <i class="${properties.kcResetFlowIcon!}"></i>
+                                    <span class="kc-tooltip-text">${msg("restartLoginTooltip")}</span>
+                                </div>
+                            </a>
+                        </div>
+                    </div>
+                </div>
+            <#else>
+                <#nested "show-username">
+                <div id="kc-username" class="${properties.kcFormGroupClass!}">
+                    <label id="kc-attempted-username">${auth.attemptedUsername}</label>
+                    <a id="reset-login" href="${url.loginRestartFlowUrl}" aria-label="${msg("restartLoginTooltip")}">
+                        <div class="kc-login-tooltip">
+                            <i class="${properties.kcResetFlowIcon!}"></i>
+                            <span class="kc-tooltip-text">${msg("restartLoginTooltip")}</span>
+                        </div>
+                    </a>
+                </div>
+            </#if>
+        </#if>
+      </div>
+      <div id="kc-content">
+        <div id="kc-content-wrapper">
+          <#-- App-initiated actions should not see warning messages about the need to complete the action -->
+          <#-- during login.                                                                               -->
+          <#if displayMessage && message?has_content && (message.type != 'warning' || !isAppInitiatedAction??)>
+              <div class="alert-${message.type} ${properties.kcAlertClass!} pf-m-<#if message.type = 'error'>danger<#else>${message.type}</#if>">
+                  <div class="pf-c-alert__icon">
+                      <#if message.type = 'success'><span class="${properties.kcFeedbackSuccessIcon!}"></span></#if>
+                      <#if message.type = 'warning'><span class="${properties.kcFeedbackWarningIcon!}"></span></#if>
+                      <#if message.type = 'error'><span class="${properties.kcFeedbackErrorIcon!}"></span></#if>
+                      <#if message.type = 'info'><span class="${properties.kcFeedbackInfoIcon!}"></span></#if>
+                  </div>
+                      <span class="${properties.kcAlertTitleClass!}">${kcSanitize(message.summary)?no_esc}</span>
+              </div>
+          </#if>
+
+          <#nested "form">
+
+          <#if auth?has_content && auth.showTryAnotherWayLink()>
+              <form id="kc-select-try-another-way-form" action="${url.loginAction}" method="post">
+                  <div class="${properties.kcFormGroupClass!}">
+                      <input type="hidden" name="tryAnotherWay" value="on"/>
+                      <a href="#" id="try-another-way"
+                         onclick="document.forms['kc-select-try-another-way-form'].submit();return false;">${msg("doTryAnotherWay")}</a>
+                  </div>
+              </form>
+          </#if>
+
+          <#nested "socialProviders">
+
+          <#if displayInfo>
+              <div id="kc-info" class="${properties.kcSignUpClass!}">
+                  <div id="kc-info-wrapper" class="${properties.kcInfoAreaWrapperClass!}">
+                      <#nested "info">
+                  </div>
+              </div>
+          </#if>
+        </div>
+      </div>
+    </main>
+    <footer>
+        <nav>
+            <ul class="ozg-login-footer">
+                <#import "footer-links.ftl" as footer>
+                <@footer.content/>
+            </ul>
+        </nav>
+    </footer>
+  </div>
+</body>
+</html>
+</#macro>
diff --git a/keycloak-templates/themes/ozg/login/theme.properties b/keycloak-templates/themes/ozg/login/theme.properties
new file mode 100644
index 0000000000000000000000000000000000000000..44cd95cd68f56a254e3dceae3b2094124599f701
--- /dev/null
+++ b/keycloak-templates/themes/ozg/login/theme.properties
@@ -0,0 +1,3 @@
+parent=keycloak
+styles=css/login.css css/styles.css
+staticUrlBarrierefreiheit=https://static.dev.by.ozg-cloud.de/barrierefreiheit
\ No newline at end of file