/* =============================================================================
   HACT CTMS - login theme styles
   -----------------------------------------------------------------------------
   Loaded in addition to the parent theme's PatternFly stylesheets, which are
   kept because they are what make Keycloak's own components (alerts, required
   actions, the password visibility control) render correctly.

   Structure
     1. tokens       - the brand palette, spacing and radii
     2. brand panel  - the left-hand column, desktop only
     3. page + card  - background, card, headings
     4. controls     - inputs, focus states, password toggle, checkbox
     5. buttons + links
     6. alerts       - Keycloak error/warning/success/info messages
     7. motion       - subtle, and fully disabled for reduced motion
     8. responsive   - single column below 992px, tuned for small screens
     9. accessibility- focus visibility and high-contrast support

   Every colour is a token so the palette is declared once. Contrast: body
   text #0f2a4d on white (13.4:1), muted #48607d on white (6.4:1), button
   label white on #1d4ed8 (6.7:1) - all above the WCAG AA 4.5:1 threshold.
   ========================================================================== */

/* --- 1. Tokens ------------------------------------------------------------ */

:root {
  --hact-blue-700: #1d4ed8;
  --hact-blue-600: #2563eb;
  --hact-blue-300: #93b4ea;
  --hact-blue-200: #c7dbf7;
  --hact-blue-100: #e8f1fe;
  --hact-blue-050: #f4f8fe;

  --hact-navy-900: #0f2a4d;
  --hact-navy-600: #48607d;

  --hact-white: #ffffff;
  --hact-border: #dbe7f8;
  --hact-danger: #b42318;
  --hact-danger-bg: #fef3f2;
  --hact-success: #05603a;
  --hact-success-bg: #ecfdf3;
  --hact-warning: #93370d;
  --hact-warning-bg: #fffaeb;
  --hact-info: #0f2a4d;
  --hact-info-bg: #eff6ff;

  --hact-radius: 12px;
  --hact-radius-sm: 8px;
  --hact-shadow: 0 18px 40px -18px rgba(15, 42, 77, 0.28);
  --hact-shadow-sm: 0 1px 2px rgba(15, 42, 77, 0.06);
  --hact-ring: 0 0 0 3px rgba(37, 99, 235, 0.28);
  --hact-font: "Inter", "Segoe UI", system-ui, -apple-system, "Helvetica Neue",
    Arial, sans-serif;
}

/* --- 2. Brand panel ------------------------------------------------------- */

/* The two-column shell. The grid lives on a wrapper rather than on
   .login-pf-page so the built-in container keeps its own layout rules
   untouched; on narrow screens the grid collapses to one column and the
   panel is trimmed by the media query in section 8. */
.hact-shell {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  min-height: 100vh;
}

.hact-brand {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  padding: 3.5rem;
  background: var(--hact-blue-050);
  border-right: 1px solid var(--hact-border);
}

.hact-brand__inner {
  position: relative;
  z-index: 1;
  max-width: 30rem;
}

/* Decorative shapes: flat, low-contrast circles. They carry no information and
   are hidden from assistive technology by aria-hidden on the <aside>. */
.hact-brand__blob {
  position: absolute;
  border-radius: 50%;
  background: var(--hact-blue-100);
}

.hact-brand__blob--a {
  width: 22rem;
  height: 22rem;
  top: -7rem;
  right: -6rem;
}

.hact-brand__blob--b {
  width: 13rem;
  height: 13rem;
  bottom: -4rem;
  left: -3rem;
  background: var(--hact-blue-200);
  opacity: 0.45;
}

.hact-brand__blob--c {
  width: 7rem;
  height: 7rem;
  top: 45%;
  right: 22%;
  background: var(--hact-blue-200);
  opacity: 0.3;
}

.hact-brand__logo {
  display: block;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 14px;
  box-shadow: var(--hact-shadow-sm);
}

.hact-brand__name {
  margin: 1.25rem 0 0.25rem;
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--hact-navy-900);
}

.hact-brand__full {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--hact-blue-700);
}

