Style Keycloak PatternFly markup in login theme
Pages we don't override with a custom .ftl (change password, OTP, verify email, required actions, etc.) render their inner form with Keycloak's stock PatternFly/Bootstrap classes. The brutalist card shell was styled but the fields inside were not. Add resources/css/brutalist.css with targeted overrides on .pf-c-form-control, .pf-c-button, .pf-c-input-group, .checkbox, .form-group, alerts and headings, then link it from template.ftl so every Keycloak auto-generated page inherits the E-Cosplay look without touching each individual .ftl file. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
277
themes/ecosplay/login/resources/css/brutalist.css
Normal file
277
themes/ecosplay/login/resources/css/brutalist.css
Normal file
@@ -0,0 +1,277 @@
|
||||
/* ============================================================
|
||||
E-Cosplay brutalist overrides for default Keycloak markup
|
||||
------------------------------------------------------------
|
||||
The shell (card, header, marquee, footer) is rendered by our
|
||||
template.ftl. Pages that we do NOT override (change password,
|
||||
OTP, verify email, required actions, etc.) reuse Keycloak's
|
||||
stock PatternFly/Bootstrap markup for their inner form. This
|
||||
file restyles those classes so everything inside the card
|
||||
matches the brutalist identity without having to override
|
||||
every single .ftl file.
|
||||
============================================================ */
|
||||
|
||||
/* Layout: kill Bootstrap grid side-padding that breaks our card */
|
||||
.form-group {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
.form-group > div[class*="col-"] {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
float: none !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
.form-horizontal {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ---------- Labels ---------- */
|
||||
.pf-c-form__label,
|
||||
.pf-c-form__label-text,
|
||||
label {
|
||||
display: block;
|
||||
font-weight: 900 !important;
|
||||
text-transform: uppercase !important;
|
||||
letter-spacing: 0.1em;
|
||||
font-size: 11px;
|
||||
color: #111827 !important;
|
||||
margin-bottom: 0.5rem;
|
||||
font-style: normal !important;
|
||||
}
|
||||
|
||||
/* ---------- Inputs ---------- */
|
||||
.pf-c-form-control,
|
||||
input[type="text"],
|
||||
input[type="email"],
|
||||
input[type="password"],
|
||||
input[type="tel"],
|
||||
input[type="number"],
|
||||
input[type="url"],
|
||||
select,
|
||||
textarea {
|
||||
width: 100% !important;
|
||||
padding: 14px 16px !important;
|
||||
background: #ffffff !important;
|
||||
color: #111827 !important;
|
||||
border: 4px solid #111827 !important;
|
||||
border-radius: 0 !important;
|
||||
font-weight: 700 !important;
|
||||
font-style: normal !important;
|
||||
font-size: 16px !important;
|
||||
line-height: 1.4 !important;
|
||||
box-shadow: none !important;
|
||||
outline: none !important;
|
||||
transition: all 0.15s ease !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.pf-c-form-control:focus,
|
||||
input[type="text"]:focus,
|
||||
input[type="email"]:focus,
|
||||
input[type="password"]:focus,
|
||||
input[type="tel"]:focus,
|
||||
input[type="number"]:focus,
|
||||
input[type="url"]:focus,
|
||||
select:focus,
|
||||
textarea:focus {
|
||||
background: #fef9c3 !important;
|
||||
box-shadow: 6px 6px 0 #4f46e5 !important;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.pf-c-form-control[aria-invalid="true"] {
|
||||
border-color: #dc2626 !important;
|
||||
background: #fee2e2 !important;
|
||||
}
|
||||
|
||||
/* ---------- Input group (password reveal button etc.) ---------- */
|
||||
.pf-c-input-group {
|
||||
display: flex !important;
|
||||
align-items: stretch !important;
|
||||
gap: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pf-c-input-group > .pf-c-form-control,
|
||||
.pf-c-input-group > input {
|
||||
flex: 1 1 auto !important;
|
||||
}
|
||||
|
||||
.pf-c-input-group > .pf-c-button.pf-m-control {
|
||||
display: inline-flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
min-width: 56px !important;
|
||||
padding: 0 18px !important;
|
||||
background: #111827 !important;
|
||||
color: #ffffff !important;
|
||||
border: 4px solid #111827 !important;
|
||||
border-left: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
font-weight: 900 !important;
|
||||
cursor: pointer !important;
|
||||
box-shadow: none !important;
|
||||
transform: none !important;
|
||||
letter-spacing: 0 !important;
|
||||
font-style: normal !important;
|
||||
text-transform: none !important;
|
||||
}
|
||||
|
||||
.pf-c-input-group > .pf-c-button.pf-m-control:hover {
|
||||
background: #4f46e5 !important;
|
||||
}
|
||||
|
||||
/* ---------- Buttons (primary / default / cancel) ---------- */
|
||||
.pf-c-button,
|
||||
input[type="submit"],
|
||||
button[type="submit"],
|
||||
button[type="button"].btn,
|
||||
a.btn {
|
||||
display: inline-block;
|
||||
padding: 16px 28px !important;
|
||||
font-weight: 900 !important;
|
||||
text-transform: uppercase !important;
|
||||
letter-spacing: 0.12em !important;
|
||||
font-style: italic !important;
|
||||
font-size: 14px !important;
|
||||
line-height: 1 !important;
|
||||
border: 4px solid #111827 !important;
|
||||
border-radius: 0 !important;
|
||||
cursor: pointer !important;
|
||||
transition: all 0.15s ease !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.pf-c-button.pf-m-primary,
|
||||
input.pf-m-primary,
|
||||
input[type="submit"].pf-m-primary,
|
||||
input[type="submit"].btn-primary,
|
||||
button.btn-primary {
|
||||
background: #4f46e5 !important;
|
||||
color: #ffffff !important;
|
||||
box-shadow: 8px 8px 0 rgba(0, 0, 0, 1) !important;
|
||||
}
|
||||
|
||||
.pf-c-button.pf-m-primary:hover,
|
||||
input[type="submit"].pf-m-primary:hover,
|
||||
button.btn-primary:hover {
|
||||
box-shadow: none !important;
|
||||
transform: translate(4px, 4px) !important;
|
||||
background: #4338ca !important;
|
||||
}
|
||||
|
||||
.pf-c-button.btn-default,
|
||||
.pf-c-button.btn-secondary,
|
||||
button.btn-default,
|
||||
button.btn-secondary,
|
||||
input[type="submit"].btn-default {
|
||||
background: #ffffff !important;
|
||||
color: #111827 !important;
|
||||
box-shadow: 8px 8px 0 rgba(0, 0, 0, 1) !important;
|
||||
}
|
||||
|
||||
.pf-c-button.btn-default:hover,
|
||||
button.btn-default:hover {
|
||||
background: #facc15 !important;
|
||||
box-shadow: none !important;
|
||||
transform: translate(4px, 4px) !important;
|
||||
}
|
||||
|
||||
/* Avoid the input-group eye button inheriting the primary style above */
|
||||
.pf-c-input-group .pf-c-button.pf-m-control {
|
||||
padding: 0 18px !important;
|
||||
font-size: 14px !important;
|
||||
letter-spacing: 0 !important;
|
||||
text-transform: none !important;
|
||||
font-style: normal !important;
|
||||
}
|
||||
|
||||
/* ---------- Checkboxes ---------- */
|
||||
.checkbox {
|
||||
margin: 1rem 0 !important;
|
||||
}
|
||||
|
||||
.checkbox label {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
gap: 12px !important;
|
||||
cursor: pointer !important;
|
||||
font-size: 11px !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
width: 20px !important;
|
||||
height: 20px !important;
|
||||
margin: 0 !important;
|
||||
border: 4px solid #111827 !important;
|
||||
accent-color: #4f46e5 !important;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
/* ---------- Button row ---------- */
|
||||
#kc-form-buttons {
|
||||
display: flex !important;
|
||||
gap: 12px !important;
|
||||
flex-wrap: wrap !important;
|
||||
margin-top: 1.5rem !important;
|
||||
}
|
||||
|
||||
#kc-form-buttons > .pf-c-button,
|
||||
#kc-form-buttons > input[type="submit"],
|
||||
#kc-form-buttons > button {
|
||||
flex: 1 1 160px;
|
||||
}
|
||||
|
||||
/* ---------- Alerts / messages ---------- */
|
||||
.alert,
|
||||
.pf-c-alert {
|
||||
border: 4px solid #111827 !important;
|
||||
border-radius: 0 !important;
|
||||
box-shadow: 6px 6px 0 rgba(0, 0, 0, 1) !important;
|
||||
padding: 14px 18px !important;
|
||||
font-weight: 800 !important;
|
||||
margin-bottom: 1.5rem !important;
|
||||
}
|
||||
|
||||
.alert-success,
|
||||
.pf-c-alert.pf-m-success {
|
||||
background: #bbf7d0 !important;
|
||||
}
|
||||
.alert-warning,
|
||||
.pf-c-alert.pf-m-warning {
|
||||
background: #fde68a !important;
|
||||
}
|
||||
.alert-danger,
|
||||
.alert-error,
|
||||
.pf-c-alert.pf-m-danger {
|
||||
background: #fecaca !important;
|
||||
}
|
||||
.alert-info,
|
||||
.pf-c-alert.pf-m-info {
|
||||
background: #c7d2fe !important;
|
||||
}
|
||||
|
||||
/* ---------- Links ---------- */
|
||||
a {
|
||||
color: #4f46e5 !important;
|
||||
text-decoration: underline !important;
|
||||
text-decoration-thickness: 3px !important;
|
||||
text-underline-offset: 4px !important;
|
||||
font-weight: 800 !important;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #111827 !important;
|
||||
}
|
||||
|
||||
/* ---------- Headings inside the card ---------- */
|
||||
.pf-c-title,
|
||||
#kc-page-title,
|
||||
h1, h2, h3 {
|
||||
font-weight: 900 !important;
|
||||
text-transform: uppercase !important;
|
||||
font-style: italic !important;
|
||||
letter-spacing: -0.02em !important;
|
||||
color: #111827 !important;
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>${msg("loginTitle",(realm.displayName!''))}</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="stylesheet" href="${url.resourcesPath}/css/brutalist.css">
|
||||
<style>
|
||||
@keyframes marquee {
|
||||
0% { transform: translateX(0); }
|
||||
|
||||
Reference in New Issue
Block a user