/* ENBD Keycloak login theme — aligned with @synapseslab/design-system, glass visual style.
 *
 * Sources of truth (do not invent values here):
 *   Radius / shadow / glass tokens ..... design-system/src/styles/tokens.css  (.ds-glass block)
 *   Colors ............................. colors.json supplied by the client   (ENBD / Light Mode)
 *   Component metrics .................. design-system/src/components/{Button,Input,Alert,Checkbox}
 *
 * Glass radius ramp is 12 / 16 / 20 / 28; buttons, inputs and tabs are capsule (9999px).
 * When adding a radius, pick the tier by surface size — never introduce a new value.
 */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

:root {
    /* ── Colors — ENBD / Light Mode ───────────────────────────────── */
    --primaryColor: #072447;
    /* Primary/Main */
    --primaryHover01: #001B3B;
    /* Primary/Hover 01 */
    --primaryActive01: #00112C;
    /* Primary/Active 01 */
    --backgroundColor: #F4F4F4;
    /* UI/Background */
    --uiField01: #FFFFFF;
    /* UI/Field01 */
    --uiSecondary: #EEEEF0;
    /* UI/Secondary */
    --uiHover: #949AA524;
    /* UI/Hover */
    --uiActive: #949AA547;
    /* UI/Active */
    --errorMain: #E53935;
    /* Error/Main — also Text/Errortext */
    --errorAccent01: #E95E5C;
    /* Error/Accent 01 */
    --errorAccent02: #570C0B;
    /* Error/Accent 02 — Alert label, per variantTextClasses. 10.49:1 on
       Error/Background here, so this palette has none of the alert contrast
       shortfall the Blue GPS one is tracked for. */
    --errorBackground: #FFD3C2;
    /* Error/Background */
    --focusBorderColor: #8898AE;
    /* Actions/Focusborder */
    --textPrimary: #072447;
    /* Text/Primary */
    --textSecondary: #3A4B5C;
    /* Text/Secondary */
    --textTertiary: #6C7A89;
    /* Text/Tertiary */
    --textButton02Color: #293641;
    /* Text/Button02 */
    --textButtonContained: #FAFAFA;
    /* Text/Buttoncontained01 */
    --iconPrimary: #3A4B5C;
    /* Icon/Primary */
    --iconSecondary: #5E6168;
    /* Icon/Secondary */
    --secondaryAccent01: #BFCDD9;
    /* Secondary/Accent 01 */

    /* ── Radius — .ds-glass ───────────────────────────────────────── */
    --ds-radius-modal: 28px;
    /* lg — the login card is a large focused surface */
    --ds-radius-dropdown: 20px;
    /* md */
    --ds-radius-alert: 16px;
    /* sm */
    --ds-radius-button: 9999px;
    /* capsule */
    --ds-radius-input: 9999px;
    /* capsule */
    --ds-radius-checkbox: 4px;
    /* Checkbox default is rounded-sm, not a pill */

    /* ── Shadows — .ds-glass ──────────────────────────────────────── */
    --ds-shadow-modal: 0px 8px 32px -4px rgba(0, 0, 0, 0.12);
    --ds-shadow-dropdown: 0px 12px 32px -8px rgba(0, 0, 0, 0.15);

    /* ── Glass surface ───────────────────────────────────────────────
     * The login page background is a flat color, and backdrop-filter over a
     * flat fill produces no visible frost — so the blur is deliberately not
     * applied. Introduce a gradient or image background and the commented
     * block on .card-pf below turns the real frosted surface on.
     */
    --ds-glass-surface-bg: rgba(255, 255, 255, 0.96);
    --ds-glass-border: rgba(255, 255, 255, 0.45);
    --ds-glass-blur: 20px;

    /* ── Metrics — Input size="md" / Button size="l" ──────────────── */
    --field-height: 48px;
    --field-padding-x: 16px;
    --logo-height: 40px;
    /* 40px tall = 126px wide at the logo's 126:40 ratio */

    /* ── Vertical rhythm ─────────────────────────────────────────────
     * PatternFly v3 carries Bootstrap's `.form-group { margin-bottom: 15px }`,
     * which was the *only* step in the whole card: fields, the remember-me row,
     * the primary action and the IdP block all sat at one distance, so nothing
     * grouped. Three steps instead, on the design system's 4px grid — 16px is
     * the gap its own demos use to stack fields (space-y-4). */
    --rhythm-field: 16px;
    --rhythm-group: 24px;
    --rhythm-section: 32px;

    /* ── Typography ──────────────────────────────────────────────────
     * The design system does not bundle fonts; the consumer loads them.
     * Inter comes from Google Fonts above, Schibsted Grotesk is shipped
     * with this theme, and both fall back to system fonts.
     */
    --fontFamily: 'Inter', system-ui, -apple-system, sans-serif;
    --fontFamilyDisplay: 'Schibsted Grotesk', system-ui, -apple-system, sans-serif;
}

