/* Syntrix / CampbellON Keycloak Login Theme
   ============================================================================
   Token source:  ui/styles/themes/_keycloak-tokens.scss (manually synced from
   _light.scss). Compile with `npm run build:keycloak-tokens` from ui/ to
   regenerate ./tokens.css alongside this file.

   Conventions:
   - All colors come from var(--mat-sys-*) tokens via ./tokens.css.
   - Typography: DM Sans (Google Fonts).
   - Buttons: 32px height, 9999px radius, Sentence case (no uppercase).
   - Inputs:  36px height, 4px radius, visible label above.
   - Card:    8px border-radius, 1px outline-variant border, no box-shadow.
   ============================================================================ */

@import "./tokens.css";

/* Self-hosted fonts (no external network in air-gapped/on-prem deployments).
   Files live under ../fonts/. Paths are relative to this CSS file.
   DM Sans latin subset is a variable font — one WOFF2 covers 400/500/600. */
@font-face {
  font-family: "DM Sans";
  font-style: normal;
  font-weight: 100 1000;
  font-display: swap;
  src: url("../fonts/dm-sans/DMSans-Regular.woff2") format("woff2");
}
@font-face {
  font-family: "DM Sans";
  font-style: italic;
  font-weight: 100 1000;
  font-display: swap;
  src: url("../fonts/dm-sans/DMSans-Italic.woff2") format("woff2");
}
@font-face {
  font-family: "Material Symbols Outlined";
  font-style: normal;
  font-weight: 400;
  /* block, not swap: this is a ligature icon font — a swap-mode fallback
     renders the raw ligature words ("visibility", "construction") until the
     font arrives. block keeps the text invisible while loading, so worst
     case is a brief blank gap instead of flashed words. template.ftl also
     preloads this file to keep that gap near zero. */
  font-display: block;
  src: url("../fonts/material-symbols/MaterialSymbolsOutlined.woff2")
    format("woff2");
}

.material-symbols-outlined {
  font-family: "Material Symbols Outlined";
  font-weight: normal;
  font-style: normal;
  font-size: 24px;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  display: inline-block;
  white-space: nowrap;
  word-wrap: normal;
  direction: ltr;
  font-feature-settings: "liga";
  -webkit-font-feature-settings: "liga";
  -webkit-font-smoothing: antialiased;
}

/* ── Reset & Base ────────────────────────────────────────── */

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: "DM Sans", sans-serif;
  font-weight: 400;
  font-size: 13px;
  line-height: 20px;
  letter-spacing: 0.25px;
  color: var(--mat-sys-on-surface);
  background-color: var(--mat-sys-surface-dim);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding: 40px 24px;
}

/* Narrow-viewport padding. Below 600px (phones, narrow split-screen)
   tighten the gutter to 24px vertical / 12px horizontal so the form
   card keeps usable input width without the body margin crowding it. */
@media (max-width: 599px) {
  body {
    padding: 24px 12px;
  }
}

a {
  color: var(--mat-sys-on-surface-variant);
  text-decoration: underline;
}

a:hover {
  color: var(--mat-sys-on-surface);
}

a:focus-visible,
.syntrix-link:focus-visible,
.syntrix-back-link:focus-visible {
  outline: 2px solid var(--mat-sys-on-surface);
  outline-offset: 2px;
  border-radius: 2px;
}

/* ── Hide Keycloak default elements ──────────────────────── */

#kc-header,
#kc-header-wrapper {
  display: none;
}

/* ── Card Container ──────────────────────────────────────── */

#kc-login {
  width: 100%;
  max-width: 440px;
  margin: 0 auto;
}

.login-pf-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 36px;
  width: 100%;
  /* Caps the centered column — comfortably seats the preview block (max 780)
     and the auth card, both centered within. Widened by the split-layout
     media query below when the preview copy moves beside the card. */
  max-width: 904px;
  /* Auto block margins center the page vertically when the viewport is
     taller than the content, and collapse to 0 (normal top-anchored flow +
     scroll) when it isn't — safe centering for tall pages like register. */
  margin-block: auto;
}

.login-pf-page.card-pf-wide {
  /* Wider cap to seat the two-column register card (900). */
  max-width: 1460px;
}

/* ── Auth Column ─────────────────────────────────────────── */
/* Groups the auth card and the Campbell Scientific footer logo so they move
   as one unit: stacked under the preview copy on narrow viewports, the right
   column of the split layout on wide ones. The 36px gap preserves the
   card→logo spacing the page-level gap used to provide. */
.syntrix-auth-column {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 36px;
  width: 100%;
}

/* ── Auth Card Layout Row ────────────────────────────────── */
/* Wraps the auth card (and the wide register card) and centers it. The
   CampbellON preview block no longer sits in this row — it renders as a
   standalone centered block above the auth card (STX-267) — so this is now a
   single-card row. */
.syntrix-auth-layout {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: center;
  gap: 24px;
  width: 100%;
}

.syntrix-auth-layout > .card-pf {
  flex: 0 1 360px;
}

.syntrix-auth-layout > .card-pf.card-pf-wide {
  flex: 0 1 900px;
}

/* Narrow viewports: let the auth card take a comfortable width (the wide
   register card is excluded so its form isn't squeezed). flex-shrink still
   lets it narrow below 420 on small phones. */
@media (max-width: 951px) {
  .syntrix-auth-layout > .card-pf:not(.card-pf-wide) {
    flex-basis: 420px;
    max-width: 420px;
  }
}

#kc-form-wrapper,
.card-pf {
  background: var(--mat-sys-surface-container-lowest);
  border: 1px solid var(--mat-sys-outline-variant);
  border-radius: 8px;
  padding: 0;
  width: 100%;
  max-width: 440px;
  display: flex;
  flex-direction: column;
  align-items: center;
  overflow: hidden;
}

#kc-form-wrapper.card-pf-wide,
.card-pf.card-pf-wide {
  max-width: 900px;
  padding: 0;
}

