/* ==========================================================================
   Inline validation for the signup / login forms (auth.html).

   Palette follows the auth card itself, which runs on the plum the header,
   footer and Login button use — not the storefront yellow. Idle -> hover ->
   focus is one plum ramp; only the two verdicts introduce a second hue.

     #ab2d72                   brand plum (focus ring, Login button, chrome)
     #e83e8c                   accent pink (links, headings)
     --text          #001430   headings / input text
     --text_color    #69778a   muted copy

   Only errors get a loud colour. A passed field settles to a calm border and
   says so with a small plum tick underneath — green was the one hue on the
   card that belonged to no other part of the site.
   ========================================================================== */

.form-wrapper {
  --brand: #ab2d72;
  /* "Passed" is the brand plum, not a green. Green was borrowed from nowhere —
     the card, its button, its links and the site chrome are all plum, so a
     green tick was the only element on the page with no relatives. */
  --ok: #ab2d72;
  --ok-ink: #8f2560;
  --bad: #e5484d;
  --bad-ink: #cf3339;
  /* The border a field settles on once it has passed. */
  --settled: #cfd6dd;
}

/* Bootstrap owns `.input-group` and makes it `display:flex; flex-wrap:wrap`.
   Everything this stylesheet injects into a group therefore has to claim a
   full row, or it lines up beside the field instead of under it. */
.form-wrapper .field-msg,
.form-wrapper .pw-strength {
  flex: 0 0 100%;
  width: 100%;
}

/* The two password fields sit in a grid whose gap stacks on top of the
   .input-group bottom margin, so that pair drifted noticeably further apart
   than every other field once the messages appeared. Let the grid own it. */
.form-wrapper .password-row {
  gap: 20px;
  margin-bottom: 20px;
}

.form-wrapper .password-row .input-group {
  margin-bottom: 0;
}

/* --- Field states -------------------------------------------------------- */

/* The field being typed into had no state of its own — it fell through to
   :hover, so the active field and a merely pointed-at one looked identical.
   Plum matches `.ac-input:focus-within` on the password-reset pages. */
.form-wrapper .input-box:focus-within,
.form-wrapper .input-box:hover:focus-within {
  border-color: var(--brand);
  box-shadow: 0 0 0 4px rgba(171, 45, 114, 0.15);
}

.form-wrapper .input-box:focus-within .auth-input__left {
  color: var(--brand);
}

.form-wrapper .input-box.is-invalid,
.form-wrapper .input-box.is-invalid:hover,
.form-wrapper .input-box.is-invalid:focus-within {
  border-color: var(--bad);
  box-shadow: 0 0 0 4px rgba(229, 72, 77, 0.12);
}

/* A passed field does not need to shout — it needs to stop asking for
   attention. Border settles one shade darker than idle, ring goes away, and
   the tick underneath carries the actual verdict. An error still shouts,
   because that one the customer has to act on. */
.form-wrapper .input-box.is-valid {
  border-color: var(--settled);
  box-shadow: none;
}

/* Focus outranks "passed": the field being typed in is always the plum one. */
.form-wrapper .input-box.is-valid:hover {
  border-color: rgba(171, 45, 114, 0.45);
  box-shadow: 0 0 0 4px rgba(171, 45, 114, 0.12);
}

.form-wrapper .input-box.is-valid:focus-within {
  border-color: var(--brand);
  box-shadow: 0 0 0 4px rgba(171, 45, 114, 0.15);
}

.form-wrapper .input-box.is-invalid .auth-input__left {
  color: var(--bad);
}

/* Settles back to the idle grey with its border. Hover and focus still tint it
   plum, so the field is not inert — it just is not announcing anything. */
.form-wrapper .input-box.is-valid .auth-input__left {
  color: #9aa1ae;
}

.form-wrapper .input-box.is-valid:hover .auth-input__left,
.form-wrapper .input-box.is-valid:focus-within .auth-input__left {
  color: var(--brand);
}

.form-wrapper .input-box.is-invalid:focus-within .auth-input__left {
  color: var(--bad);
}

/* Chrome paints autofilled fields pale blue, which fights every border colour
   above and looks nothing like the rest of the form. */
.form-wrapper input:-webkit-autofill,
.form-wrapper input:-webkit-autofill:hover,
.form-wrapper input:-webkit-autofill:focus {
  -webkit-text-fill-color: #001430;
  -webkit-box-shadow: 0 0 0 40px #fff inset;
  box-shadow: 0 0 0 40px #fff inset;
  caret-color: #001430;
  transition: background-color 9999s ease-in-out 0s;
}

@keyframes authSpin {
  to { transform: rotate(360deg); }
}

/* --- Per-field message ---------------------------------------------------
   The tick / cross lives on this line rather than inside the field: .input-box
   is a flex row whose input is sized with calc(), so an extra child in there
   pushes the layout around. */

.form-wrapper .field-msg {
  display: none;
  gap: 7px;
  align-items: flex-start;
  margin: 7px 0 0;
  font-size: 12.5px;
  line-height: 1.45;
  font-weight: 500;
}

.form-wrapper .field-msg.is-shown {
  display: flex;
  animation: authFadeIn 0.18s ease-out;
}