@font-face {
    font-family: Schibsted Grotesk;
    src: url(../fonts/SchibstedGrotesk-Bold.ttf);
    font-weight: 700;
    font-display: swap;
}

@font-face {
    font-family: IconMoon;
    src: url(../fonts/IconMoon.ttf);
    font-display: block;
}

body * {
    font-family: var(--fontFamily);
}

h2 {
    font-family: var(--fontFamily);
    font-size: 12px;
    font-weight: 400;
    color: var(--textTertiary);
}


/* ── Page shell ──────────────────────────────────────────────────── */

/* PatternFly sets html, body { height: 100% }, capping the body at the
 * viewport. `justify-content: center` distributes only *positive* free space:
 * with a card taller than the viewport it still centres, so the card overflows
 * both ways and its top becomes unreachable — measured at top: -62px on a
 * 613px viewport in the current theme, i.e. the logo is cut off and no amount
 * of scrolling reaches it. Letting the body grow past the viewport keeps the
 * centring for short content and makes tall content scroll instead.
 * Pre-existing defect, fixed here because this area is being rewritten. */
html.login-pf,
.login-pf body {
    height: auto;
    min-height: 100vh;
}

/* patternfly-additions.min.css paints the <html> element itself:
 *   .login-pf { height: 100%; background: #030303 url(../img/bg-login.jpg) ... }
 * That is PatternFly's own dark image, not this theme's. It used to stay
 * hidden because html and body were both exactly 100% tall, so body covered
 * it; dropping that height above removed the guarantee, and anything making
 * the document taller than the body exposed a black band. Painting html too
 * closes the whole class of bug rather than the one instance of it. */
html.login-pf {
    background: var(--backgroundColor);
}

.login-pf body {
    background: var(--backgroundColor);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

/* logo.svg is intrinsically 126x40, so at --logo-height it renders 1:1.
 * `contain` is kept so a future logo of any ratio still fits the box
 * instead of being painted at full size and clipped. */
#logo-img {
    background-image: url("../img/logo.svg?v=2.0.7");
    background-position: center;
    background-repeat: no-repeat;
    background-size: contain;
    height: var(--logo-height);
    margin-bottom: var(--rhythm-field);
}

.login-pf-page {
    padding: 20px;
    display: flex;
    flex-direction: row;
    justify-content: center;
    width: 100%;
}

#kc-header-wrapper {
    font-size: 0;
}

#kc-header {
    color: black;
    overflow: visible;
    background-image: url("../img/logo.svg?v=2.0.7");
    background-position: center;
    background-repeat: no-repeat;
    background-size: 180px;
    white-space: nowrap;
    display: none;
}


/* ── Login card — Modal tier ─────────────────────────────────────── */

.card-pf {
    background: var(--uiField01);
    box-shadow: var(--ds-shadow-modal);
    /* --ds-glass-border is rgba(255,255,255,.45): invisible on a light ground,
     * which left the card defined by its shadow alone. */
    border: 1px solid var(--uiSecondary);
    border-radius: var(--ds-radius-modal);
    padding: 24px;
}