/* ── CampbellON Preview Panel ────────────────────────────── */
/* An editorial preview block rendered as page copy (no card), placed above the
   auth card. ONE brand accent — a soft-yellow PREVIEW chip inline with the
   headline; all body text stays in accessible tokens. Hierarchy: headline +
   PREVIEW chip -> lede -> a neutral status note (maintenance icon + the
   "rough edges" caution + feedback ask). A one-time staggered reveal adds
   finesse on load. Theme-aware via tokens.css; restraint, spacing and type do
   the work. STX-267. */

.syntrix-preview-card {
  width: 100%;
  /* Cardless: renders as page copy above the auth card, centered by
     .login-pf-page. Wide enough for the lede to sit on one line on large
     screens; it wraps naturally as the viewport narrows. STX-267. */
  max-width: 780px;
  /* Small top inset; the block sits first in the page column. */
  margin-top: 16px;
}

.syntrix-preview-body {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* Centered welcome block — each line is a single line at this width, so
     centering reads clean (no ragged paragraphs). STX-267. */
  text-align: center;
}

/* Headline + inline PREVIEW badge on one row; flex-wrap drops the badge below
   the headline if the line gets tight on a narrow screen. */
.syntrix-preview-headingrow {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
}

/* Preview badge — matches the in-app info-chip (.lib-info-chip) box: 24px tall,
   corner-small (4px) radius, 12px/500. Keeps the soft-yellow primary-container
   tone (the same pairing as the Continue button) and UPPERCASE label, sitting
   inline after the headline. */
.syntrix-preview-eyebrow {
  display: inline-flex;
  align-items: center;
  height: 24px;
  margin: 0;
  padding: 0 8px;
  border-radius: 4px;
  background: var(--mat-sys-primary-container);
  color: var(--mat-sys-on-primary-container);
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0;
  text-transform: uppercase;
  white-space: nowrap;
}

.syntrix-preview-title {
  margin: 0;
  font-family: "DM Sans", sans-serif;
  font-size: 22px;
  font-weight: 600;
  line-height: 28px;
  letter-spacing: 0;
  color: var(--mat-sys-on-surface);
}

.syntrix-preview-lede {
  margin: 0;
  font-size: 14px;
  font-weight: 400;
  line-height: 21px;
  letter-spacing: 0.15px;
  color: var(--mat-sys-on-surface-variant);
}

/* Status note — the "rough edges" caution + feedback ask in a subtle neutral
   callout, kept neutral (not the brand yellow) so it doesn't compete with the
   PREVIEW chip. A small maintenance icon leads line 1; the feedback ask sits
   beneath on line 2. align-self keeps the box hugging its content, centered. */
.syntrix-preview-note {
  align-self: center;
  max-width: 100%;
  margin: 6px 0 0;
  padding: 14px 20px;
  border: 1px solid var(--mat-sys-outline-variant);
  border-radius: 10px;
  background: var(--mat-sys-surface-container-low);
  font-size: 13px;
  line-height: 20px;
  letter-spacing: 0.15px;
  color: var(--mat-sys-on-surface-variant);
}

