/* Just Mercy · forms
   Split out of the single components.css so concurrent work on different
   areas cannot collide in one file, and so a page can eventually load only
   the CSS its elements need. Tokens come from tokens.css; no literal brand
   hex belongs in here (the page-quality gate's D2 criterion enforces it). */

/* =========================================================================
   JM Field and Choice row — Figma "Molecules / Field" (522:1248),
   "Molecules / Choice row" (522:1259) and the Input atoms.

   Built to the Figma "Spec — Forms, states & accessibility" panel (523:1406):
     focus-visible 3px Purple/500 ring at 2px offset, on every control, never removed
     errors 2px feedback/error border + a message under the field, never colour alone
     labels always visible above the field
     targets minimum 44x44 including padding, and the choice hit area is the whole row
     border-color transitions var(--motion-fast) var(--motion-ease-out)
   ========================================================================= */

.jm-field {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;                         /* 8 */
  /*
   * Fill the container's cross axis. Bricks' `.brxe-block` is a column flex
   * container with `align-items: flex-start`, so without this a field shrinks to
   * its own content width: on the Contact page the email, organisation and
   * message fields came out 228px inside a 402px column while the first
   * name/surname pair — which sits in a grid, where the default IS stretch —
   * correctly filled it. Fields looked randomly sized down the form.
   *
   * `align-self` rather than `width: 100%`: in a column flex parent the cross
   * axis is horizontal, so this gives full width, and in a grid or a row parent
   * it only restates the default, so it cannot fight a future layout.
   */
  align-self: stretch;
}

.jm-field__label {
  font: 500 var(--text-body)/1.2 var(--font-sans);       /* 16 Medium */
  color: var(--purple-500);
}
.jm-field__required { color: var(--feedback-error); }

.jm-field__control {
  width: 100%;
  min-height: 3.4375rem;               /* 55 */
  padding: 0.75rem 1.25rem;            /* 20 sides; vertical keeps the 55 height */
  border: 1px solid transparent;       /* reserved so no state shifts the layout */
  border-radius: 0;
  background-color: var(--stone-100);
  color: var(--purple-700);
  font: 400 var(--text-body)/1.4 var(--font-sans);
  transition: border-color var(--motion-fast) var(--motion-ease-out);
  appearance: none;
}
.jm-field__control::placeholder { color: var(--purple-400); }

.jm-field__control:hover { border-color: var(--purple-400); }

/* Filled — a value present, per the atom's Filled variant. :not(:placeholder-shown)
   is the closest CSS gets to "has a value" without script. */
.jm-field__control:not(:placeholder-shown):not(:focus) { border-color: var(--purple-100); }

.jm-field__control:focus-visible,
.jm-field__control:focus {
  outline: 3px solid var(--purple-500);
  outline-offset: 2px;
  border-color: transparent;
}

.jm-field__control[aria-invalid='true'] { border: 2px solid var(--feedback-error); }

.jm-field__control:disabled {
  background-color: var(--stone-300);
  border-color: var(--stone-600);
  color: var(--stone-700);
  cursor: not-allowed;
}

.jm-field--textarea .jm-field__control {
  min-height: 8.75rem;                 /* 140 */
  padding: 1rem 1.25rem;               /* 16 top, 20 sides */
  resize: vertical;
}

/* Dropdown: the native control keeps arrow keys, Enter/Space and Esc, which is
   exactly the keyboard behaviour the spec asks for. The caret is ours. */
.jm-field--select { position: relative; }
.jm-field--select .jm-field__control { padding-right: 3rem; }
.jm-field__caret {
  position: absolute;
  right: 1.25rem;
  bottom: 1.25rem;
  color: var(--purple-500);
  pointer-events: none;
}
.jm-field--select:has(.jm-field__helper) .jm-field__caret { bottom: 3.25rem; }

.jm-field__helper {
  margin: 0;
  font: 400 var(--text-label-s)/1.3 var(--font-sans);    /* 13 */
  color: var(--purple-400);
}

/* Never colour alone — the message is always the signal, the border only supports it. */
.jm-field__error {
  margin: 0;
  font: 500 var(--text-label-s)/1.3 var(--font-sans);
  color: var(--feedback-error);
}
.jm-field__error[hidden] { display: none; }

/* ---- Choice row ---- */

.jm-choice { position: relative; }

/* Visually hidden but never display:none — it must stay focusable and in the
   accessibility tree. The visible box is drawn by the label. */
.jm-choice__input {
  position: absolute;
  top: 0;
  left: 0;
  width: 1.25rem;
  height: 1.25rem;
  opacity: 0;
  margin: 0;
}

.jm-choice__label {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.75rem;                        /* 12 */
  /* 24, not 44.

     The board draws this row 22.4 tall (588:3225). 44 is the WCAG 2.5.8 AAA
     figure; AA asks for 24x24, and the label wraps the whole row so the target is
     already full-width. Forcing 44 inflated the row by ~27px and pushed the
     Contact form's newsletter line well off the board. 24 satisfies AA and lands
     1.6px off the drawn height. */
  min-height: 1.5rem;                  /* 24 */
  cursor: pointer;
}

.jm-choice__box {
  flex: 0 0 auto;
  display: block;
  width: 1.25rem;                      /* 20 */
  height: 1.25rem;
  border: 1.5px solid var(--purple-400);
  background-color: var(--stone-100);
  transition: border-color var(--motion-fast) var(--motion-ease-out), background-color var(--motion-fast) var(--motion-ease-out);
}
.jm-choice--radio .jm-choice__box { border-radius: var(--radius-pill); }

.jm-choice__text {
  font: 400 var(--text-body)/1.4 var(--font-sans);
  color: var(--purple-700);
}

.jm-choice__box {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.jm-choice__label:hover .jm-choice__box { border-color: var(--purple-500); }

/* Checked marks, exactly as the atoms draw them.
   Checkbox: Purple/500 fill and border, with a 12px Stone/100 tick.
   Radio:    Stone/100 fill, Purple/500 border, and an 8px Purple/500 dot. */

.jm-choice--checkbox .jm-choice__input:checked + .jm-choice__label .jm-choice__box {
  border-color: var(--purple-500);
  background-color: var(--purple-500);
}
.jm-choice--checkbox .jm-choice__input:checked + .jm-choice__label .jm-choice__box::after {
  content: '\2713';
  font: 500 0.75rem/1 var(--font-sans);   /* 12 Medium */
  color: var(--stone-100);
}

.jm-choice--radio .jm-choice__input:checked + .jm-choice__label .jm-choice__box {
  border-color: var(--purple-500);
  background-color: var(--stone-100);
}
.jm-choice--radio .jm-choice__input:checked + .jm-choice__label .jm-choice__box::after {
  content: '';
  width: 0.5rem;                       /* 8 — the Figma dot is r=4 */
  height: 0.5rem;
  border-radius: 50%;
  background-color: var(--purple-500);
}

.jm-choice__input:focus-visible + .jm-choice__label .jm-choice__box {
  outline: 3px solid var(--purple-500);
  outline-offset: 2px;
}

.jm-choice__input:disabled + .jm-choice__label {
  cursor: not-allowed;
  color: var(--stone-700);
}
.jm-choice__input:disabled + .jm-choice__label .jm-choice__box {
  border-color: var(--stone-600);
  background-color: var(--stone-300);
}

.jm-choice__desc {
  margin: 0 0 0 2rem;                  /* aligned under the label text */
  font: 400 var(--text-label-s)/1.4 var(--font-sans);
  color: var(--purple-400);
}

@media (prefers-reduced-motion: reduce) {
  .jm-field__control,
  .jm-choice__box { transition: none; }
}
