/*
 * The CatalogSOD sign-in pages.
 *
 * The one hand-written file in this theme. It names tokens from tokens.css,
 * which packages/ui generates, and it carries no hex value of its own -- the
 * palette is frozen in docs/requirements/ui-ux-requirements.md and reaches
 * every surface through that one package. UI-001 and UI-002.
 *
 * The parent theme is PatternFly v5. Most rules below set a PatternFly variable
 * rather than restyling a component, so a Keycloak upgrade that changes markup
 * still finds the palette. Only the shapes PatternFly has no variable for are
 * written as rules.
 *
 * Three tokens carry a usage rule, measured in packages/ui/src/tokens.test.ts:
 *
 *   --primary   3.1:1 on a light surface. A filled control uses --action.
 *   --accent    2.0:1 on white. A fill or a decoration, never text.
 *   --border    1.3:1. A field always shows a label and a focus ring too.
 */

/*
 * PatternFly resolves its light palette on :root and its dark palette on
 * .pf-v5-theme-dark, which the parent template adds from the system preference.
 * The tokens already answer that same preference, so both selectors receive the
 * same mapping and each token supplies the value for the theme in force.
 * UI-015.
 */
:root,
.pf-v5-theme-dark {
  --pf-v5-global--BackgroundColor--100: var(--surface);
  --pf-v5-global--BackgroundColor--200: var(--surface-muted);
  --pf-v5-global--BackgroundColor--light-300: var(--canvas);
  --pf-v5-global--Color--100: var(--text);
  --pf-v5-global--Color--200: var(--text-muted);
  --pf-v5-global--BorderColor--100: var(--border);

  /* A filled control and a link both use --action. Never --primary. */
  --pf-v5-global--primary-color--100: var(--action);
  --pf-v5-global--primary-color--200: var(--action);
  --pf-v5-global--active-color--100: var(--action);
  --pf-v5-global--link--Color: var(--action);
  --pf-v5-global--link--Color--hover: var(--action);

  --pf-v5-global--danger-color--100: var(--danger);
  --pf-v5-global--success-color--100: var(--success);
  --pf-v5-global--warning-color--100: var(--warning);

  --pf-v5-global--FontFamily--text: var(--font-sans);
  --pf-v5-global--FontFamily--heading: var(--font-sans);
  --pf-v5-global--FontFamily--monospace: var(--font-mono);

  --pf-v5-global--BorderRadius--sm: var(--radius-control);
  --pf-v5-global--BoxShadow--sm: var(--shadow);
  --pf-v5-global--BoxShadow--md: var(--shadow-raised);

  /* The line above the card. The parent paints it Keycloak blue. */
  --keycloak-card-top-color: var(--primary);
}

/*
 * The page. The parent serves a Keycloak illustration as a fixed background;
 * COLOR-001 and IDENT-004 ask for a plain surface under the task instead.
 */
.login-pf body {
  background: var(--canvas);
  color: var(--text);
}

/*
 * Where the card sits. The parent centres it in the full viewport height, which
 * puts it noticeably lower than the entry card in the application, and a person
 * crosses between the two inside one task. This is the .entry rule from
 * apps/web/app/globals.css: centred in the upper part of the page, with the
 * footer below it rather than off the bottom.
 */
.pf-v5-c-login {
  align-items: center;
  min-height: 62vh;
  padding-block-end: var(--space-6);
  padding-block-start: var(--space-6);
}

/* ------------------------------------------------------------- wordmark ---- */

/*
 * CatalogSOD, always. The realm carries the wordmark as its displayNameHtml and
 * the header renders it here. AGENTS.md, section Naming, and IDENT-001.
 *
 * The parent theme prints this line in uppercase and paints it white with an
 * `!important`, because it expects the Keycloak illustration behind it. On a
 * light canvas that is white on near-white. The declaration below answers that
 * `!important` and nothing else here needs one; the parent's uppercase and its
 * wide tracking are plain declarations that this block simply outranks.
 */
#kc-header-wrapper {
  color: var(--primary-strong) !important;
  font-size: clamp(2.125rem, 1.6rem + 2.2vw, 2.5rem);
  font-weight: 350;
  letter-spacing: -0.01em;
  line-height: 1.15;
  padding: var(--space-6) 0 var(--space-5);
  text-align: center;
  text-transform: none;
}

#kc-header-wrapper b {
  font-weight: 800;
}

/* ----------------------------------------------------------------- card ---- */

.pf-v5-c-login__main {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow);
}

#kc-page-title {
  color: var(--text);
  font-size: var(--type-title-size);
  font-weight: var(--type-title-weight);
  line-height: var(--type-title-line);
}

/* ---------------------------------------------------------------- field ---- */

/*
 * PatternFly draws a field as a bottom rule. The design system draws a bordered
 * box with a radius, so the pseudo-element borders are cleared and one real
 * border replaces them. --border measures 1.3:1 against a light surface, under
 * the 3:1 rule for a non-text control, so the box never marks the field alone:
 * the label above it and the focus ring below do that.
 */
.pf-v5-c-form-control {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  color: var(--text);
  min-height: 44px;
}

.pf-v5-c-form-control::before,
.pf-v5-c-form-control::after {
  border: 0;
}