.syntrix-preview-note-primary {
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.syntrix-preview-note-secondary {
  margin: 2px 0 0;
}

.syntrix-preview-note-icon {
  font-size: 16px;
  line-height: 1;
  flex-shrink: 0;
}

/* One-time staggered reveal on load — subtle finesse only, disabled below for
   users who prefer reduced motion. */
@keyframes syntrix-preview-rise {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.syntrix-preview-body > * {
  animation: syntrix-preview-rise 0.45s ease both;
}

.syntrix-preview-body > *:nth-child(1) {
  animation-delay: 0.05s;
}
.syntrix-preview-body > *:nth-child(2) {
  animation-delay: 0.12s;
}
.syntrix-preview-body > *:nth-child(3) {
  animation-delay: 0.19s;
}

@media (prefers-reduced-motion: reduce) {
  .syntrix-preview-body > * {
    animation: none;
  }
}

/* ── Logo Header ─────────────────────────────────────────── */

.syntrix-logo-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 24px;
  width: 100%;
  border-bottom: 1px solid var(--mat-sys-outline-variant);
}

/* Tone the CampbellON lockup back from 100% in dark mode so the pure
   saturated brand yellow doesn't glow brighter than the softened dark
   palette. 80% opacity matches the button + surrounding surface without
   re-encoding the asset. */
:root[data-effective-theme="dark"] .syntrix-logo--dark {
  opacity: 0.8;
}

.syntrix-logo-header .syntrix-logo {
  max-width: 200px;
  width: 100%;
  height: auto;
  display: block;
}

/* Theme-driven lockup swap. Both variants ship as separate SVG files
   (light has a dark #4d4d4d wordmark, dark has a white wordmark). The
   data-effective-theme attribute on <html> picks which one renders; the
   other collapses out via display. */
.syntrix-logo-header .syntrix-logo--dark {
  display: none;
}

:root[data-effective-theme="dark"] .syntrix-logo-header .syntrix-logo--light {
  display: none;
}

:root[data-effective-theme="dark"] .syntrix-logo-header .syntrix-logo--dark {
  display: block;
}

/* ── Card Body ───────────────────────────────────────────── */

.syntrix-card-body {
  width: 100%;
  padding: 24px 32px 32px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* ── Headings & Section Title ────────────────────────────── */

h1,
.syntrix-h1 {
  font-family: "DM Sans", sans-serif;
  font-size: 16px;
  font-weight: 500;
  line-height: 24px;
  letter-spacing: 0.1px;
  color: var(--mat-sys-on-surface);
  margin: 0 0 8px;
  text-align: left;
  width: 100%;
}

.syntrix-section-title {
  font-size: 14px;
  font-weight: 500;
  line-height: 20px;
  letter-spacing: 0.1px;
  color: var(--mat-sys-on-surface);
  margin-bottom: 4px;
}

.syntrix-section-desc {
  font-size: 13px;
  font-weight: 400;
  line-height: 20px;
  letter-spacing: 0.25px;
  color: var(--mat-sys-on-surface-variant);
  margin: 0 0 8px;
}

.syntrix-page-expired-line {
  margin-bottom: 16px;
}

/* ── Form ────────────────────────────────────────────────── */

.syntrix-form {
  width: 100%;
  max-width: 500px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding-top: 8px;
}

.syntrix-form-group {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.syntrix-form-group label {
  display: block;
  font-size: 13px;
  font-weight: 500;
  line-height: 16px;
  letter-spacing: 0.4px;
  color: var(--mat-sys-on-surface-variant);
}

.syntrix-form-group label.required::after {
  content: " *";
  color: var(--mat-sys-error);
}

.syntrix-form-group input[type="text"],
.syntrix-form-group input[type="email"],
.syntrix-form-group input[type="password"],
.syntrix-form-group input[type="tel"],
.syntrix-form-group input[type="number"],
.syntrix-form-group select {
  width: 100%;
  height: 36px;
  padding: 0 12px;
  font-family: "DM Sans", sans-serif;
  font-size: 13px;
  font-weight: 400;
  line-height: 20px;
  letter-spacing: 0.25px;
  color: var(--mat-sys-on-surface);
  background: var(--mat-sys-surface-container-lowest);
  border: 1px solid var(--mat-sys-outline);
  border-radius: 4px;
  outline: none;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}

.syntrix-form-group input::placeholder {
  color: var(--mat-sys-on-surface-variant);
  opacity: 1;
}

.syntrix-form-group input:focus,
.syntrix-form-group input:focus-visible,
.syntrix-form-group select:focus,
.syntrix-form-group select:focus-visible {
  border-color: var(--mat-sys-on-surface);
  border-width: 2px;
  padding: 0 11px;
}

.syntrix-form-group input[aria-invalid="true"],
.syntrix-form-group input.has-error,
.syntrix-form-group select[aria-invalid="true"],
.syntrix-form-group select.has-error {
  border-color: var(--mat-sys-error);
}

.syntrix-form-group input[aria-invalid="true"]:focus,
.syntrix-form-group input.has-error:focus {
  border-color: var(--mat-sys-error);
}

/* Catch un-classed inputs from Keycloak default templates (login-otp,
   login-update-password, etc.) so they pick up the same shell visually. */
input[type="text"].pf-c-form-control,
input[type="email"].pf-c-form-control,
input[type="password"].pf-c-form-control {
  width: 100%;
  height: 36px;
  padding: 0 12px;
  font-family: "DM Sans", sans-serif;
  font-size: 13px;
  color: var(--mat-sys-on-surface);
  background: var(--mat-sys-surface-container-lowest);
  border: 1px solid var(--mat-sys-outline);
  border-radius: 4px;
}

/* ── Password show/hide toggle ───────────────────────────── */

.syntrix-password-wrapper {
  position: relative;
  display: flex;
}

.syntrix-password-wrapper input {
  width: 100%;
  padding-right: 40px;
}

.syntrix-password-toggle {
  position: absolute;
  top: 50%;
  right: 4px;
  transform: translateY(-50%);
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: var(--mat-sys-on-surface-variant);
  cursor: pointer;
  border-radius: 4px;
  padding: 0;
}

.syntrix-password-toggle:hover {
  background: var(--mat-sys-surface-container);
  color: var(--mat-sys-on-surface);
}

.syntrix-password-toggle:focus-visible {
  outline: 2px solid var(--mat-sys-on-surface);
  outline-offset: 2px;
}

.syntrix-password-toggle .material-symbols-outlined {
  font-size: 20px;
  line-height: 1;
}

/* ── Password requirements helper ────────────────────────── */

.syntrix-password-requirements {
  width: 100%;
  margin-top: 4px;
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.4px;
  color: var(--mat-sys-on-surface-variant);
}

.syntrix-password-requirements__title {
  font-weight: 500;
  margin-bottom: 2px;
}

.syntrix-password-requirements__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.syntrix-password-requirements__item {
  color: var(--mat-sys-on-surface-variant);
  transition: color 0.15s ease;
}

.syntrix-password-requirements__item--invalid {
  color: var(--mat-sys-on-error-container);
}

/* ── Inline field error ──────────────────────────────────── */

.syntrix-form-field-error {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.4px;
  color: var(--mat-sys-on-error-container);
  margin-top: 4px;
}

.syntrix-form-field-error .material-symbols-outlined {
  font-size: 14px;
  line-height: 1;
  flex-shrink: 0;
  color: var(--mat-sys-on-error-container);
}

/* Single credential error rendered once above the email field (login.ftl),
   styled as the app UI's error-message chip: filled error-container
   background, circular icon, rounded corners. */
.syntrix-login-error {
  gap: 8px;
  margin-top: 0;
  margin-bottom: 16px;
  padding: 12px 16px;
  border-radius: 8px;
  background: var(--mat-sys-error-container);
  font-size: 14px;
  line-height: 20px;
}

.syntrix-login-error .material-symbols-outlined {
  font-size: 20px;
}

/* ── Registration Header ─────────────────────────────────── */

.syntrix-reg-header {
  width: 100%;
  text-align: left;
}

/* ── Alerts ──────────────────────────────────────────────── */

.syntrix-alert {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 13px;
  font-weight: 400;
  line-height: 20px;
  letter-spacing: 0.25px;
  padding: 12px 16px;
  margin-bottom: 16px;
  border-radius: 4px;
  width: 100%;
}

.syntrix-alert-icon {
  font-size: 24px;
  flex-shrink: 0;
  line-height: 1;
}

.syntrix-alert a {
  color: inherit;
  text-decoration: underline;
}

.syntrix-alert-error {
  background: var(--mat-sys-error-container);
  color: var(--mat-sys-on-error-container);
}

.syntrix-alert-warning {
  background: var(--mat-sys-warning-container);
  color: var(--mat-sys-on-warning-container);
}

.syntrix-alert-success {
  background: var(--mat-sys-success-container);
  color: var(--mat-sys-on-success-container);
}

.syntrix-alert-info {
  background: var(--mat-sys-info-container);
  color: var(--mat-sys-on-info-container);
}

/* ── Buttons ─────────────────────────────────────────────── */

.syntrix-footer {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding-top: 20px;
}

.syntrix-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: 160px;
  height: 32px;
  padding: 0 24px;
  border-radius: 9999px;
  font-family: "DM Sans", sans-serif;
  font-size: 13px;
  font-weight: 500;
  line-height: 20px;
  letter-spacing: 0.1px;
  text-transform: none;
  cursor: pointer;
  border: none;
  text-decoration: none;
  transition:
    background-color 0.15s ease,
    box-shadow 0.15s ease,
    opacity 0.15s ease;
  position: relative;
}

.syntrix-btn:focus-visible {
  outline: 2px solid var(--mat-sys-on-surface);
  outline-offset: 2px;
}

.syntrix-btn:hover {
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}

.syntrix-btn:disabled,
.syntrix-btn[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.65;
  box-shadow: none;
}

.syntrix-btn-primary {
  background: var(--mat-sys-primary-container);
  color: var(--mat-sys-on-primary-container);
}

.syntrix-btn-tonal {
  background: var(--mat-sys-secondary-container);
  color: var(--mat-sys-on-secondary-container);
}

.syntrix-btn-outlined,
.syntrix-btn-outline {
  background: transparent;
  color: var(--mat-sys-on-surface-variant);
  border: 1px solid var(--mat-sys-outline-variant);
}

.syntrix-btn-text {
  background: transparent;
  color: var(--mat-sys-on-surface-variant);
  text-decoration: none;
  padding: 0 16px;
  min-width: 0;
}

.syntrix-btn-text:hover {
  background: var(--mat-sys-surface-container);
  box-shadow: none;
  text-decoration: none;
}

.syntrix-btn-text .btn-text-label {
  text-decoration: none;
}

/* Submit-button loading spinner (pure CSS).
   Activate by adding `aria-busy="true"` on the disabled button. */
.syntrix-btn[aria-busy="true"]:disabled::after {
  content: "";
  width: 14px;
  height: 14px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: syntrix-spin 0.6s linear infinite;
}

@keyframes syntrix-spin {
  to {
    transform: rotate(360deg);
  }
}

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

.syntrix-link {
  display: inline-block;
  padding: 2px 0;
  font-size: 13px;
  font-weight: 400;
  line-height: 20px;
  letter-spacing: 0.25px;
  color: var(--mat-sys-on-surface);
  text-decoration: underline;
}

.syntrix-text-secondary {
  font-size: 13px;
  font-weight: 400;
  line-height: 20px;
  letter-spacing: 0.25px;
  color: var(--mat-sys-on-surface);
  padding-top: 16px;
}

/* ── Footer Logo ─────────────────────────────────────────── */

.syntrix-footer-logo {
  opacity: 0.75;
}

.syntrix-footer-logo img {
  width: 150px;
  height: auto;
}

/* ── Registration Two-Column ─────────────────────────────── */

.syntrix-reg-columns {
  display: flex;
  gap: 64px;
  width: 100%;
}

.syntrix-reg-column {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.syntrix-reg-column-header {
  font-size: 14px;
  font-weight: 500;
  line-height: 20px;
  letter-spacing: 0.1px;
  color: var(--mat-sys-on-surface);
  padding-top: 24px;
  margin-bottom: 8px;
}

/* ── Checkboxes (Terms) ──────────────────────────────────── */

.syntrix-checkbox {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  margin-top: 8px;
}

.syntrix-checkbox__hit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  margin: -7px -4px 0 -4px;
  flex-shrink: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.syntrix-checkbox__hit:hover {
  background: var(--mat-sys-surface-container);
}

.syntrix-checkbox input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  margin: 0;
  background: transparent;
  border: 2px solid var(--mat-sys-on-surface-variant);
  border-radius: 2px;
  cursor: pointer;
  transition:
    background-color 0.15s ease,
    border-color 0.15s ease;
}

.syntrix-checkbox input[type="checkbox"]:hover,
.syntrix-checkbox__hit:hover input[type="checkbox"] {
  border-color: var(--mat-sys-on-surface);
}

.syntrix-checkbox input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--mat-sys-on-surface);
  outline-offset: 2px;
}