.hact-brand__art {
  display: block;
  width: 100%;
  max-width: 27.5rem;
  height: auto;
  margin: 2rem 0 1.5rem;
}

.hact-brand__blurb {
  margin: 0 0 1.5rem;
  max-width: 26rem;
  font-size: 1.05rem;
  line-height: 1.6;
  color: var(--hact-navy-600);
}

.hact-brand__facts {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.6rem;
}

.hact-brand__facts li {
  position: relative;
  padding-left: 1.75rem;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--hact-navy-900);
}

/* A drawn tick rather than a bullet glyph, so it renders identically on every
   platform and carries no emoji or dingbat font dependency. */
.hact-brand__facts li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.34em;
  width: 0.95rem;
  height: 0.5rem;
  border-left: 2px solid var(--hact-blue-600);
  border-bottom: 2px solid var(--hact-blue-600);
  transform: rotate(-45deg);
}
/* --- 3. Page and card ----------------------------------------------------- */

body {
  font-family: var(--hact-font);
  color: var(--hact-navy-900);
  background: var(--hact-white);
  -webkit-font-smoothing: antialiased;
}

.hact-shell > .login-pf-page {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 3rem 2.5rem;
  background: var(--hact-white);
  overflow: hidden;
}

/* On the login page the built-in template puts the header and the form inside
   a single .card-pf, so the card is restyled into the bordered, rounded,
   softly shadowed panel the design calls for. `width: 100%` with a max-width
   replaces PatternFly's fixed grid offsets, which is what stops the card from
   overflowing the column. */
.login-pf-page .card-pf {
  width: 100%;
  max-width: 27rem;
  margin: 0 auto;
  padding: 2.5rem 2.25rem;
  border: 1px solid var(--hact-border);
  border-radius: var(--hact-radius);
  box-shadow: var(--hact-shadow);
  background: var(--hact-white);
}

/* The built-in header is a full-bleed bar; inside the card it becomes a plain
   block so the heading sits in the normal document flow. */
.login-pf-page .login-pf-page-header {
  margin: 0 0 1.75rem;
  padding: 0;
  text-align: center;
  background: transparent;
  height: auto;
  line-height: 1.4;
}

.login-pf-page .login-pf-header {
  margin: 0 0 0.5rem;
  padding: 0;
  background: transparent;
}

/* The HACT lockup inside the card: mark plus wordmark, centred above the
   heading. The mark is decorative, so the wordmark carries the name. */
.hact-lockup {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 1.25rem;
}

.hact-lockup__mark {
  display: block;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 10px;
  box-shadow: var(--hact-shadow-sm);
}

.hact-lockup__name {
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--hact-navy-900);
}

.login-pf-page .login-pf-page-header h1,
.hact-title {
  margin: 0;
  font-size: 1.6rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--hact-navy-900);
}

.hact-subtitle {
  margin: 0.4rem 0 0;
  font-size: 0.95rem;
  font-weight: 400;
  color: var(--hact-navy-600);
}

#kc-content {
  background: transparent;
  padding: 0;
  width: 100%;
}

.login-pf-page #kc-content-wrapper,
.login-pf-page #kc-form,
.login-pf-page #kc-form-wrapper {
  width: 100%;
  margin: 0;
  padding: 0;
}

/* PatternFly's column offsets are replaced by block flow: the card owns the
   spacing now, and the offsets only cause overflow at narrow widths. */
.login-pf-page .col-sm-10,
.login-pf-page .col-md-10,
.login-pf-page .col-lg-8,
.login-pf-page [class*="col-"] {
  width: 100%;
  max-width: 100%;
  padding-left: 0;
  padding-right: 0;
  margin-left: 0;
  margin-right: 0;
  float: none;
}

/* --- 4. Controls ---------------------------------------------------------- */

.login-pf-page label {
  margin-bottom: 0.4rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--hact-navy-900);
}

