/* ═══════════════════════════════════════════════════════════════════════════
   LUSKI — inline form errors  (Phase 6)
   ───────────────────────────────────────────────────────────────────────────
   Replaces every browser popup on the lead-capture pages. A validation failure is
   red text UNDER the field it belongs to, not a modal that hides the form
   while you read it and forgets which field was wrong when you dismiss it.

   ── PROPERTY OWNERSHIP ─────────────────────────────────────────────────────
   arcade/interact.css owns transform, box-shadow, outline, opacity and cursor
   for every interactive element on this site (read its header). So this file
   declares NONE of those on inputs. The invalid state is carried by
   border-color and background-color -- both of which components own -- plus
   the error text itself. In particular there is no :focus rule here: the ruby
   focus ring interact.css draws with box-shadow stays exactly as it is, and a
   focused invalid field shows BOTH the ring and the red border.

   No `transition:` SHORTHAND appears in this file. A shorthand resets
   transition-property and would silently delete interact.css's transform
   timing on any selector it manages.

   ── SPECIFICITY ────────────────────────────────────────────────────────────
   The invalid selectors are element-qualified on purpose. The pages that load
   this file style their fields at (0,1,1) -- `.tool-field input` on /finance/,
   `.f-row input` on /sell-your-car/ -- and at (0,2,1) when focused. A bare
   `.arc-input--invalid` at (0,1,0) would lose outright. `input.arc-input--
   invalid` is (0,1,1) and `input.arc-input--invalid:focus` is (0,2,1): both
   are TIES, broken by source order, which is why this must be the LAST
   stylesheet linked on every page that uses it. That position is load-bearing.

   ── TOKENS ─────────────────────────────────────────────────────────────────
   arcade/tokens.css has no red. The three tokens below are declared here so a
   seven-page feature does not force a version bump on the ~86 pages that link
   tokens.css. Their long-term home IS arcade/tokens.css -- promote them in the
   next full version sweep, not before.
   Contrast on the parchment these forms sit on: 5.13:1 on --arc-parchment
   (#ece3cf), 4.53:1 on --arc-parchment-2 (#e2d6b8). Both clear AA for the
   12.5px bold text below. This is NOT pixel-identical to the garage, which
   blends --g-bad-ink toward body text with color-mix; do not claim parity.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  --arc-bad: #B3261E;
  --arc-bad-soft: rgba(179, 38, 30, .10);
  --arc-bad-line: rgba(179, 38, 30, .34);
}

/* Geometry derived from garage/garage.css .g-field__error, so the two error
   treatments read as one system. The top margin is new: this node stands on
   its own rather than inside a gapped .g-field column. */
.arc-field-error {
  display: flex;
  align-items: center;
  gap: .4em;
  margin: 6px 0 0;
  color: var(--arc-bad);
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1.4;
}

/* Shape as well as colour: under forced-colors the red is dropped and the
   triangle is the only thing left carrying the signal. */
.arc-field-error::before {
  content: '';
  flex: none;
  display: block;
  width: .8em;
  height: .72em;
  background: currentColor;
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

/* border-color and background-color only -- see PROPERTY OWNERSHIP above. */
input.arc-input--invalid,
select.arc-input--invalid,
textarea.arc-input--invalid {
  border-color: var(--arc-bad);
  background-color: var(--arc-bad-soft);
}

/* (0,2,1), to tie with the pages' own `.tool-field input:focus` /
   `.f-row input:focus` border-colour and win on source order. The error must
   not vanish the moment the visitor focuses the field to fix it. */
input.arc-input--invalid:focus,
select.arc-input--invalid:focus,
textarea.arc-input--invalid:focus,
input.arc-input--invalid:focus-visible,
select.arc-input--invalid:focus-visible,
textarea.arc-input--invalid:focus-visible {
  border-color: var(--arc-bad);
}

/* Form-level banner. Network failures, not field failures. */
.arc-alert {
  display: block;
  padding: 12px 16px;
  border: 1px solid var(--arc-bad-line);
  border-left-width: 4px;
  border-radius: 8px;
  color: inherit;
  font-size: 13.5px;
  line-height: 1.6;
  margin: 0 0 12px;
}

.arc-alert--bad {
  border-left-color: var(--arc-bad);
  background: var(--arc-bad-soft);
}

/* Local screen-reader utility. Deliberately duplicates dialogue-box.css's
   .dlg-visually-hidden rather than importing it, so arcade/form-error.* has
   no cross-sheet dependency and can be linked on a page that loads neither. */
.arc-srt {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@keyframes arc-err-in {
  from { opacity: 0; transform: translateY(-3px); }
  to   { opacity: 1; transform: none; }
}

/* A shake, not a bounce: 200ms on a sharp curve, once per submit, on the FIRST
   invalid field only. Repeating it per field would read as the page breaking.
   This is the one transform in this file. It does not contest interact.css's
   ownership: that file's T5 field family declares no transform at all ("a
   moving input is hostile while you are typing into it") and this is an
   `animation`, not a `transition`, fired once by JS and removed on
   animationend -- it never fights a hover, press or focus rule. */
@keyframes arc-input-nudge {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-3px); }
  40%      { transform: translateX(3px); }
  60%      { transform: translateX(-2px); }
  80%      { transform: translateX(2px); }
}

.arc-field-error:not([hidden]),
.arc-alert:not([hidden]) {
  animation: arc-err-in 160ms var(--arc-ease);
}

.arc-input--nudge {
  animation: arc-input-nudge 200ms cubic-bezier(.36, .07, .19, .97);
}

@media (prefers-reduced-motion: reduce) {
  .arc-field-error:not([hidden]),
  .arc-alert:not([hidden]),
  .arc-input--nudge {
    animation: none;
  }
}
