/* =============================================================
   Forms

   The contact form's fields and the availability table that sits
   alongside it on Reach Out.

   Structure only. Every value is a token from tokens.css — no
   hard-coded hex, spacing or type values in here (see CLAUDE.md).

   Load order: 6th and last, after components.css. See the stylesheet
   block in _includes/layouts/base.njk for the full order.
   ============================================================= */

/* --- Contact form -------------------------------------------------- */

.form-field {
  margin: 0 0 var(--space-m);
  max-width: 32rem;
}

.form-field label {
  display: block;
  font-weight: var(--weight-medium);
  margin-bottom: var(--space-3xs);
}

.form-field input,
.form-field select,
.form-field textarea {
  width: 100%;
  font: inherit;
  color: var(--color-text);
  background: var(--color-bg);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-s);
  padding: var(--space-2xs) var(--space-xs);
  min-height: var(--target-comfortable);
}

/* Grows with what is typed instead of scrolling inside an 8rem box, up to
   a cap, then scrolls. width: 100% above keeps it from also resizing
   sideways, which jumps the moment a long placeholder gives way to one
   typed character. Browsers without field-sizing keep the fixed 8rem box
   and the manual resize handle, which is what everyone had before. */
.form-field textarea {
  min-height: 8rem;
  max-height: 24rem;
  field-sizing: content;
  resize: vertical;
}

/* Invalid fields, marked only AFTER the visitor has interacted: typed and
   left the field, or tried to submit. :invalid would paint every empty
   required field red on page load, before anyone has done anything wrong.

   Two signals, not colour alone (WCAG 1.4.1): the error colour and a
   thicker leading edge. The browser's own validation message supplies the
   words on submit. No box-shadow here: *:focus-visible draws its halo
   ring with box-shadow, and this rule's higher specificity would erase
   the focus indicator on exactly the field the visitor is fixing.

   Browsers without :user-invalid drop the whole rule and show nothing,
   the same as before this existed. */
.form-field :is(input, select, textarea):user-invalid {
  border-color: var(--color-error);
  border-inline-start-width: var(--space-3xs);
}

.form-field--checkbox {
  display: flex;
  align-items: start;
  gap: var(--space-2xs);
}

/* Equal specificity (0,1,1) to `.form-field input` above and relies on
   source order to win. Both rules must stay in this file, in this
   order — splitting them apart is the one edit that would silently
   break the checkbox layout. */
.form-field--checkbox input {
  width: auto;
  min-height: auto;
  margin-top: 0.3em;
}

.form-field--checkbox label {
  font-weight: var(--weight-normal);
}

/* Grouped fields and choice lists, rendered by partials/declared-form.njk.
   A fieldset carries its own legend, so the browser's border and padding
   come off and the legend reads like any other field label. */
.form-group,
.form-choices {
  border: 0;
  padding: 0;
  margin: 0 0 var(--space-m);
  min-width: 0;
}

.form-group > legend {
  font-weight: var(--weight-bold);
  margin-bottom: var(--space-xs);
}

.form-choices > legend {
  font-weight: var(--weight-medium);
  margin-bottom: var(--space-3xs);
}

/* One row per option: the input beside its label, as for the privacy box.
   (0,2,1) beats `.form-field input` (0,1,1), so a radio or checkbox here is
   never stretched to the field's full width. */
.form-choice {
  display: flex;
  align-items: start;
  gap: var(--space-2xs);
  margin-bottom: var(--space-3xs);
}

.form-choices .form-choice input {
  width: auto;
  min-height: auto;
  margin-top: 0.3em;
}

.form-choices .form-choice label {
  font-weight: var(--weight-normal);
  margin: 0;
}

.form-optional,
.form-hint {
  color: var(--color-text-muted);
  font-weight: var(--weight-normal);
}

.form-hint {
  margin: 0 0 var(--space-3xs);
  font-size: 0.9rem;
}