.syntrix-checkbox input[type="checkbox"]:checked {
  background-color: var(--mat-sys-primary);
  border-color: var(--mat-sys-primary);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'><path fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round' d='M4 9.2 L7.6 12.8 L14 6'/></svg>");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 18px 18px;
}

/* Dark mode: --mat-sys-primary is a soft light yellow, so the white
   checkmark loses contrast. Swap to a dark stroke matching
   --mat-sys-on-primary (rgb(29, 29, 29)) to mirror the in-app
   Material checkbox's on-primary checkmark color.

   Gated on the data-effective-theme attribute (NOT @media
   prefers-color-scheme) so the checkmark follows the SAME signal as the fill
   color (--mat-sys-primary, also attribute-gated in tokens.css). Using @media
   here let the checkmark follow the OS while the fill followed the page theme,
   producing a dark checkmark on a light-mode dark-gray fill when the OS was
   dark but the page rendered light — an invisible check. */
:root[data-effective-theme="dark"] .syntrix-checkbox input[type="checkbox"]:checked {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'><path fill='none' stroke='rgb(29,29,29)' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round' d='M4 9.2 L7.6 12.8 L14 6'/></svg>");
}

.syntrix-checkbox input[type="checkbox"]:disabled {
  border-color: var(--mat-sys-outline-variant);
  background-color: transparent;
  cursor: not-allowed;
  opacity: 0.6;
}

/* Invalid state — red border to match the text-input error treatment.
   Hover override below ensures the red doesn't get overwritten by the
   on-surface hover color while the field is still invalid. */
