Files
certifai/keycloak/themes/certifai/login/resources/css/login.css
Sharang Parnerkar 50237f5377
All checks were successful
CI / Format (push) Successful in 2s
CI / Clippy (push) Successful in 2m13s
CI / Security Audit (push) Successful in 1m37s
CI / Tests (push) Successful in 2m52s
CI / Deploy (push) Successful in 2s
feat(chat): added chat interface and connection to ollama (#10)
Co-authored-by: Sharang Parnerkar <parnerkarsharang@gmail.com>
Reviewed-on: #10
2026-02-20 19:40:25 +00:00

584 lines
16 KiB
CSS

/* CERTifAI Keycloak Login Theme
* Overrides PatternFly v4 / legacy Keycloak classes to match the dashboard.
*
* Actual page structure (Keycloak 26 with parent=keycloak):
* html.login-pf > body
* div.login-pf-page
* div#kc-header.login-pf-page-header
* div#kc-header-wrapper
* div.card-pf
* header.login-pf-header > h1#kc-page-title
* div#kc-content > div#kc-content-wrapper
* form#kc-form-login
* .form-group (email)
* .form-group (password + .pf-c-input-group)
* .form-group.login-pf-settings (forgot pwd)
* .form-group #kc-form-buttons (submit: input#kc-login.pf-c-button.pf-m-primary)
* div#kc-info.login-pf-signup (register link)
*
* Classes used: pf-c-* (PF v4), login-pf-*, card-pf, form-group
*/
/* ===== Google Fonts ===== */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Space+Grotesk:wght@500;600;700&display=swap');
/* ===== CSS Variables ===== */
:root {
--cai-bg-body: #0f1116;
--cai-bg-card: #1a1d26;
--cai-bg-surface: #1e222d;
--cai-bg-input: #12141a;
--cai-text-primary: #e2e8f0;
--cai-text-heading: #f1f5f9;
--cai-text-muted: #8892a8;
--cai-text-faint: #5a6478;
--cai-border-primary: #1e222d;
--cai-border-secondary: #2a2f3d;
--cai-accent: #91a4d2;
--cai-accent-secondary: #6d85c6;
--cai-brand-indigo: #4B3FE0;
--cai-brand-teal: #38B2AC;
--cai-error: #f87171;
--cai-success: #4ade80;
}
/* ===== Animations ===== */
/* Slow-moving ambient gradient behind the page */
@keyframes ambientShift {
0% { background-position: 0% 0%; }
25% { background-position: 100% 50%; }
50% { background-position: 50% 100%; }
75% { background-position: 0% 50%; }
100% { background-position: 0% 0%; }
}
/* Subtle glow pulse on the card */
@keyframes cardGlow {
0%, 100% { box-shadow: 0 4px 24px rgba(0, 0, 0, 0.3), 0 0 60px rgba(75, 63, 224, 0.04); }
50% { box-shadow: 0 4px 24px rgba(0, 0, 0, 0.3), 0 0 80px rgba(56, 178, 172, 0.06); }
}
/* Gentle float for the logo */
@keyframes logoFloat {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-4px); }
}
/* Gradient shimmer on the button */
@keyframes buttonShimmer {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
/* ===== Base Page ===== */
html.login-pf {
background-color: var(--cai-bg-body) !important;
}
html.login-pf body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
background:
radial-gradient(ellipse at 20% 20%, rgba(75, 63, 224, 0.07) 0%, transparent 50%),
radial-gradient(ellipse at 80% 80%, rgba(56, 178, 172, 0.05) 0%, transparent 50%),
radial-gradient(ellipse at 50% 50%, rgba(109, 133, 198, 0.03) 0%, transparent 70%),
var(--cai-bg-body) !important;
background-size: 200% 200%, 200% 200%, 100% 100%, 100% 100% !important;
animation: ambientShift 20s ease-in-out infinite !important;
color: var(--cai-text-primary) !important;
min-height: 100vh;
}
/* ===== Page Layout ===== */
.login-pf-page {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
padding: 40px 24px;
position: relative;
}
/* ===== Header (Logo + Realm Name) ===== */
#kc-header.login-pf-page-header {
background: transparent !important;
background-image: none !important;
padding: 0 0 32px !important;
text-align: center;
max-width: 440px;
width: 100%;
margin: 0;
}
#kc-header-wrapper {
font-family: 'Space Grotesk', sans-serif !important;
font-size: 28px !important;
font-weight: 700 !important;
color: var(--cai-text-heading) !important;
letter-spacing: -0.02em;
text-transform: none !important;
padding: 0 !important;
}
/* Logo via ::before pseudo-element */
#kc-header-wrapper::before {
content: '';
display: block;
width: 64px;
height: 64px;
margin: 0 auto 16px;
background-image: url('../img/logo.svg');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
animation: logoFloat 4s ease-in-out infinite;
filter: drop-shadow(0 0 12px rgba(75, 63, 224, 0.3));
}
/* ===== Login Card ===== */
.card-pf {
background-color: var(--cai-bg-card) !important;
border: 1px solid var(--cai-border-secondary) !important;
border-radius: 12px !important;
max-width: 440px;
width: 100%;
padding: 32px !important;
margin: 0 !important;
animation: cardGlow 6s ease-in-out infinite;
position: relative;
overflow: hidden;
}
/* Subtle gradient border effect on the card via ::before overlay */
.card-pf::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 2px;
background: linear-gradient(
90deg,
transparent,
var(--cai-brand-indigo),
var(--cai-brand-teal),
var(--cai-accent-secondary),
transparent
);
opacity: 0.5;
}
/* ===== Card Header (Sign In Title) ===== */
.login-pf-header {
border-bottom: none !important;
padding: 0 0 24px !important;
margin: 0 !important;
}
#kc-page-title {
font-family: 'Space Grotesk', sans-serif !important;
font-size: 22px !important;
font-weight: 600 !important;
color: var(--cai-text-heading) !important;
text-align: center;
margin: 0 !important;
}
/* ===== Form Groups ===== */
.form-group {
margin-bottom: 20px !important;
}
/* ===== Labels ===== */
.pf-c-form__label,
.pf-c-form__label-text,
.login-pf-page .form-group label,
.card-pf label {
font-family: 'Inter', sans-serif !important;
font-size: 13px !important;
font-weight: 500 !important;
color: var(--cai-text-muted) !important;
margin-bottom: 6px !important;
display: block;
}
/* ===== Text Inputs ===== */
.pf-c-form-control,
.login-pf-page .form-control,
.card-pf input[type="text"],
.card-pf input[type="password"],
.card-pf input[type="email"] {
background-color: var(--cai-bg-input) !important;
border: 1px solid var(--cai-border-secondary) !important;
border-radius: 8px !important;
color: var(--cai-text-primary) !important;
font-family: 'Inter', sans-serif !important;
font-size: 14px !important;
padding: 10px 14px !important;
height: auto !important;
line-height: 1.5 !important;
transition: border-color 0.2s ease, box-shadow 0.2s ease !important;
box-shadow: none !important;
outline: none !important;
}
.pf-c-form-control:focus,
.pf-c-form-control:focus-within,
.card-pf input[type="text"]:focus,
.card-pf input[type="password"]:focus,
.card-pf input[type="email"]:focus {
border-color: var(--cai-accent) !important;
box-shadow: 0 0 0 1px var(--cai-accent), 0 0 12px rgba(145, 164, 210, 0.1) !important;
outline: none !important;
}
.pf-c-form-control::placeholder,
.card-pf input::placeholder {
color: var(--cai-text-faint) !important;
}
/* Override browser autofill yellow background */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
-webkit-box-shadow: 0 0 0 9999px var(--cai-bg-input) inset !important;
-webkit-text-fill-color: var(--cai-text-primary) !important;
caret-color: var(--cai-text-primary) !important;
transition: background-color 5000s ease-in-out 0s !important;
background-color: var(--cai-bg-input) !important;
color: var(--cai-text-primary) !important;
}
/* Firefox autofill override */
input:autofill {
background-color: var(--cai-bg-input) !important;
color: var(--cai-text-primary) !important;
border-color: var(--cai-border-secondary) !important;
}
/* Additional specificity for autofill inside input-group */
.pf-c-input-group input:-webkit-autofill,
.card-pf input:-webkit-autofill,
.form-group input:-webkit-autofill,
#username:-webkit-autofill,
#password:-webkit-autofill {
-webkit-box-shadow: 0 0 0 9999px var(--cai-bg-input) inset !important;
-webkit-text-fill-color: var(--cai-text-primary) !important;
background-color: var(--cai-bg-input) !important;
}
/* ===== Password Input Group ===== */
/* FIX: The .pf-c-input-group has white bg from PF4, causing white corners
* behind the rounded child elements. Set transparent + matching border-radius. */
.pf-c-input-group {
display: flex !important;
align-items: stretch !important;
background-color: transparent !important;
background: transparent !important;
border-radius: 8px !important;
overflow: hidden !important;
}
.pf-c-input-group > .pf-c-form-control,
.pf-c-input-group > input.pf-c-form-control,
.pf-c-input-group > input[type="password"],
#password {
border-radius: 8px 0 0 8px !important;
border-right: none !important;
flex: 1;
}
/* Password visibility toggle */
.pf-c-button.pf-m-control,
.pf-c-input-group > .pf-c-button.pf-m-control {
background-color: var(--cai-bg-surface) !important;
color: var(--cai-text-muted) !important;
border-top: 1px solid var(--cai-border-secondary) !important;
border-right: 1px solid var(--cai-border-secondary) !important;
border-bottom: 1px solid var(--cai-border-secondary) !important;
border-left: 1px solid var(--cai-border-primary) !important;
border-radius: 0 8px 8px 0 !important;
padding: 0 14px !important;
transition: color 0.2s ease, background-color 0.2s ease !important;
line-height: 1 !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
}
.pf-c-button.pf-m-control:hover,
.pf-c-input-group > .pf-c-button.pf-m-control:hover {
color: var(--cai-accent) !important;
background-color: rgba(145, 164, 210, 0.08) !important;
}
.pf-c-button.pf-m-control:focus,
.pf-c-input-group > .pf-c-button.pf-m-control:focus {
box-shadow: none !important;
outline: none !important;
}
/* ===== Primary Button (Sign In) ===== */
.pf-c-button.pf-m-primary,
input.pf-c-button.pf-m-primary,
#kc-login {
background: linear-gradient(135deg,
var(--cai-accent),
var(--cai-accent-secondary),
var(--cai-brand-indigo),
var(--cai-accent-secondary),
var(--cai-accent)) !important;
background-size: 300% 100% !important;
animation: buttonShimmer 6s ease-in-out infinite !important;
border: none !important;
border-radius: 8px !important;
color: #0a0c10 !important;
font-family: 'Inter', sans-serif !important;
font-size: 14px !important;
font-weight: 600 !important;
padding: 12px 20px !important;
cursor: pointer !important;
transition: opacity 0.15s ease, box-shadow 0.2s ease !important;
text-shadow: none !important;
box-shadow: 0 2px 12px rgba(109, 133, 198, 0.2) !important;
width: 100%;
text-align: center;
}
.pf-c-button.pf-m-primary:hover,
input.pf-c-button.pf-m-primary:hover,
#kc-login:hover {
opacity: 0.95;
box-shadow: 0 4px 20px rgba(109, 133, 198, 0.35) !important;
}
.pf-c-button.pf-m-primary:focus,
#kc-login:focus {
box-shadow: 0 0 0 2px var(--cai-accent), 0 4px 20px rgba(109, 133, 198, 0.3) !important;
outline: none !important;
}
/* ===== Links ===== */
.login-pf-page a,
.card-pf a {
color: var(--cai-accent) !important;
text-decoration: none !important;
transition: color 0.15s ease !important;
}
.login-pf-page a:hover,
.card-pf a:hover {
color: var(--cai-accent-secondary) !important;
text-decoration: none !important;
}
/* Forgot Password link */
.login-pf-settings {
text-align: right;
margin-bottom: 24px !important;
}
.login-pf-settings a {
font-size: 13px !important;
}
/* ===== Registration / Info Section ===== */
#kc-info.login-pf-signup {
background-color: var(--cai-bg-surface) !important;
border-top: 1px solid var(--cai-border-primary) !important;
padding: 16px 32px !important;
margin: 0 -32px -32px !important;
border-radius: 0 0 12px 12px !important;
text-align: center;
}
#kc-info-wrapper,
#kc-registration {
font-size: 14px !important;
color: var(--cai-text-muted) !important;
}
#kc-registration span {
color: var(--cai-text-muted) !important;
}
/* ===== Alert / Error Messages ===== */
.alert,
.pf-c-alert {
background-color: var(--cai-bg-surface) !important;
border: 1px solid var(--cai-border-secondary) !important;
border-radius: 8px !important;
color: var(--cai-text-primary) !important;
padding: 12px 16px !important;
margin-bottom: 16px !important;
font-size: 14px !important;
}
.alert-error,
.alert-warning,
.pf-c-alert.pf-m-danger,
.pf-c-alert.pf-m-warning {
border-color: var(--cai-error) !important;
}
.alert-error .kc-feedback-text,
.pf-c-alert .pf-c-alert__title {
color: var(--cai-text-primary) !important;
}
.alert-success {
border-color: var(--cai-success) !important;
}
/* ===== Checkboxes (Remember Me) ===== */
.pf-c-check,
.login-pf-page .checkbox {
display: flex;
align-items: center;
gap: 8px;
}
.pf-c-check__label,
.login-pf-page .checkbox label {
font-size: 13px !important;
color: var(--cai-text-muted) !important;
cursor: pointer;
}
.pf-c-check__input,
.login-pf-page input[type="checkbox"] {
accent-color: var(--cai-accent);
width: 16px;
height: 16px;
}
/* ===== Select / Dropdown ===== */
.card-pf select,
.login-pf-page select {
background-color: var(--cai-bg-input) !important;
border: 1px solid var(--cai-border-secondary) !important;
border-radius: 8px !important;
color: var(--cai-text-primary) !important;
padding: 10px 14px !important;
font-family: 'Inter', sans-serif !important;
font-size: 14px !important;
}
/* ===== Social Login / Identity Providers ===== */
#kc-social-providers {
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid var(--cai-border-primary);
}
#kc-social-providers ul {
list-style: none;
padding: 0;
margin: 0;
}
#kc-social-providers li {
margin-bottom: 8px;
}
#kc-social-providers a,
#kc-social-providers .pf-c-button {
background-color: var(--cai-bg-surface) !important;
border: 1px solid var(--cai-border-secondary) !important;
border-radius: 8px !important;
color: var(--cai-text-primary) !important;
padding: 10px 16px !important;
display: block;
text-align: center;
font-size: 14px !important;
font-weight: 500 !important;
transition: border-color 0.15s ease !important;
}
#kc-social-providers a:hover,
#kc-social-providers .pf-c-button:hover {
border-color: var(--cai-accent) !important;
}
/* ===== Form Buttons Row ===== */
#kc-form-buttons {
margin-top: 8px !important;
}
#kc-form-options {
margin-bottom: 4px;
}
/* ===== Tooltip ===== */
.kc-tooltip-text {
background-color: var(--cai-bg-surface) !important;
color: var(--cai-text-primary) !important;
border: 1px solid var(--cai-border-secondary) !important;
border-radius: 8px !important;
font-size: 13px !important;
}
/* ===== Scrollbar ===== */
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: var(--cai-bg-body);
}
::-webkit-scrollbar-thumb {
background: var(--cai-border-secondary);
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--cai-text-faint);
}
/* ===== Responsive ===== */
@media (max-width: 768px) {
.login-pf-page {
padding: 24px 16px;
}
.card-pf {
padding: 24px !important;
}
#kc-header-wrapper {
font-size: 24px !important;
}
#kc-header-wrapper::before {
width: 48px;
height: 48px;
}
#kc-info.login-pf-signup {
margin: 0 -24px -24px !important;
padding: 16px 24px !important;
}
}
/* ===== Override PatternFly background images ===== */
.login-pf-page .login-pf-page-header,
.login-pf body {
background-image: none !important;
}
/* Remove any PF4 container-fluid stretching */
.container-fluid {
padding: 0 !important;
max-width: none !important;
}
/* Ensure the card doesn't stretch full width */
.login-pf-page > .card-pf {
max-width: 440px;
margin: 0 auto !important;
}