/* "Why we ask, and who would know", under a field's label. Closed by
   default: most visitors need it for a few questions, not all of them. */
.form-help {
  margin: 0 0 var(--space-2xs);
  font-size: 0.9rem;
}

.form-help > summary {
  cursor: pointer;
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 0.15em;
  width: fit-content;
}

.form-help > p {
  margin: var(--space-3xs) 0 0;
  max-width: var(--measure);
}

/* A statement the visitor ticks to agree to. The label is a sentence or
   two, not a field name, so it reads at normal weight. */
.form-field--confirm {
  max-width: var(--measure);
}

/* "Save my answers on this device" (config/forms.json saveOnDevice). Set
   apart from the questions: it is about the form, not part of it. */
.form-save {
  max-width: var(--measure);
  margin: 0 0 var(--space-l);
  padding: var(--space-s) var(--space-m);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-m);
  background: var(--color-surface);
}

.form-save .form-field {
  margin-bottom: var(--space-2xs);
}

.form-save__status:empty {
  display: none;
}

/* --- Forms in steps (config/forms.json `steps`) ---------------------- */

/* The list of sections. Without JavaScript it is a table of contents for
   one long form; form-steps.js turns it into the progress indicator, with
   aria-current="step" on the section on screen. */
.form-steps ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-s);
  margin: 0 0 var(--space-l);
  padding: 0;
  list-style: none;
  counter-reset: form-step;
}

.form-steps li {
  counter-increment: form-step;
}

.form-steps a::before {
  content: counter(form-step) ". ";
}

.form-steps a[aria-current="step"] {
  font-weight: var(--weight-bold);
  text-decoration-thickness: 0.15em;
}

.form-step {
  margin: 0 0 var(--space-2xl);
}

.form-step > h2 {
  scroll-margin-top: var(--space-l);
}

.form-step__count {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--weight-normal);
  color: var(--color-text-muted);
}

.form-step__intro {
  max-width: var(--measure);
}

/* One step on screen at a time: the next one starts right under the
   buttons, so the gap between steps is not needed. */
.form.is-stepped .form-step {
  margin-bottom: 0;
}

.form-step__nav,
.form-submit {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  margin-top: var(--space-l);
}

/* <button>s do not inherit the page's type, so Back and Next would read
   smaller than the questions above them. Scoped to stepped forms so the
   single-step forms' submit buttons stay exactly as they were. */
.form--stepped .button,
.form-save .button {
  font: inherit;
  font-weight: var(--weight-medium);
  border: 1px solid transparent;
  cursor: pointer;
}

.form .button--secondary {
  background: transparent;
  border-color: var(--color-border-strong);
}

/* Honeypot — NOT RENDERED. display: none, deliberately.

   This used to be visually hidden instead (1px, clip-path: inset(50%)), so that
   assistive-tech users who reached it would get a label telling them to leave
   it blank. That had it backwards. The screen-reader-only pattern exists to
   keep an element IN the accessibility tree, so it is what put the field in
   front of screen-reader users at all — and it kept the field rendered, which
   made it an autofill target. Browsers fill a field named "company" whatever
   autocomplete="off" says. A filled honeypot means the handler fakes success
   and records and sends nothing: on the first client, two genuine test
   enquiries vanished that way, with no sheet row, no mail attempt, no trace.

   With display: none no person reaches it, by keyboard, screen reader or
   autofill, so there is nobody to warn. A bot reading the HTML still fills it.
   The cost is a bot that skips display:none fields getting through: a spam row,
   against a lost enquiry. Put `hidden` on the wrapper too, so this holds
   without the stylesheet. */
.form-field--honeypot {
  display: none;
}

/* --- Availability table -------------------------------------------- */

.availability {
  border-collapse: collapse;
  margin: var(--space-l) 0;
}

.availability th,
.availability td {
  text-align: left;
  padding: var(--space-2xs) var(--space-m) var(--space-2xs) 0;
  border-bottom: 1px solid var(--color-border);
}