/* Real frosted surface — enable together with a non-flat page background:
.card-pf {
    background: var(--ds-glass-surface-bg);
    backdrop-filter: blur(var(--ds-glass-blur));
    -webkit-backdrop-filter: blur(var(--ds-glass-blur));
}
*/

.login-pf-page .card-pf {
    inline-size: 100%;
    max-inline-size: 460px;
}

/* Two-panel inside the card, not across the page. .card-pf has exactly two
 * children — <header class="login-pf-header"> and <div id="kc-content"> — so a
 * grid can hold the image in one column as a ::before and stack both children
 * in the other. No .ftl needed.
 *
 * Declared inside min-width, mobile-first: below the breakpoint the base
 * single-column card above is what applies. That is the better structure, but
 * it does not save the download — measured in Chrome, the preload scanner
 * fetches a stylesheet's url() without evaluating media queries, so narrow
 * screens still pull the 40KB. Avoiding it needs a media-scoped <link> or
 * <picture>, i.e. markup this theme deliberately does not own.
 *
 * 900px: the image column is 40%, leaving 60% = 540px minus 2x32px of padding
 * = 476px for a form that needs ~412px. */
@media screen and (min-width: 900px) {

    .login-pf-page .card-pf {
        display: grid;
        grid-template-columns: 40% 1fr;
        grid-template-rows: auto 1fr;
        max-inline-size: 900px;
        padding: 0;
        overflow: hidden;
    }

    .login-pf-page .card-pf::before {
        content: '';
        grid-column: 1;
        grid-row: 1 / -1;
        background-image: url("../img/bg-login.jpg?v=2.0.7");
        background-position: center;
        background-size: cover;
        background-repeat: no-repeat;
    }

    /* Both children into the second column, stacked. Anything else Keycloak
     * might add lands there too rather than auto-placing over the image. */
    .login-pf-page .card-pf > * {
        grid-column: 2;
    }

    .login-pf-page .card-pf > .login-pf-header {
        grid-row: 1;
        padding: 40px 40px 0;
    }

    .login-pf-page .card-pf > #kc-content {
        grid-row: 2;
        padding: 0 40px 40px;
    }
}

@media screen and (max-width: 560px) {

    /* Full-bleed on small screens: no card edge, so no radius either. */
    .login-pf-page .card-pf {
        width: 100%;
        border: none;
        border-radius: 0;
        background: var(--uiField01);
        box-shadow: none;
    }

    .login-pf body {
        background: var(--uiField01);
    }
}

/* Typography variant="h2" — 28px/36px bold Inter. The card is mapped to the
 * Modal radius tier, and Modal.tsx:107 titles that surface with h2; h1 is 42px
 * display type, which overpowered a 412px column. */
#kc-page-title {
    align-self: start;
    margin: 0 0 var(--rhythm-field);
    color: var(--textPrimary);
    font-family: var(--fontFamily);
    font-size: 28px;
    line-height: 36px;
    font-style: normal;
    font-weight: 700;
    text-align: start;
}


/* ── Vertical rhythm ─────────────────────────────────────────────── */

/* Every form Keycloak renders in the card owns its rhythm, not just the login
 * one: the register page uses #kc-register-form, reset uses
 * #kc-reset-password-form, and others exist. Scoping both rules to the same
 * selector means a form can never end up with the margin zeroed and no gap to
 * replace it — which is what left the register fields touching. */
.card-pf form {
    display: flex;
    flex-direction: column;
    gap: var(--rhythm-field);
}

.card-pf form > .form-group {
    margin-bottom: 0;
}

/* 16px of form gap + 8px = 24px before the primary action. */
#kc-form-buttons {
    margin-top: 8px;
}

#kc-social-providers {
    margin-top: var(--rhythm-section);
}

#kc-info {
    margin-top: var(--rhythm-group);
}

/* The one legitimate exception to the single axis: a left/right pair. */
.login-pf-settings {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--rhythm-field);
}


/* ── Links ───────────────────────────────────────────────────────── */

