/*
 * Unified form validation styles (v1.6.83)
 *
 * Activated by the vform-validate.js module after a server-side
 * validation failure. The CSS is intentionally lightweight: just an
 * error border + tinted background, an animated shake on first focus,
 * an inline message rendered below the field, and a "this tab has
 * errors" indicator for tabbed forms.
 *
 * The same selectors work for any input shape (input, select, textarea)
 * so this CSS is application-wide and doesn't need to know about
 * specific form layouts.
 */

/* ── Field highlight ──────────────────────────────────────────────────── */

.vfield-error,
.vfield-error.vinput,
input.vfield-error,
select.vfield-error,
textarea.vfield-error {
  border-color: #dc2626 !important;
  background-color: #fef2f2 !important;
  /* The 2px ring + 1.5px border gives 3.5px of red visual weight, more
     than enough to stand out against the form's neutral palette without
     looking like an emergency. */
  box-shadow: 0 0 0 2px rgba(220, 38, 38, 0.12) !important;
}

.vfield-error:focus,
input.vfield-error:focus,
select.vfield-error:focus,
textarea.vfield-error:focus {
  border-color: #dc2626 !important;
  /* On focus the ring intensifies slightly so the user knows where their
     cursor is even though the field already had error styling. */
  box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.22) !important;
  outline: none;
}

/* The error label rendered by the JS as a sibling of the bad input. */
.vfield-error-msg {
  display: block;
  margin-top: 4px;
  font-size: 11.5px;
  color: #b91c1c;
  font-weight: 500;
  line-height: 1.4;
  /* Subtle fade-in so messages don't pop into existence. 120ms is fast
     enough to feel snappy but slow enough to register. */
  animation: vform-fade-in 120ms ease-out;
}

.vfield-error-msg .ri,
.vfield-error-msg i {
  margin-right: 4px;
  font-size: 12px;
  vertical-align: -1px;
}

@keyframes vform-fade-in {
  from { opacity: 0; transform: translateY(-2px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Shake animation (first-focus attention nudge) ────────────────────── */

@keyframes vform-shake {
   0%, 100% { transform: translateX(0); }
  15%, 45%, 75% { transform: translateX(-6px); }
  30%, 60%, 90% { transform: translateX(6px); }
}

.vfield-shake {
  animation: vform-shake 380ms cubic-bezier(.36, .07, .19, .97) both;
}

/* ── Tab indicator (for forms that use the .tm-tab-strip pattern) ─────── */

/* When a tab contains a field with an error, the JS adds .vtab-has-error
   to the matching pill in the tab strip. Renders a tiny red dot the way
   "unread notification" badges work — visible enough to draw the eye
   but not so loud that it competes with the actual error styling. */
.tm-tab.vtab-has-error::after {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-left: 6px;
  border-radius: 50%;
  background: #dc2626;
  vertical-align: middle;
  /* Slow pulse to make sure the user can find the off-tab errors after
     dismissing the first round. Roughly 2 seconds — calm, not anxious. */
  animation: vform-tab-pulse 2.1s ease-in-out infinite;
}

@keyframes vform-tab-pulse {
   0%, 100% { box-shadow: 0 0 0 0   rgba(220, 38, 38, 0.45); }
  50%       { box-shadow: 0 0 0 5px rgba(220, 38, 38, 0); }
}

/* ── Summary banner enhancement ───────────────────────────────────────── */

/* The existing .valt.valt-err banner above each form (rendered by views)
   gets a soft entry animation so when a user hits Save and fails it
   doesn't just teleport in. */
.valt.valt-err {
  animation: vform-banner-slide 200ms ease-out;
}

@keyframes vform-banner-slide {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── v1.6.90 — Tab-click attention pulse ───────────────────────────────
   When the user clicks a tab that has empty required fields, the JS
   adds the .vfield-attention class to every such field. This CSS does
   a 3-pulse amber-to-red flash on the border + background, so all the
   "remaining work" lights up briefly. Self-cleans via animation-fill-mode
   `forwards` — the JS also strips the class after ~1.8s as belt-and-suspenders.

   v1.6.91 — Select2 wraps native <select> and hides the original.
   So when the .vfield-attention class lands on the .select2-container
   wrapper instead, we need the pulse to paint on its inner
   .select2-selection (the visible chrome). Same idea for flag-input
   widgets used by Country fields. */

/* Native fields — input, select (when not wrapped), textarea. */
input.vfield-attention,
select.vfield-attention,
textarea.vfield-attention {
  animation: vform-attention-pulse 1.6s ease-out 2;
}

/* Select2 container — the pulse lives on the inner .select2-selection
   so the visible bordered box reacts. We also lift the box-shadow to
   the outer container so the glow halo appears around the whole widget. */
.select2-container.vfield-attention {
  animation: vform-attention-glow 1.6s ease-out 1;
  border-radius: 7px;
}
.select2-container.vfield-attention .select2-selection {
  animation: vform-attention-pulse 1.6s ease-out 1;
}

/* Intl-phone flag-input wrapper. */
[data-input-flag].vfield-attention {
  animation: vform-attention-pulse 1.6s ease-out 2;
  border-radius: 7px;
}

/* v1.6.96 — vselect custom widget wrapper. The wrapping div is the
   visible element; we pulse it directly. */
.vselect-wrap.vfield-attention {
  animation: vform-attention-pulse 1.6s ease-out 2;
  border-radius: 7px;
}

@keyframes vform-attention-pulse {
  0% {
    outline: 2px solid transparent;
    outline-offset: 0;
    background-color: transparent;
    box-shadow: 0 0 0 0 rgba(245, 158, 11, 0);
  }
  20% {
    outline: 3px solid #f59e0b;
    outline-offset: 2px;
    background-color: #fef3c7;
    box-shadow: 0 0 0 6px rgba(245, 158, 11, 0.30);
  }
  50% {
    outline: 3px solid #dc2626;
    outline-offset: 2px;
    background-color: #fee2e2;
    box-shadow: 0 0 0 8px rgba(220, 38, 38, 0.20);
  }
  80% {
    outline: 3px solid #f59e0b;
    outline-offset: 2px;
    background-color: #fef3c7;
    box-shadow: 0 0 0 4px rgba(245, 158, 11, 0.15);
  }
  100% {
    outline: 2px solid transparent;
    outline-offset: 0;
    background-color: transparent;
    box-shadow: 0 0 0 0 rgba(245, 158, 11, 0);
  }
}

/* For wrappers where the border is on a child (e.g. Select2): keep
   the keyframe simpler — just the glow halo, since the child handles
   the border/bg pulse via vform-attention-pulse on its own. */
@keyframes vform-attention-glow {
  0%   { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0); }
  20%  { box-shadow: 0 0 0 4px rgba(245, 158, 11, 0.30); }
  50%  { box-shadow: 0 0 0 6px rgba(220, 38, 38, 0.20); }
  80%  { box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.15); }
  100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0); }
}