.login-pf-page input[type="text"],
.login-pf-page input[type="email"],
.login-pf-page input[type="password"],
.login-pf-page input[type="tel"],
.login-pf-page input[type="number"],
.login-pf-page textarea {
  width: 100%;
  height: 2.875rem;
  padding: 0 0.9rem;
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--hact-navy-900);
  background: var(--hact-white);
  border: 1px solid var(--hact-blue-200);
  border-radius: var(--hact-radius-sm);
  box-shadow: var(--hact-shadow-sm);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.login-pf-page textarea {
  height: auto;
  padding: 0.65rem 0.9rem;
  line-height: 1.5;
}

.login-pf-page input::placeholder,
.login-pf-page textarea::placeholder {
  color: #8a9bb0;
}

/* Focus is shown with both a border change and a ring, so it is visible on
   white and still distinguishable without relying on hue alone. */
.login-pf-page input:focus,
.login-pf-page textarea:focus {
  border-color: var(--hact-blue-600);
  box-shadow: var(--hact-ring);
  outline: 2px solid transparent;
  outline-offset: 2px;
}

/* Keycloak marks a failed attempt with aria-invalid, so the error state is
   driven by the same attribute the screen reader announces. */
.login-pf-page input[aria-invalid="true"] {
  border-color: #f04438;
  background: #fffbfb;
}

.login-pf-page input[aria-invalid="true"]:focus {
  box-shadow: 0 0 0 3px rgba(240, 68, 56, 0.25);
  border-color: #d92d20;
}

.login-pf-page .form-group {
  margin-bottom: 1.25rem;
}

/* Field-level validation text. The template renders it with aria-live, so the
   announcement is already handled; this only makes it visible and calm. */
.login-pf-page .pf-c-form__helper-text.pf-m-error,
.login-pf-page .kc-feedback-text {
  display: block;
  margin-top: 0.4rem;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--hact-danger);
}

.login-pf-page .required {
  color: var(--hact-danger);
}

/* Password field and the show/hide control. Keycloak's own script toggles the
   icon on the button, so only the presentation is changed here. */
.login-pf-page .pf-c-input-group {
  position: relative;
  display: flex;
  width: 100%;
  margin: 0;
  /* PatternFly draws the input group as a bordered box of its own, which
     would put a second outline around the field the user is typing into.
     The field already carries its own border, so the group is neutralised and
     only supplies positioning for the visibility button. */
  border: 0;
  background: transparent;
  box-shadow: none;
}

.login-pf-page .pf-c-input-group .pf-c-form-control {
  padding-right: 3rem;
}

/* Password reveal control.
   Keycloak renders this button after the field wrapper with
   `class="pf-c-button pf-m-control"`. Two things make it awkward:
   the field is 100% wide, so the button lands under the input, and
   PatternFly gives `.pf-c-button.pf-m-control` inside an input group its own
   border, background and `position: relative`, which draws a control box
   inside the field.
   The selector is deliberately unscoped: Keycloak 26 does not render the
   `login-pf-page` wrapper on this page, so a rule scoped by it silently never
   matches and the button falls back to PatternFly's defaults. `!important` is
   applied only to the properties PatternFly also sets, so that this file wins
   the cascade regardless of the order the two stylesheets arrive in. */
[data-password-toggle] {
  position: absolute !important;
  top: 50% !important;
  right: 0.35rem !important;
  transform: translateY(-50%) !important;
  z-index: 1 !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0 !important;
  color: var(--hact-navy-600);
  background-color: transparent !important;
  border: 0 !important;
  border-radius: 6px;
  box-shadow: none;
  cursor: pointer;
  transition: color 0.15s ease, background-color 0.15s ease;
}

[data-password-toggle]:hover {
  color: var(--hact-blue-700);
  background-color: var(--hact-blue-050) !important;
}

.login-pf-page [data-password-toggle]:focus-visible {
  outline: 2px solid var(--hact-blue-600);
  outline-offset: 1px;
  color: var(--hact-blue-700);
}

/* Remember me and the other inline options. */
.login-pf-page .pf-c-check {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-size: 0.9rem;
  color: var(--hact-navy-900);
}

.login-pf-page .pf-c-check__input {
  width: 1.05rem;
  height: 1.05rem;
  margin: 0;
  accent-color: var(--hact-blue-600);
  cursor: pointer;
}