/*
 * The control inside the wrapper. PatternFly paints the select and the input
 * themselves as well as the box around them, and its dark value is a grey that
 * belongs to no token. Naming a surface here leaves one surface.
 *
 * The colour is written out rather than left transparent or inherited. A browser
 * paints the open list of a select with that element's own background, and a
 * transparent one falls back to white while the text stays with the theme. In
 * the dark theme that is near-white text on a white list, which is the option a
 * person cannot read.
 */
.pf-v5-c-form-control > input,
.pf-v5-c-form-control > select,
.pf-v5-c-form-control > textarea,
.pf-v5-c-form-control > select option {
  background: var(--surface);
  color: var(--text);
}

/* The password reveal, and any other control sharing a field's row. */
.pf-v5-c-input-group__item .pf-v5-c-button.pf-m-control {
  background: var(--surface-muted);
  border: 1px solid var(--border);
  color: var(--text);
}

.pf-v5-c-form__label-text {
  font-size: var(--type-small-size);
  font-weight: 600;
}

/* --------------------------------------------------------------- button ---- */

/*
 * A primary action fills with --action, never with --primary. White on
 * --primary measures 3.1:1 in the light theme and fails a normal-size label, so
 * --action resolves to primaryStrong in light and to primary in dark, and
 * --on-fill flips to match.
 */
.pf-v5-c-button {
  border-radius: var(--radius-control);
  font-weight: 600;
  min-height: 44px;
  transition: transform var(--motion-press) var(--motion-ease);
}

.pf-v5-c-button.pf-m-primary {
  background: var(--action);
  color: var(--on-fill);
}

.pf-v5-c-button.pf-m-secondary {
  background: var(--surface);
  border: 1px solid var(--action);
  color: var(--action);
}

.pf-v5-c-button.pf-m-link {
  color: var(--action);
  min-height: 32px;
}

/* Visible within 100ms, 98 percent over 120ms. MOTION-001 and MOTION-002. */
.pf-v5-c-button:active {
  transform: scale(var(--motion-press-scale));
}

/* ----------------------------------------------------------------- focus ---- */

/*
 * Never remove an outline without replacing it. A keyboard user navigates by
 * seeing where they are, and this ring is the only thing that tells them. Two
 * pixels in the action colour, offset by two, on any background. UI-011.
 *
 * The components are named as well as the bare pseudo-class, because
 * PatternFly's own focus rules outrank a single :focus-visible.
 */
:focus-visible,
.pf-v5-c-button:focus-visible,
.pf-v5-c-form-control:focus-within,
.pf-v5-c-check__input:focus-visible {
  outline: 2px solid var(--action);
  outline-offset: 2px;
}

/* --------------------------------------------------------- instruction ---- */

/*
 * The sentence above an action, such as the sign-out question. The template
 * puts the paragraph and the form next to each other with no space, so the
 * question reads as a label stuck to the button.
 */
.instruction {
  color: var(--text-muted);
  margin: 0 0 var(--space-6);
  text-wrap: pretty;
}

/* ---------------------------------------------------------------- alert ---- */

/*
 * A failed sign-in. Red means blocked, invalid, or failed, and it never travels
 * alone: PatternFly puts an icon beside the text and the text says the same
 * thing in words. UI-005 and UI-008.
 */
.pf-v5-c-alert.pf-m-danger,
.pf-v5-c-alert.pf-m-error {
  background: var(--danger-tint);
}

.pf-v5-c-alert.pf-m-info {
  background: var(--info-tint);
}

.pf-v5-c-alert.pf-m-success {
  background: var(--success-tint);
}

/* --------------------------------------------------------------- footer ---- */

/*
 * The footer resources/js/appearance.js builds, and the appearance control in
 * it. These rules restate the .site-footer, .theme-field, and .theme-toggle
 * blocks in apps/web/app/globals.css, because a theme mounted into a container
 * cannot import that stylesheet. Both spend the same tokens, so the two footers
 * agree as long as the tokens do. Change one, read the other.
 *
 * TEMPORARY, with the script. See the file header there.
 */
.site-footer {
  margin: 0 auto;
  max-width: 64rem;
  padding: 0 var(--space-5) var(--space-8);
}

.site-footer__inner {
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  display: flex;
  flex-wrap: wrap;
  font-size: var(--type-small-size);
  gap: var(--space-3) var(--space-5);
  padding: var(--space-5) 0;
}

.site-footer a {
  color: var(--primary-strong);
}

/* Targets are 28px, over the 24px floor for a pointer. UI-012. */
.theme-field {
  align-items: center;
  display: flex;
  gap: var(--space-2);
  margin-left: auto;
}

.theme-field__label {
  color: var(--text-muted);
  font-size: var(--type-small-size);
}

.theme-toggle {
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  display: inline-flex;
  overflow: hidden;
}

.theme-toggle__option {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font: inherit;
  font-size: var(--type-small-size);
  min-height: 28px;
  padding: 0 var(--space-3);
}

.theme-toggle__option[aria-pressed="true"] {
  background: var(--surface-muted);
  color: var(--text);
  font-weight: 600;
}

/* The button rules above set 44px and a fill. This control is neither. */
.site-footer .theme-toggle__option {
  border-radius: 0;
  min-height: 28px;
  transition: none;
}

.theme-toggle__option:focus-visible {
  outline-offset: -2px;
}

/* --------------------------------------------------------------- motion ---- */

/* A moving control is decoration, and some people are made ill by it. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  /* MOTION-010 and ACC-007: no scaling, just the state change. */
  .pf-v5-c-button:active {
    transform: none;
  }
}