a {
    color: var(--textButton02Color);
    font-size: 14px;
    font-weight: 500;
}

a:hover,
a:focus {
    color: var(--textButton02Color);
}

a:focus {
    outline: none;
}


/* ── Primary button — Button size="l" btnStyle="filled" ──────────── */

#kc-form-buttons .pf-c-button,
#kc-form-buttons input[type=submit] {
    height: var(--field-height);
    padding: 0 12px;
    border: none;
    border-radius: var(--ds-radius-button);
    background-color: var(--primaryColor);
    color: var(--textButtonContained);
    font-size: 16px;
    line-height: 22px;
    font-weight: 600;
    transition: background-color 200ms;
}

#kc-form-buttons .pf-c-button:hover,
#kc-form-buttons input[type=submit]:hover {
    background-color: var(--primaryHover01);
}

#kc-form-buttons .pf-c-button:active,
#kc-form-buttons input[type=submit]:active {
    background-color: var(--primaryActive01);
}

#kc-form-buttons .pf-c-button:focus-visible,
#kc-form-buttons input[type=submit]:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--focusBorderColor);
}


/* ── Secondary buttons — Button size="l" btnStyle="outlined" ─────── */

.pf-c-button.pf-m-control {
    min-height: var(--field-height);
    margin-bottom: 8px;
    margin-right: 8px;
    padding: 0 12px;
    text-align: center;
    border: 2px solid var(--secondaryAccent01);
    border-radius: var(--ds-radius-button);
    background-color: transparent;
    color: var(--textButton02Color);
    font-weight: 600;
    font-size: 16px;
    line-height: 22px;
    transition: background-color 200ms;
}

.pf-c-button.pf-m-control:hover {
    background-color: var(--uiHover);
    color: var(--textButton02Color);
    border: 2px solid var(--secondaryAccent01);
    border-radius: var(--ds-radius-button);
}

.pf-c-button.pf-m-control:active {
    background-color: var(--uiActive);
}

.pf-c-button.pf-m-control::after {
    border-bottom: none;
    border: none;
}

.pf-c-button.pf-m-control:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--focusBorderColor);
}


/* ── Inputs — Input size="md" ────────────────────────────────────── */

.pf-c-form__label,
.pf-c-form__label-text {
    display: none;
}

.pf-c-form-control {
    box-sizing: border-box;
    height: var(--field-height) !important;
    padding: 0 var(--field-padding-x);
    background: var(--uiField01);
    border: 2px solid var(--uiSecondary);
    border-radius: var(--ds-radius-input);
    font-family: var(--fontFamily);
    font-size: 16px;
    font-style: normal;
    font-weight: 400;
    color: var(--textPrimary);
    overflow: hidden;
    transition: border-color 200ms;
}

.pf-c-form-control:focus {
    outline: none;
    border-color: var(--primaryColor);
}

.pf-c-form-control[aria-invalid=true] {
    border-color: var(--errorMain);
    background: var(--uiField01);
}

.pf-c-form-control::placeholder {
    font-family: var(--fontFamily);
    font-size: 16px;
    font-weight: 400;
    color: var(--textTertiary);
}


/* ── Password field — the toggle lives inside the capsule ────────────
 * The design system renders the visibility toggle as a borderless 20px
 * icon button inside the field border (Input.tsx), not as an adjacent
 * bordered button. PatternFly's input-group becomes that capsule.
 */

.pf-c-input-group {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    gap: 8px;
    height: var(--field-height);
    padding: 0 var(--field-padding-x);
    background: var(--uiField01);
    border: 2px solid var(--uiSecondary);
    border-radius: var(--ds-radius-input);
    overflow: hidden;
    transition: border-color 200ms;
}

.pf-c-input-group:focus-within {
    border-color: var(--primaryColor);
}

.pf-c-input-group:has(.pf-c-form-control[aria-invalid=true]) {
    border-color: var(--errorMain);
}

.pf-c-input-group .pf-c-form-control,
.pf-c-input-group .pf-c-form-control:focus {
    flex: 1;
    min-width: 0;
    height: auto !important;
    padding: 0;
    border: none;
    border-radius: 0;
    background: transparent;
}