.login-pf-page .pf-c-check__label {
  font-weight: 500;
  cursor: pointer;
}

.login-pf-page .login-pf-settings {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}
/* --- 5. Buttons and links ------------------------------------------------- */

.login-pf-page .btn-primary,
.login-pf-page button[type="submit"],
.login-pf-page input[type="submit"] {
  display: block;
  width: 100%;
  min-height: 2.875rem;
  padding: 0.7rem 1.25rem;
  font-family: inherit;
  font-size: 1rem;
  font-weight: 600;
  color: var(--hact-white);
  background: var(--hact-blue-700);
  border: 1px solid var(--hact-blue-700);
  border-radius: var(--hact-radius-sm);
  box-shadow: none;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease,
    transform 0.15s ease;
}

.login-pf-page .btn-primary:hover,
.login-pf-page button[type="submit"]:hover,
.login-pf-page input[type="submit"]:hover {
  background: #1a43bb;
  border-color: #1a43bb;
}

.login-pf-page .btn-primary:active,
.login-pf-page button[type="submit"]:active,
.login-pf-page input[type="submit"]:active {
  transform: translateY(1px);
}

.login-pf-page .btn-primary:focus-visible,
.login-pf-page button[type="submit"]:focus-visible,
.login-pf-page input[type="submit"]:focus-visible {
  outline: 2px solid var(--hact-navy-900);
  outline-offset: 2px;
}

.login-pf-page .btn-primary[disabled] {
  background: var(--hact-blue-300);
  border-color: var(--hact-blue-300);
  cursor: not-allowed;
  transform: none;
}

/* Secondary buttons: "Cancel" on the required-action screens. */
.login-pf-page .btn-default {
  min-height: 2.75rem;
  padding: 0.6rem 1.25rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--hact-navy-900);
  background: var(--hact-white);
  border: 1px solid var(--hact-blue-200);
  border-radius: var(--hact-radius-sm);
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.login-pf-page .btn-default:hover {
  background: var(--hact-blue-050);
  border-color: var(--hact-blue-300);
}

.login-pf-page a {
  color: var(--hact-blue-700);
  font-weight: 500;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.login-pf-page a:hover {
  color: #1a43bb;
  border-bottom-color: currentColor;
}

.login-pf-page a:focus-visible {
  outline: 2px solid var(--hact-blue-600);
  outline-offset: 3px;
  border-radius: 2px;
}

/* --- 6. Alerts ------------------------------------------------------------ */

/* Keycloak's own error, warning, info and success messages. The template
   renders them as .alert-<type>; only the palette is changed, so the messages
   themselves and their roles are untouched. */
.login-pf-page .alert-error,
.login-pf-page .pf-c-alert.pf-m-danger {
  margin-bottom: 1.5rem;
  padding: 0.85rem 1rem;
  font-size: 0.9rem;
  color: var(--hact-danger);
  background: var(--hact-danger-bg);
  border: 1px solid #fecdca;
  border-left: 3px solid #f04438;
  border-radius: var(--hact-radius-sm);
}

.login-pf-page .alert-warning,
.login-pf-page .pf-c-alert.pf-m-warning {
  margin-bottom: 1.5rem;
  padding: 0.85rem 1rem;
  font-size: 0.9rem;
  color: var(--hact-warning);
  background: var(--hact-warning-bg);
  border: 1px solid #fedf89;
  border-left: 3px solid #f79009;
  border-radius: var(--hact-radius-sm);
}

.login-pf-page .alert-info,
.login-pf-page .pf-c-alert.pf-m-info {
  margin-bottom: 1.5rem;
  padding: 0.85rem 1rem;
  font-size: 0.9rem;
  color: var(--hact-info);
  background: var(--hact-info-bg);
  border: 1px solid var(--hact-blue-200);
  border-left: 3px solid var(--hact-blue-600);
  border-radius: var(--hact-radius-sm);
}

.login-pf-page .alert-success,
.login-pf-page .pf-c-alert.pf-m-success {
  margin-bottom: 1.5rem;
  padding: 0.85rem 1rem;
  font-size: 0.9rem;
  color: var(--hact-success);
  background: var(--hact-success-bg);
  border: 1px solid #a6f4c5;
  border-left: 3px solid #12b76a;
  border-radius: var(--hact-radius-sm);
}

.login-pf-page .alert-error .pf-c-alert__icon,
.login-pf-page .alert-warning .pf-c-alert__icon,
.login-pf-page .alert-info .pf-c-alert__icon,
.login-pf-page .alert-success .pf-c-alert__icon {
  color: inherit;
  opacity: 0.9;
}
/* --- 7. Motion ------------------------------------------------------------ */

/* Deliberately small: a short fade for the card and a slow drift for the
   illustration. Transform and opacity only, so nothing triggers layout.
   The reduced-motion block in section 8 switches all of it off. */
@keyframes hact-card-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes hact-art-drift {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-8px);
  }
}