.syntrix-checkbox input[type="checkbox"][aria-invalid="true"] {
  border-color: var(--mat-sys-error);
}

.syntrix-checkbox input[type="checkbox"][aria-invalid="true"]:hover,
.syntrix-checkbox__hit:hover input[type="checkbox"][aria-invalid="true"] {
  border-color: var(--mat-sys-error);
}

/* Wrapper for a checkbox + its inline error message, mirroring the
   structure of .syntrix-form-group for text inputs. The inline error
   sits below the checkbox row at the same 4px gap the form-field-error
   uses elsewhere. */
.syntrix-checkbox-group {
  display: flex;
  flex-direction: column;
  margin-top: 8px;
}

.syntrix-checkbox-group .syntrix-checkbox {
  margin-top: 0;
}

.syntrix-checkbox-group .syntrix-form-field-error {
  /* Indent under the checkbox text, not under the checkbox itself, so
     it reads as "this rule applies to that label." Checkbox is 18px +
     8px gap = 26px from the row start. */
  padding-left: 26px;
}

.syntrix-checkbox__text {
  font-size: 13px;
  font-weight: 400;
  line-height: 20px;
  letter-spacing: 0.25px;
  color: var(--mat-sys-on-surface-variant);
  cursor: pointer;
}

/* ── Footer Buttons Row ──────────────────────────────────── */

.syntrix-footer-buttons {
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: flex-end;
  background: var(--mat-sys-surface-container-low);
  border-top: 1px solid var(--mat-sys-outline-variant);
  padding: 16px 32px;
  margin: 32px -32px -32px;
}

/* ── Note ────────────────────────────────────────────────── */

.syntrix-note {
  font-size: 13px;
  font-style: italic;
  font-weight: 400;
  line-height: 20px;
  letter-spacing: 0.25px;
  color: var(--mat-sys-on-surface-variant);
  max-width: 500px;
  padding-top: 24px;
}

/* ── Pre-registration sections ───────────────────────────── */

.syntrix-prescreen-section {
  width: 100%;
  max-width: 500px;
  margin: 0 auto;
}

/* ── On-screen dialog (Info / Error / Empty state) ───────── */
/* Mirrors libs/ui/ui-dialogs/.../on-screen-dialog.scss visually. */

.syntrix-on-screen-dialog {
  width: 100%;
  max-width: 400px;
  margin: 0 auto;
  padding: 32px 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 8px;
  color: var(--mat-sys-on-surface-variant);
}

.syntrix-on-screen-dialog__icon {
  font-size: 48px;
  line-height: 1;
  width: 48px;
  height: 48px;
  color: var(--mat-sys-on-surface-variant);
}

.syntrix-on-screen-dialog__title {
  font-family: 'DM Sans', sans-serif;
  font-weight: 500;
  font-size: 20px;
  line-height: 1.3;
  letter-spacing: 0;
  color: var(--mat-sys-on-surface);
  margin: 0;
  width: auto;
  text-align: center;
}

.syntrix-on-screen-dialog__description {
  font-weight: 400;
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: 0.25px;
  color: var(--mat-sys-on-surface-variant);
  margin: 0 0 16px;
}

.syntrix-on-screen-dialog__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  margin-top: 16px;
}

.syntrix-on-screen-dialog--left {
  align-items: flex-start;
  text-align: left;
  max-width: none;
}

.syntrix-on-screen-dialog--left .syntrix-on-screen-dialog__actions {
  justify-content: flex-start;
}

.syntrix-back-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  font-weight: 400;
  line-height: 20px;
  letter-spacing: 0.25px;
  color: var(--mat-sys-on-surface-variant);
  text-decoration: none;
}

.syntrix-back-link:hover {
  color: var(--mat-sys-on-surface);
}

.syntrix-back-link .material-symbols-outlined {
  font-size: 20px;
}

/* ── OTP / Terms shared chrome ───────────────────────────── */

.syntrix-otp-input {
  text-align: center;
  letter-spacing: 6px !important;
  font-variant-numeric: tabular-nums;
}

.syntrix-terms-block {
  width: 100%;
  max-height: 240px;
  overflow-y: auto;
  padding: 12px 16px;
  border: 1px solid var(--mat-sys-outline-variant);
  border-radius: 4px;
  background: var(--mat-sys-surface-container-lowest);
  font-size: 13px;
  line-height: 20px;
  color: var(--mat-sys-on-surface);
  margin-top: 8px;
}

.syntrix-terms-block::-webkit-scrollbar {
  width: 8px;
}
.syntrix-terms-block::-webkit-scrollbar-track {
  background: var(--mat-sys-surface-container);
}
.syntrix-terms-block::-webkit-scrollbar-thumb {
  background: var(--mat-sys-outline-variant);
  border-radius: 4px;
}
.syntrix-terms-block {
  scrollbar-width: thin;
  scrollbar-color: var(--mat-sys-outline-variant)
    var(--mat-sys-surface-container);
}

/* ── Responsive ──────────────────────────────────────────── */

@media (max-width: 960px) {
  .syntrix-reg-columns {
    flex-direction: column;
    gap: 24px;
  }
}

@media (max-width: 599px) {
  body {
    padding: 24px 12px;
  }

  #kc-form-wrapper,
  .card-pf {
    padding: 0;
  }

  .syntrix-logo-header {
    padding: 16px;
  }

  .syntrix-card-body {
    padding: 16px 16px 24px;
  }

  .syntrix-preview-body {
    padding: 20px 16px 24px;
  }

  .syntrix-footer-buttons {
    justify-content: center;
    flex-direction: column-reverse;
    padding: 16px;
    margin: 24px -16px -24px;
  }

  .syntrix-footer-buttons .syntrix-btn {
    width: 100%;
  }
}