.pf-c-input-group .pf-c-button.pf-m-control,
.pf-c-input-group .pf-c-button.pf-m-control:hover {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    min-height: 0;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: var(--ds-radius-button);
    background: transparent;
    color: var(--iconSecondary);
    font-size: 16px;
    transition: color 200ms;
}

.pf-c-input-group .pf-c-button.pf-m-control:hover {
    color: var(--iconPrimary);
}


/* ── Field-level errors ──────────────────────────────────────────── */

#input-error,
#input-error-username,
#input-error-email,
#input-error-password,
#input-error-password-confirm {
    color: var(--errorAccent02);
}


/* ── Alert — Alert component, sm tier ────────────────────────────── */

.pf-c-alert {
    margin-bottom: 8px;
    border-radius: var(--ds-radius-alert);
}

.pf-c-alert.pf-m-danger {
    --pf-c-alert--BorderTopColor: var(--errorAccent01);
    --pf-c-alert__icon--Color: var(--errorAccent02);
    --pf-c-alert__title--Color: var(--errorAccent02);
    --pf-c-alert--m-inline--BackgroundColor: var(--errorBackground);
    border: 2px solid var(--errorAccent01);
}


/* ── Checkbox / radio — Checkbox default (rounded-sm, not a pill) ── */

/* A native checkbox ignores border-radius, so the box has to be drawn.
 * Checkbox.tsx: 20x20, rounded-sm, `border-2 border-icon-primary` when empty,
 * `bg-primary-main` when checked, with a 14px white tick — the path below is
 * that component's, verbatim. */
input[type=checkbox] {
    appearance: none;
    -webkit-appearance: none;
    box-sizing: border-box;
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    margin: 0;
    border: 2px solid var(--iconPrimary);
    border-radius: var(--ds-radius-checkbox);
    background-color: transparent;
    background-repeat: no-repeat;
    background-position: center;
    background-size: 14px 14px;
    cursor: pointer;
    transition: background-color 150ms, border-color 150ms;
}

input[type=checkbox]:checked {
    border-color: var(--primaryColor);
    background-color: var(--primaryColor);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M2.5 7.5L5.5 10.5L11.5 3.5' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

input[type=checkbox]:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--focusBorderColor);
}

input[type=radio] {
    box-sizing: border-box;
    width: 20px;
    height: 20px;
    margin: 0;
    line-height: normal;
    accent-color: var(--primaryColor);
}

/* PatternFly v3 carries Bootstrap's pair for this widget: the label gets
 * `padding-left: 20px` and the box `position: absolute; margin-left: -20px`
 * to sit back inside that padding. Absolute positioning takes the box out of
 * the flex flow, so the row gap below never reached it and the text sat flush
 * against it. Both halves have to go together — dropping only the negative
 * margin leaves the row indented 20px past the fields above. */
.checkbox input[type=checkbox],
.radio input[type=radio] {
    position: static;
    margin-left: 0;
}

/* Keycloak emits `<label><input> Remember me</label>`, so without a flex row
 * the box and the bare text node align on the baseline and touch. */
.checkbox label,
.radio label {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding-left: 0;
    font-weight: 400;
    font-size: 14px;
    color: var(--textPrimary);
    cursor: pointer;
}

.checkbox,
.radio {
    display: block;
    margin-bottom: 0px;
    margin-top: 0px;
}


/* ── Social / identity providers ─────────────────────────────────── */

.kc-social-links {
    margin-top: 20px;
}

.kc-social-links li {
    width: 100%;
}

/* One gap for the whole stack, so the buttons read as a single object.
 * The per-button margins from .pf-c-button.pf-m-control are cleared below. */
.kc-social-grid {
    display: grid;
    column-gap: 10px;
    row-gap: 8px;
    grid-column-end: span 12;
    --pf-l-grid__item--GridColumnEnd: span 12;
}

