/* ==========================================================================
   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: 12px 14px;
  border: 1px solid rgb(0 0 0 / 0.14);   /* Squarespace's field: square, faint edge, off-white */
  border-radius: 0;
  background-color: #fafafa;
  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: 6px;
  font-size: 16px;
}

/* 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; }


/* Cor Deo: a conditional fieldset (terminal42/contao-conditionalformfields)
   is a row of its own, so col-* widths work inside it as they do in .formbody.
   Its legend reads as a section heading in the site's label style. */
.formbody fieldset[data-cff-condition] {
  display: flex;
  flex-wrap: wrap;
  gap: var(--row-gap-y) var(--row-gap-x);
  margin: 12px 0 0;
  padding: 0;
  border: 0;
}
.formbody fieldset[data-cff-condition] > * { flex: 0 1 100%; min-width: 0; }
.formbody fieldset[data-cff-condition] > legend {
  margin-bottom: 4px;
  padding: 0;
  font-family: var(--type-display);
  font-size: 18px;
  font-weight: 400;
  letter-spacing: 4px;
  text-transform: uppercase;
}
/* Radio and checkbox groups: the group label like a field label; .inline sets options in a row */
.formbody .radio_container,
.formbody .checkbox_container { margin: 0; padding: 0; border: 0; }
.formbody .radio_container legend,
.formbody .checkbox_container legend { margin-bottom: 6px; padding: 0; font-size: 16px; }
.formbody .radio_container.inline > span { display: inline-flex; gap: 8px; margin-right: 22px; }
.formbody .explanation p { margin: 0; }
.formbody .checkbox_container.inline > span { display: inline-flex; gap: 8px; margin-right: 22px; }


/* TOUR PICKER — the "Tour time" field as a calendar + times (tour-picker.js).
   Calendar left, the chosen day's times right; stacked on phones. */
.tour-picker {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: 24px;
  margin-top: 4px;
}
.tp-cal { border: 1px solid var(--stroke); padding: 14px; }
.tp-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.tp-month { font-family: var(--type-display); font-size: 15px; font-weight: 500; letter-spacing: 2px; text-transform: uppercase; }
.tp-nav {
  width: 34px; height: 34px;
  border: 0; background: none; cursor: pointer;
  font-size: 24px; line-height: 1; color: var(--accent);
}
.tp-nav:disabled { color: var(--stroke); cursor: default; }
.tp-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; text-align: center; }
.tp-wd { font-size: 12px; color: var(--text-muted); padding-bottom: 4px; }
.tp-date {
  aspect-ratio: 1;
  min-height: 34px;
  border: 1px solid transparent;
  background: var(--brand-blue-tint);
  color: var(--accent);
  font: 600 15px/1 var(--type-body);
  cursor: pointer;
}
.tp-date:hover { border-color: var(--accent); }
.tp-date:disabled { background: none; color: rgb(0 0 0 / 0.28); font-weight: 300; cursor: default; border-color: transparent; }
.tp-date[aria-pressed="true"] { background: var(--accent); color: var(--white); }
.tp-day { margin: 6px 0 12px; font-family: var(--type-display); font-size: 18px; }
.tp-slots { display: flex; flex-wrap: wrap; gap: 8px; }
.tp-time {
  padding: 10px 16px;
  border: 2px solid var(--accent);
  background: var(--white);
  color: var(--accent);
  font: 500 15px/1 var(--type-body);
  cursor: pointer;
}
.tp-time:hover { background: var(--brand-blue-tint); }
.tp-time[aria-pressed="true"] { background: var(--accent); color: var(--white); }
.tp-note { margin-top: 14px; font-size: 14px; color: var(--text-muted); }
.tour-picker button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (max-width: 640px) {
  .tour-picker { grid-template-columns: 1fr; }
}