/* ── Split layout (wide viewports) ───────────────────────── */
/* Side-by-side hero layout: the CampbellON preview copy becomes a
   left-aligned editorial column and the auth column (card + Campbell
   Scientific logo) sits to its right, both vertically centered against
   each other. Pages without the preview (register, error) keep a single
   centered column — with one flex child, row direction renders the same
   as the stacked layout. Below this breakpoint everything falls back to
   the centered stack. */
@media (min-width: 1100px) {
  .login-pf-page {
    flex-direction: row;
    align-items: center;
    justify-content: center;
    gap: clamp(56px, 7vw, 112px);
    max-width: 1200px;
  }

  /* Left column: cap the copy at a comfortable reading measure. */
  .syntrix-preview-card {
    flex: 0 1 480px;
    margin-top: 0;
  }

  /* Right column: fixed-basis so the card renders at its full width.
     Scoped away from the wide register page (bodyClass card-pf-wide lands
     on .login-pf-page too) — its 900px card needs the fluid column. */
  .login-pf-page:not(.card-pf-wide) .syntrix-auth-column {
    flex: 0 0 440px;
    width: 440px;
  }

  .syntrix-auth-layout > .card-pf:not(.card-pf-wide) {
    flex: 1 1 auto;
  }

  /* The preview copy reads as a hero: left-aligned, with a larger
     headline to anchor the column. Centering only made sense when each
     line sat alone in the middle of the page. */
  .syntrix-preview-body {
    text-align: left;
    gap: 12px;
  }

  .syntrix-preview-headingrow {
    justify-content: flex-start;
  }

  .syntrix-preview-title {
    font-size: 32px;
    line-height: 40px;
  }

  .syntrix-preview-lede {
    font-size: 16px;
    line-height: 24px;
  }

  .syntrix-preview-note {
    align-self: flex-start;
    margin-top: 10px;
  }

  .syntrix-preview-note-primary {
    justify-content: flex-start;
  }
}

/* -----------------------------------------------------------------------
   SSO email-first flow (login-username.ftl, login-password.ftl)
   -----------------------------------------------------------------------
   Added for the design spec's email-first login experience
   (docs/superpowers/specs/2026-05-11-org-sso-design.md §6).
   These additions are scoped to the new screens; the legacy combined
   login.ftl is untouched.
*/

/* Trailing-icon variant of syntrix-btn-primary (used on the Continue button). */
.syntrix-btn .syntrix-btn-icon {
    font-size: 1.1em;
    margin-left: 6px;
    vertical-align: middle;
}

/* Secondary action line under the primary submit ("Don't have an account? Create one"). */
.syntrix-secondary-action {
    margin: 16px 0 0;
    text-align: center;
    font-size: 0.9rem;
}

.syntrix-secondary-action .syntrix-link {
    margin-left: 4px;
}

/* Inline-with-label link (e.g. Forgot password? sits beside the password label). */
.syntrix-form-group__label-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.syntrix-link--inline {
    font-size: 13px;
}

/* User pill — shown on the password step to remind the user which email
   they entered, with a Change link that restarts the auth flow. */