/* Symmetric padding wide enough for the icon on either side: the label stays
 * on the card's centre axis and can never run under the icon. */
.pf-c-button.pf-m-control.kc-social-item {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0;
    /* Symmetric, wide enough for the icon on either side: the label stays on
     * the card's centre axis and can never run under the icon. */
    padding: 0 44px;
    /* Button size="m" (Button.tsx:22) — 40px against the primary's 48px, so
     * the four secondary actions stop outweighing the form. */
    min-height: 40px;
    font-size: 16px;
    line-height: 22px;
    text-align: center;
}

/* Icon pinned to a fixed offset instead of floated, so in a stack the icons
 * line up in a column while every label sits on the same centre axis. */
.kc-social-provider-logo {
    position: absolute;
    /* Logical, not `left`: with Arabic in `locales` Keycloak renders
     * dir="rtl" and a physical offset leaves the icon on the wrong side. */
    inset-inline-start: var(--field-padding-x);
    top: 50%;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    float: none;
    font-size: 20px;
    line-height: 1;
    color: inherit;
}

/* Drops the old float compensation — the two offsets under-corrected by 5px
 * whenever the grid class was applied, which is any realm with 4+ providers. */
.kc-social-provider-name,
.kc-social-icon-text {
    position: static;
    left: auto;
}

.kc-social-gray {
    color: var(--pf-global--Color--200);
}

.kc-social-gray h2 {
    font-size: 1em;
}

.kc-login-tooltip {
    position: relative;
    display: inline-block;
}

.kc-social-section {
    text-align: center;
}

/* script.js removes the <hr> Keycloak emits here, which left the label
 * floating with nothing to divide. The rule is drawn from the label instead —
 * on both sides, since the label is centred. */
#kc-social-providers h2 {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 0 0 var(--rhythm-field);
}

#kc-social-providers h2::before,
#kc-social-providers h2::after {
    content: '';
    flex: 1;
    block-size: 1px;
    background: var(--uiSecondary);
}

.kc-social-section hr {
    margin-bottom: 10px
}


/* ── Locale selector ─────────────────────────────────────────────── */

/* template.ftl puts #kc-locale inside <header class="login-pf-header"> and
 * script.js inserts #logo-img as the header's firstChild, so the DOM order is
 * logo -> locale -> title. In flow it becomes its own row, which drops the
 * magic offsets and the collision with the title. */
/* `position: relative` with no offsets lays out exactly like static, but it
 * is also the containing block for the absolutely positioned
 * .pf-c-dropdown__menu. Making this static dropped the menu 768px down the
 * page — measured — because it then resolved against the body. The button
 * itself is what needed un-anchoring, and that is done on its own rule below. */
#kc-locale {
    position: relative;
    text-align: end;
    margin-bottom: 4px;
    z-index: 9999;
}

button#kc-current-locale-link {
    display: inline-flex;
    align-items: center;
    min-height: 32px;
    margin-bottom: 8px;
    margin-right: 8px;
    padding: 0 12px;
    text-align: center;
    border: none;
    border-radius: var(--ds-radius-button);
    background-color: transparent;
    color: var(--textSecondary);
    font-size: 16px;
    transition: background-color 200ms;
}

button#kc-current-locale-link:hover {
    background-color: var(--uiHover);
}

button#kc-current-locale-link::after {
    content: '\f078';
    font-family: 'IconMoon';
    font-size: 20px;
    align-self: center;
}

button#kc-current-locale-link[aria-expanded=true]::after {
    content: '\e97f';
}

.pf-c-dropdown .pf-c-menu,
.pf-c-dropdown__menu {
    min-width: 0%;
    border-radius: var(--ds-radius-dropdown);
    box-shadow: var(--ds-shadow-dropdown);
    overflow: hidden;
}

/* The 60px offset compensated for the locale button being absolutely
 * positioned. It is in flow now, so the menu sits just under it. */
.pf-c-dropdown .pf-c-menu.pf-m-align-right,
.pf-c-dropdown__menu.pf-m-align-right {
    margin-top: 4px;
    display: none;
}