.login-pf-page .card-pf {
  animation: hact-card-in 0.35s ease-out both;
}

.hact-brand__art {
  animation: hact-art-drift 7s ease-in-out infinite;
}

.hact-brand__inner {
  animation: hact-card-in 0.4s ease-out both;
}

/* --- 8. Responsive -------------------------------------------------------- */

/* Tablet and below: one column. The illustration costs the most space and the
   least meaning once the card is full width, so it is dropped; the name and
   full title stay, so the page is still branded. */
@media (max-width: 991.98px) {
  .hact-shell {
    grid-template-columns: minmax(0, 1fr);
  }

  .hact-brand {
    padding: 2.25rem 1.75rem 2rem;
    border-right: 0;
    border-bottom: 1px solid var(--hact-border);
  }

  .hact-brand__art,
  .hact-brand__blurb,
  .hact-brand__facts,
  .hact-brand__blob--c {
    display: none;
  }

  .hact-brand__name {
    margin-top: 0.85rem;
    font-size: 1.4rem;
  }

  .hact-brand__logo {
    width: 2.75rem;
    height: 2.75rem;
  }

  .hact-shell > .login-pf-page {
    padding: 2rem 1.25rem 3rem;
  }

  .login-pf-page .card-pf {
    max-width: 30rem;
  }
}

/* Phones: the card goes edge to edge and the internal padding tightens, so
   nothing forces a horizontal scrollbar. */
@media (max-width: 575.98px) {
  .hact-brand {
    padding: 1.75rem 1.25rem 1.5rem;
  }

  .hact-shell > .login-pf-page {
    padding: 1.5rem 1rem 2.5rem;
  }

  .login-pf-page .card-pf {
    padding: 1.75rem 1.25rem;
    border-radius: 10px;
  }

  .hact-title,
  .login-pf-page .login-pf-page-header h1 {
    font-size: 1.4rem;
  }

  .login-pf-page .login-pf-settings {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
  }
}

/* Reduced motion: honour the preference by removing the animation entirely
   rather than merely shortening it. */
@media (prefers-reduced-motion: reduce) {
  .login-pf-page .card-pf,
  .hact-brand__inner,
  .hact-brand__art {
    animation: none;
  }

  .login-pf-page *,
  .hact-brand * {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

/* --- 9. Accessibility ----------------------------------------------------- */

/* A visible, high-contrast focus ring for keyboard users on anything not
   covered by a component rule above. :focus-visible keeps it off mouse clicks
   while guaranteeing it for the keyboard. */
.login-pf-page a:focus-visible,
.login-pf-page button:focus-visible,
.login-pf-page input:focus-visible,
.login-pf-page [tabindex]:focus-visible {
  outline: 2px solid var(--hact-blue-700);
  outline-offset: 2px;
}

.login-pf-page .pf-c-dropdown,
.login-pf-page .sr-only {
  color: var(--hact-navy-900);
}

/* Windows High Contrast / forced-colors: keep the card and controls
   distinguishable when the author colours are discarded. */
@media (forced-colors: active) {
  .login-pf-page .card-pf,
  .login-pf-page input,
  .login-pf-page button[type="submit"] {
    border: 1px solid CanvasText;
  }

  .hact-brand__blob {
    display: none;
  }
}