.syntrix-user-pill {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    box-sizing: border-box;
    padding: 8px 12px;
    background: var(--syntrix-surface-muted, #f5f5f5);
    border-radius: 8px;
    margin-top: 16px;
    margin-bottom: 20px;
    font-size: 0.9rem;
}

.syntrix-user-pill__avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--syntrix-surface, #ffffff);
    color: var(--syntrix-text-secondary, #6b6b6b);
    font-weight: 500;
    flex-shrink: 0;
}

.syntrix-user-pill__email {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--syntrix-text-primary, #2b2b2b);
}

.syntrix-user-pill__change {
    gap: 4px;
    text-transform: capitalize;
    letter-spacing: normal;
}

.syntrix-user-pill__change:hover,
.syntrix-user-pill__change:focus-visible {
    color: var(--syntrix-text-primary, #2b2b2b);
    text-decoration: none;
}

.syntrix-user-pill__change .material-symbols-outlined {
    font-size: 1rem;
}

/* -----------------------------------------------------------------------
   SSO IdP-redirect intermediate screen (login-idp-redirect-confirm.ftl)
   -----------------------------------------------------------------------
   Per the design spec's sso4/sso5/sso6 mocks. The IdP card sits below
   the user pill (sso-shared) and above the "Continue with [IdP]" button.
*/

.syntrix-idp-card {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 14px;
    background: var(--syntrix-surface-muted, #f5f5f5);
    border-radius: 8px;
    margin-bottom: 20px;
}

.syntrix-idp-card__logo {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: #ffffff;
    border-radius: 6px;
    overflow: hidden;
}

.syntrix-idp-card__logo img {
    width: 32px;
    height: 32px;
    display: block;
}

.syntrix-idp-card__body {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.syntrix-idp-card__label {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--syntrix-text-secondary, #6b6b6b);
}

.syntrix-idp-card__name {
    font-size: 1rem;
    font-weight: 500;
    color: var(--syntrix-text-primary, #2b2b2b);
}

.syntrix-idp-card__check {
    flex-shrink: 0;
    color: var(--syntrix-success, #2e7d32);
    background: rgba(46, 125, 50, 0.12);
    padding: 4px;
    border-radius: 50%;
    font-size: 1.1rem !important;
}

.syntrix-sso-auth-host {
    margin: 12px 0 0;
    text-align: center;
    font-size: 0.85rem;
    color: var(--syntrix-text-secondary, #6b6b6b);
}

.syntrix-sso-auth-host code {
    background: var(--syntrix-surface-muted, #f5f5f5);
    padding: 2px 6px;
    border-radius: 3px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.85rem;
}

/* -----------------------------------------------------------------------
   Dark-mode footer logo handling.
   -----------------------------------------------------------------------
   campbell-scientific-logo.svg uses a hard-coded #4D4D4D (dark gray) for
   its shield + wordmark. Without intervention the wordmark is invisible
   on the dark card. Applying `invert(1) hue-rotate(180deg)` flips
   lightness on grayscale fills (4D4D4D → B2B2B2, readable on dark) while
   leaving any saturated hues effectively unchanged after hue rotation
   cancels out the inversion.

   The header logo doesn't need this hack — it ships a dedicated
   dark-mode SVG variant (see .syntrix-logo--dark above). */
:root[data-effective-theme="dark"] .syntrix-footer-logo img {
    filter: invert(1) hue-rotate(180deg);
}

/* The IdP-redirect logo container is intentionally white in light mode
   because most third-party IdP brand SVGs are drawn for a light backdrop.
   Keep that backdrop white in dark mode too — flipping the IdP card to a
   dark backdrop would clash with the IdP's own brand colors. */
:root[data-effective-theme="dark"] .syntrix-idp-card__logo {
    background: #ffffff;
}

/* -----------------------------------------------------------------------
   Animated mesh-gradient background.
   -----------------------------------------------------------------------
   Two large blurred radial-gradient blobs drift behind the card, painted
   on body::before and body::after positioned fixed at the viewport. The
   yellow blob is brand-aligned; the cool blob picks up info-container
   tones to add depth without competing for attention. The drift uses a
   long-period transform animation (no layout cost — GPU-composited via
   transform/opacity only). Tones differ per theme so the gradient never
   washes out the card on either background. Respects
   prefers-reduced-motion (animation paused, blobs static). */
body {
    position: relative;
    isolation: isolate;
    overflow-x: hidden;
}

body::before,
body::after {
    content: "";
    position: fixed;
    z-index: -1;
    pointer-events: none;
    border-radius: 50%;
    filter: blur(80px);
    will-change: transform;
    transform: translate3d(0, 0, 0);
}

body::before {
    top: -20vmin;
    left: -15vmin;
    width: 70vmin;
    height: 70vmin;
    background: radial-gradient(closest-side, rgba(248, 193, 21, 0.32), rgba(248, 193, 21, 0));
    animation: syntrix-bg-drift-a 28s ease-in-out infinite alternate;
}

body::after {
    bottom: -25vmin;
    right: -20vmin;
    width: 80vmin;
    height: 80vmin;
    background: radial-gradient(closest-side, rgba(90, 104, 166, 0.28), rgba(90, 104, 166, 0));
    animation: syntrix-bg-drift-b 36s ease-in-out infinite alternate;
}

:root[data-effective-theme="dark"] body::before {
    background: radial-gradient(closest-side, rgba(252, 229, 136, 0.18), rgba(252, 229, 136, 0));
}

:root[data-effective-theme="dark"] body::after {
    background: radial-gradient(closest-side, rgba(150, 175, 240, 0.16), rgba(150, 175, 240, 0));
}

@keyframes syntrix-bg-drift-a {
    0% { transform: translate3d(0, 0, 0) scale(1); }
    100% { transform: translate3d(12vmin, 8vmin, 0) scale(1.15); }
}

@keyframes syntrix-bg-drift-b {
    0% { transform: translate3d(0, 0, 0) scale(1); }
    100% { transform: translate3d(-10vmin, -6vmin, 0) scale(1.1); }
}

@media (prefers-reduced-motion: reduce) {
    body::before,
    body::after {
        animation: none;
    }
}

/* -----------------------------------------------------------------------
   Theme toggle (bottom-right, three-state).
   -----------------------------------------------------------------------
   Cycles Auto → Light → Dark → Auto. The active icon swaps via the
   data-mode attribute set by the toggle script in template.ftl. Visually
   discreet: small circular surface chip, no border in idle, subtle outline
   on hover/focus. Fixed bottom-right, out of the auth flow's tab order
   priority but always reachable. */
.syntrix-theme-toggle {
    position: fixed;
    bottom: 16px;
    right: 16px;
    z-index: 10;
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--mat-sys-outline-variant);
    border-radius: 50%;
    background: var(--mat-sys-surface-container-lowest);
    color: var(--mat-sys-on-surface-variant);
    cursor: pointer;
    padding: 0;
    transition:
        background-color 0.15s ease,
        color 0.15s ease,
        border-color 0.15s ease,
        transform 0.15s ease;
}

.syntrix-theme-toggle:hover {
    color: var(--mat-sys-on-surface);
    border-color: var(--mat-sys-on-surface);
    transform: translateY(-1px);
}

.syntrix-theme-toggle:focus-visible {
    outline: 2px solid var(--mat-sys-on-surface);
    outline-offset: 2px;
}

.syntrix-theme-toggle .material-symbols-outlined {
    font-size: 20px;
}

/* Icon swap — show only the icon that matches the current mode. The
   button has three nested icon spans and the data-mode attribute selects
   which to display. */
.syntrix-theme-toggle__icon {
    display: none;
}

.syntrix-theme-toggle[data-mode="auto"] .syntrix-theme-toggle__icon--auto,
.syntrix-theme-toggle[data-mode="light"] .syntrix-theme-toggle__icon--light,
.syntrix-theme-toggle[data-mode="dark"] .syntrix-theme-toggle__icon--dark {
    display: inline-block;
}

/* ── TOTP Enrollment (login-config-totp.ftl) ─────────────── */
/* Numbered setup steps (kc-totp-settings): QR/manual-secret step, the
   nested supported-apps / policy-detail lists, and the device-label
   step. Kept generic (bare <ol>/<ul> under .syntrix-totp-steps) so no
   extra classes are needed per stock <ul> the server renders. */

.syntrix-totp-steps {
  width: 100%;
  max-width: 500px;
  margin: 0 0 8px;
  padding-left: 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  font-size: 13px;
  line-height: 20px;
  letter-spacing: 0.25px;
  color: var(--mat-sys-on-surface);
}

.syntrix-totp-steps > li {
  padding-left: 4px;
}

.syntrix-totp-steps p {
  margin: 0 0 4px;
}

.syntrix-totp-steps ul {
  margin: 4px 0 0;
  padding-left: 20px;
  color: var(--mat-sys-on-surface-variant);
}

/* Manual-entry secret key (kc-totp-secret-key). Monospace + a bordered
   chip so the character sequence is easy to scan/copy. */
.syntrix-totp-secret {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 4px;
  background: var(--mat-sys-surface-container-low);
  border: 1px solid var(--mat-sys-outline-variant);
  font-family:
    ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  letter-spacing: 0.5px;
  word-break: break-all;
}

/* QR barcode (kc-totp-secret-qr-code). Fixed white backdrop regardless
   of theme — like .syntrix-idp-card__logo, a scannable QR code needs a
   light background behind its dark modules independent of dark mode. */
.syntrix-totp-qr {
  display: block;
  width: 176px;
  height: 176px;
  margin: 8px 0;
  padding: 8px;
  background: #ffffff;
  border: 1px solid var(--mat-sys-outline-variant);
  border-radius: 8px;
}

/* SSO identity-provider buttons (login.ftl). Rendered below the login form
   when identity providers are configured; hidden otherwise. */
.syntrix-social {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 24px;
}

.syntrix-social-divider {
    display: flex;
    align-items: center;
    gap: 12px;
    color: var(--mat-sys-on-surface-variant);
    font-size: 0.875rem;
}

.syntrix-social-divider::before,
.syntrix-social-divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--mat-sys-outline-variant);
}

.syntrix-social-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.syntrix-social-button {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
}

/* Support-help line under an auth form (supportHelp macro in template.ftl).
   Colour + metrics mirror .syntrix-section-desc so it reads as secondary
   copy rather than a second call to action. */
.syntrix-form-help {
  font-size: 13px;
  font-weight: 400;
  line-height: 20px;
  letter-spacing: 0.25px;
  color: var(--mat-sys-on-surface-variant);
  text-align: center;
  margin: 16px 0 0;
}

/* Forced-MFA-enrollment explainer (login-config-totp.ftl). Hidden by
   default; revealed via inline script when JS is available so JS-off
   users see the plain working setup form (progressive enhancement). */
.syntrix-mfa-explainer {
    display: none;
}

.syntrix-mfa-explainer__title {
    margin: 0 0 12px;
    font-size: 1.0625rem;
    font-weight: 600;
}

.syntrix-mfa-explainer__list {
    margin: 12px 0 20px;
    padding-left: 20px;
    line-height: 1.6;
}

/* Option list on webauthn-register.ftl — what the browser dialog may offer.
   Mirrors .syntrix-mfa-explainer__list so the two setup pages read alike. */
.syntrix-webauthn-options {
    margin: 0 0 4px;
    padding-left: 20px;
    font-size: 13px;
    line-height: 1.6;
    color: var(--mat-sys-on-surface-variant);
}

/* ── WebAuthn (webauthn-authenticate.ftl) ────────────────── */
/* Available-passkey list shown when Keycloak has more than one
   credential to disambiguate. Informational only (the browser's own
   WebAuthn picker resolves the actual credential) — styled like
   .syntrix-social-list's row-of-cards, not as selectable controls. */
.syntrix-webauthn-list {
    list-style: none;
    margin: 0 0 16px;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.syntrix-webauthn-item {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 10px 12px;
    border: 1px solid var(--mat-sys-outline-variant);
    border-radius: 8px;
    background: var(--mat-sys-surface-container-low);
}

.syntrix-webauthn-item__icon {
    color: var(--mat-sys-on-surface-variant);
    margin-top: 2px;
}

.syntrix-webauthn-item__body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.syntrix-webauthn-item__label {
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--mat-sys-on-surface);
    overflow-wrap: anywhere;
}

.syntrix-webauthn-item__meta {
    font-size: 0.75rem;
    color: var(--mat-sys-on-surface-variant);
}

/* ── Factor chooser (select-authenticator.ftl) ───────────── */
/* Each row is a native <button type="submit"> living inside its own
   per-item form — styled as an affordant list item, not as
   .syntrix-webauthn-item's purely-informational rows. The reset rules
   below (width/text-align/font/color/appearance) undo the browser's
   default button chrome so it reads identically to the previous
   clickable-div styling. */
.syntrix-select-auth-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.syntrix-select-auth-item__button {
    display: flex;
    align-items: center;
    width: 100%;
    gap: 12px;
    padding: 12px 14px;
    border: 1px solid var(--mat-sys-outline-variant);
    border-radius: 8px;
    background: var(--mat-sys-surface-container-low);
    font: inherit;
    color: inherit;
    text-align: left;
    appearance: none;
    cursor: pointer;
}

.syntrix-select-auth-item__button:hover {
    background: var(--mat-sys-surface-container);
}

.syntrix-select-auth-item__button:focus-visible {
    outline: 2px solid var(--mat-sys-on-surface);
    outline-offset: 2px;
}

.syntrix-select-auth-item__icon {
    flex-shrink: 0;
    color: var(--mat-sys-on-surface-variant);
}

.syntrix-select-auth-item__body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.syntrix-select-auth-item__title {
    margin: 0;
    font-size: 0.9375rem;
    font-weight: 500;
    color: var(--mat-sys-on-surface);
}

.syntrix-select-auth-item__desc {
    font-size: 0.8125rem;
    color: var(--mat-sys-on-surface-variant);
}

.syntrix-select-auth-item__arrow {
    flex-shrink: 0;
    color: var(--mat-sys-on-surface-variant);
}

/* ── "Try another way" factor-switch link ────────────────── */
/* Shared by login-otp.ftl and webauthn-authenticate.ftl, guarded server-
   side by auth.showTryAnotherWayLink() so it only renders when a second
   factor is genuinely available. The control is a <button> (it must POST
   tryAnotherWay=on, not navigate), styled to read as .syntrix-link's
   inline text link rather than a default button. */
#kc-select-try-another-way-form {
    margin-top: 16px;
    text-align: center;
}

#kc-select-try-another-way-form .syntrix-link {
    background: none;
    border: none;
    padding: 2px 0;
    cursor: pointer;
    font-family: inherit;
}