.form-wrapper .field-msg--error { color: var(--bad-ink); }
.form-wrapper .field-msg--ok { color: var(--ok-ink); }
.form-wrapper .field-msg--busy { color: #8b93a2; }

.form-wrapper .field-msg a {
  color: inherit;
  font-weight: 700;
  text-decoration: underline;
}

/* Small filled badge instead of a bare icon — a yellow outline tick is almost
   invisible on white. */
.field-msg__badge {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  margin-top: 1px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 8.5px;
  color: #fff;
}

.field-msg--error .field-msg__badge { background: var(--bad); }
.field-msg--ok .field-msg__badge { background: var(--ok); color: #fff; }

.field-msg__spinner {
  flex: 0 0 auto;
  width: 13px;
  height: 13px;
  margin-top: 1px;
  border: 2px solid #ececf1;
  border-top-color: var(--ok);
  border-radius: 50%;
  animation: authSpin 0.7s linear infinite;
}

@keyframes authFadeIn {
  from { opacity: 0; transform: translateY(-3px); }
  to { opacity: 1; transform: translateY(0); }
}

/* --- Form-level alert (wrong password, account disabled, …) -------------- */

.form-wrapper .form-alert {
  display: none;
  gap: 11px;
  align-items: flex-start;
  margin-bottom: 18px;
  padding: 13px 16px;
  border-radius: 14px;
  font-size: 13.5px;
  line-height: 1.5;
  font-weight: 500;
  background: #fff5f5;
  border: 1px solid #f7d2d2;
  color: #b8353a;
}

.form-wrapper .form-alert.is-shown {
  display: flex;
  animation: authFadeIn 0.2s ease-out;
}

/* Confirmation after a completed password reset — plum, matching `--ok`, so
   the one celebratory panel on the card is in the card's own colour. */
.form-wrapper .form-alert--ok {
  background: #fdf2f8;
  border-color: #f0cfe1;
  color: var(--ok-ink);
}

.form-alert--ok .form-alert__icon {
  background: var(--ok);
  color: #fff;
}

.form-alert__icon {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-top: 1px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 10px;
  background: var(--bad);
  color: #fff;
}

.form-wrapper .form-alert a {
  color: inherit;
  font-weight: 700;
  text-decoration: underline;
}

/* --- Password strength meter --------------------------------------------- */

.form-wrapper .pw-strength {
  display: none;
  margin-top: 9px;
}

.form-wrapper .pw-strength.is-shown { display: block; }

.pw-strength__row {
  display: flex;
  align-items: center;
  gap: 12px;
}

.pw-strength__bars {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
}

.pw-strength__bar {
  height: 4px;
  border-radius: 999px;
  background: #ececf1;
  transition: background 0.25s;
}

.pw-strength__label {
  flex: 0 0 auto;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: #9aa1ae;
  white-space: nowrap;
}

/* Weak still earns a warning red; from there it climbs the brand ramp
   amber -> yellow -> pink. */
.pw-strength[data-score="1"] { --pw: #e5484d; }
.pw-strength[data-score="2"] { --pw: #f5a623; }
.pw-strength[data-score="3"] { --pw: #fcc603; }
.pw-strength[data-score="4"] { --pw: #e83e8c; }

.pw-strength[data-score="1"] .pw-strength__bar:nth-child(-n + 1),
.pw-strength[data-score="2"] .pw-strength__bar:nth-child(-n + 2),
.pw-strength[data-score="3"] .pw-strength__bar:nth-child(-n + 3),
.pw-strength[data-score="4"] .pw-strength__bar:nth-child(-n + 4) {
  background: var(--pw);
}

.pw-strength[data-score="1"] .pw-strength__label { color: #cf3339; }
.pw-strength[data-score="2"] .pw-strength__label { color: #b3730a; }
.pw-strength[data-score="3"] .pw-strength__label { color: #8a6d00; }
.pw-strength[data-score="4"] .pw-strength__label { color: #d02b78; }

/* --- Terms checkbox ------------------------------------------------------ */

.form-wrapper .checkbox.is-invalid label,
.form-wrapper .checkbox.is-invalid label a {
  color: var(--bad-ink);
}

.form-wrapper .checkbox.is-invalid input[type="checkbox"] {
  outline: 2px solid var(--bad);
  outline-offset: 1px;
  border-radius: 4px;
}

/* .checkbox is a flex row with no bottom margin of its own, so the message
   needs its own breathing room or it sits on top of the label. */
.form-wrapper .checkbox-msg {
  width: 100%;
  margin-top: 9px;
}

/* --- Submit button, while the request is in flight ----------------------- */

.form-wrapper .submit-btn.is-busy,
.form-wrapper .submit-btn.is-busy:hover {
  opacity: 0.72;
  cursor: progress;
  transform: none;
}

.submit-btn__spinner {
  display: none;
  width: 17px;
  height: 17px;
  border: 2.5px solid rgba(61, 47, 0, 0.25);
  border-top-color: #fff;
  border-radius: 50%;
  animation: authSpin 0.7s linear infinite;
}

.submit-btn.is-busy .submit-btn__spinner { display: block; }
.submit-btn.is-busy > i { display: none; }
