/* ==========================================================================
   FORMS
   ==========================================================================
   Two parts, kept separate on purpose:

     PART 1 — LAYOUT   how form fields sit in the column framework
     PART 2 — BRAND    how they look

   Change Part 2 per site. Part 1 should rarely need touching.

   SCOPE: `.formbody`, not `.ce_form .formbody`. Contao uses the same wrapper
   for the form CONTENT ELEMENT and for every member module — login, lost
   password, change password, personal data, registration. They render the
   same .widget markup, so scoping to .ce_form left every member form
   completely unstyled while the contact form looked finished.

   Two files would have been the wrong fix: they would race to style one
   .widget at equal specificity and drift apart, which is the same reasoning
   that keeps list typography in one place.
   ========================================================================== */


/* ==========================================================================
   PART 1 — LAYOUT
   ==========================================================================
   Contao renders form fields as .widget divs inside .formbody. This makes
   .formbody behave as a framework row, so a `col-*` class on a form field
   works exactly as it does on a content element inside an article — same
   widths, same gutter, same stacking.

   Editors set the width through the Theme Toolbox, which already offers the
   column options on every form field type. No template override is needed;
   this is done entirely in CSS.

   The column WIDTHS come from framework_v3 — they are plain flex-basis
   values and apply to any flex child. Only the row behaviour and the
   stacking are repeated here, because those are scoped to `.row` in the
   framework and .formbody is markup we do not control.
   ========================================================================== */

.formbody {
  display: flex;
  flex-wrap: wrap;

  /* Same tokens the framework's rows use, so form gutters match page
     gutters and respond to the same per-site dial. */
  --gap-x: var(--row-gap-x);
  --gap-y: var(--row-gap-y);
  gap: var(--gap-y) var(--gap-x);
}

/* Default every child to a full line, so a field with no col-* class takes
   its own row and Contao's own children (error messages) behave.

   :where() keeps this at ZERO specificity on purpose — the col-* classes
   must win, and this file loads after the framework, so a normal selector
   here would beat them on source order and flatten every column. */
:where(.formbody) > * {
  flex: 0 1 100%;
  min-width: 0;
}

/* Row gaps handle the spacing between fields, so widgets carry no margin
   of their own — otherwise the two would compound. */
.formbody > .widget {
  margin: 0;
}

/* Stacking, mirroring the framework's own breakpoints. Higher specificity
   than the col-* widths, so these win below the breakpoint.
   `.no-stack` on the form opts out, exactly as it does on a row. */
@media (max-width: 992px) {
  form:not(.no-stack) .formbody > .col-1-3,
  form:not(.no-stack) .formbody > .col-2-3,
  form:not(.no-stack) .formbody > .col-3-4,
  form:not(.no-stack) .formbody > .col-3-5,
  form:not(.no-stack) .formbody > .col-2-5,
  form:not(.no-stack) .formbody > .col-30,
  form:not(.no-stack) .formbody > .col-20 {
    flex-basis: 100%;
  }

  /* Quarters go 4 -> 2 before stacking, as they do in a row. */
  form:not(.no-stack) .formbody > .col-1-4 {
    flex-basis: calc(50% - var(--gap-x, 0px) * 0.5);
  }
}

@media (max-width: 600px) {
  form:not(.no-stack) .formbody > .col-1-2,
  form:not(.no-stack) .formbody > .col-1-4 {
    flex-basis: 100%;
  }
}

/* The label sits above its control. */
.formbody label {
  display: block;
}

/* Controls fill their column. Without this an input keeps its browser
   default size (roughly 20 characters) and ignores the column entirely. */
.formbody input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]),
.formbody select,
.formbody textarea {
  width: 100%;
  max-width: 100%;
}

.formbody textarea {
  display: block;
  resize: vertical;      /* horizontal resizing would break the column */
}

/* Checkbox and radio groups: the control sits beside its label. */
.formbody .checkbox_container label,
.formbody .radio_container label {
  display: inline-block;
}


/* ==========================================================================
   PART 2 — BRAND
   ==========================================================================
   Colours come from the tokens in website.css. Adjust the values here per
   site; the layout above is unaffected by anything in this section.
   ========================================================================== */

.formbody input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]),
.formbody select,
.formbody textarea {
  padding: 14px 20px;
  border: 1px solid var(--stroke);
  border-radius: 10px;
  background-color: var(--white);
  color: var(--text);
  font: inherit;         /* controls do not inherit type by default */
}

/* FOCUS — deliberately explicit.
   website_standard.css sets `outline: none` on form fields and replaces it
   with nothing, which leaves keyboard users unable to see where they are
   (WCAG 2.4.7). This restores a visible focus ring. Do not remove it
   without providing another visible indicator. */
.formbody input:focus-visible,
.formbody select:focus-visible,
.formbody textarea:focus-visible {
  outline: 2px solid var(--prime);
  outline-offset: 2px;
  border-color: var(--prime);
}

.formbody label {
  margin-bottom: var(--space-8);
  font-size: 0.875em;
}

/* The asterisk on a required field. */
.formbody span.mandatory {
  color: var(--second);
}

.formbody ::placeholder {
  color: var(--grey-dark);
  opacity: 1;            /* Firefox dims placeholders by default */
}

/* Validation messages. */
.formbody p.error,
.formbody .widget .error {
  color: var(--second);
  font-size: 0.875em;
}

.formbody .widget.error input,
.formbody .widget.error select,
.formbody .widget.error textarea {
  border-color: var(--second);
}

/* Buttons use the site's .btn rules in website.css — only the
   form-specific spacing is set here. */
.formbody .widget-submit button {
  margin-bottom: 0;
}


/* A checkbox and its label stay on one row, however long the label wraps
   (the label used to drop under the box on narrow screens) */
.checkbox_container > span { display: flex; align-items: flex-start; gap: 10px; }
.checkbox_container > span input { flex: none; margin-top: 0.25em; }
