/* ============================================================================
   The request form and the contact section around it.
   ----------------------------------------------------------------------------
   This sheet is loaded by leadFormHead, NOT from the shell's ExtraCSS list, and
   that is the whole point of it existing. leadFormHead and contactSection are
   used together at every one of the six call sites, so a stylesheet loaded by
   the former can never be missing where the latter renders.

   These rules lived in pages.css, which the LANDING page does not load — so the
   request form on the most-visited page of the site rendered as unstyled
   browser defaults, and nothing in the build could notice: pages.css was
   present on /kontakt and on every service page, where the form looked
   perfectly correct. A component's stylesheet belongs with the component, not
   with a page group that happens to contain most of its call sites.
   ========================================================================== */

/* ── The contact section ───────────────────────────────────────────
   Two columns on the landing page and the service pages: the CMS copy left,
   the form right. /kontakt uses .contact--single instead — see below. */

.contact {
  display: grid;
  grid-template-columns: minmax(260px, 0.82fr) minmax(0, 1.18fr);
  gap: var(--sp-8);
  align-items: start;
}

/* The rail travels with the form rather than stranding at the top of a column
   the form makes 900px tall. Everything unverifiable ships EMPTY here — phone,
   address, e-mail — so on a fresh deployment this column is a heading and two
   sentences beside a full-height form, and without this it reads as a hole in
   the page rather than as a margin. Sticky works from a content-height grid
   item because the sticky containing block is the grid AREA, which spans the
   full row. */
.contact-copy { position: sticky; top: 92px; }

.contact-copy h2 { max-width: 16ch; }
.contact-body {
  font: var(--body-md);
  color: var(--text-muted);
  margin-top: var(--sp-4);
  max-width: 46ch;
}
.contact-details { list-style: none; display: grid; gap: var(--sp-3); margin-top: var(--sp-6); }
.contact-details li { display: flex; align-items: center; gap: var(--sp-3); font: var(--body-md); }
.contact-details iconify-icon { flex: none; color: var(--navy-600); }
.contact-details a { color: var(--text-body); text-decoration: none; }
.contact-details a:hover { color: var(--navy-700); text-decoration: underline; }

/* A chip, not a line of amber text. The accent is allowed on chips and denied
   large surfaces, and bare amber body copy reads as an error message — which is
   the opposite of what "we answer within a working day" is saying. */
.contact-promise {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-5);
  padding: 7px 12px;
  border-radius: var(--radius-sm);
  background: var(--signal-100);
  font: var(--body-sm);
  font-weight: 500;
  color: var(--signal-600);
}
.contact-promise iconify-icon { flex: none; }

/* In /kontakt's page head the same details run ACROSS rather than down: they
   are a strip under the lead, not a column beside a form. */
.page-head .contact-details {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3) var(--sp-6);
  margin-top: var(--sp-5);
}

/* /kontakt carries its own page-head, so the section is the form alone, at a
   measure the two-column field grid actually fits in. */
.contact--single { grid-template-columns: minmax(0, 1fr); }
.contact--single .lead-form-wrap { max-width: 760px; }

/* ── The form card ─────────────────────────────────────────────── */

.lead-form-wrap {
  background: var(--paper-0);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  padding: var(--sp-6);
}

/* Three groups, in the order the conversation actually goes: what happened,
   what you can show us, how we reach you. The subject comes FIRST because it
   is what makes the follow-up questions appear — a visitor who fills in their
   name and address and is then shown four new fields has been ambushed by a
   form that looked finished.

   role="group" + aria-labelledby, NOT <fieldset>/<legend>. The pair is the
   semantically obvious choice and it is unstyleable: Chrome paints the legend
   at the fieldset's BORDER-box top and resolves the padding box BELOW it, so a
   border-top is cut out from behind the legend, the fieldset's padding-top
   lands under the label instead of above it, and even an absolutely positioned
   pseudo-element with `top: 0` comes out underneath — every route to "a rule
   above the group's name" ends in a rule beside it. A div announces itself to
   a screen reader identically and lays out like a div. */
.lead-group { min-width: 0; }
.lead-group + .lead-group {
  margin-top: var(--sp-6);
  padding-top: var(--sp-6);
  border-top: 1px solid var(--line-2);
}
.lead-group-title {
  font: var(--kicker);
  letter-spacing: var(--kicker-tracking);
  text-transform: uppercase;
  color: var(--ink-500);
}
/* The rhythm inside a group, stated once. Naming the pairs instead
   (.lead-grid + .lead-grid) silently skipped the gap wherever the conditional
   follow-up block sat between them — which is every category that has one. */
.lead-group > * + * { margin-top: var(--sp-4); }

/* An EXPLICIT two-column grid, and every field spans both columns unless it is
   deliberately paired. The previous auto-fit grid decided the spans from the
   card's width, which put "E-post" alone in the left half of a row with a hole
   beside it — the shape a form takes when nobody chose its shape. */
.lead-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-4);
}

.field {
  grid-column: 1 / -1;
  display: grid;
  gap: var(--sp-2);
  align-content: start;
  min-width: 0;
}
/* Halves are only ever used in pairs. */
.field--half { grid-column: span 1; }

.field-label {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  font: var(--body-sm);
  font-weight: 600;
  color: var(--ink-700);
}
/* Optional fields say so; required fields say nothing. The inverse — an
   asterisk on the required ones — needs a legend to decode and puts a warning
   glyph on most of the form. */
.field-optional {
  font-size: 12px;
  font-weight: 400;
  /* --ink-500, not --ink-300. This is meaningful text — it is the only thing
     telling a visitor they may skip the field — and --ink-300 on white is
     about 2.4:1, well under the 4.5:1 a body-size string has to clear. */
  color: var(--ink-500);
}
.field-hint { font: var(--body-sm); color: var(--ink-500); }
/* Attached to the pair above it, not floating between two groups. */
.field-hint--group { margin-top: var(--sp-2); }

.lead-form :is(
  input[type="text"],
  input[type="tel"],
  input[type="email"],
  input[type="date"],
  select,
  textarea
) {
  width: 100%;
  /* 16px, never smaller: iOS zooms the whole page when a smaller control takes
     focus, and the visitor is then reading a form at 130%. */
  font: var(--body-md);
  color: var(--ink-900);
  background: var(--paper-0);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-sm);
  padding: 11px 13px;
  transition: border-color var(--speed) var(--ease), box-shadow var(--speed) var(--ease);
}
.lead-form :is(input, select, textarea):hover:not(:focus) { border-color: var(--ink-300); }
.lead-form :is(input, select, textarea):focus-visible {
  outline: none;
  border-color: var(--navy-500);
  box-shadow: var(--focus-ring);
}
.lead-form textarea { resize: vertical; min-height: 140px; }

/* The native select control is the one place a careful form still looks like a
   browser default. The chevron is inlined rather than fetched: this sheet is
   embedded in the binary and a second request for 300 bytes of arrow is not a
   trade worth making. */
.lead-form select {
  appearance: none;
  padding-right: 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235E6874' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 13px center;
}

/* A control's width is a claim about the answer. A date or a yes/no stretched
   across the full column invites a sentence and gets one. */
.field--short :is(input, select) { max-width: 16rem; }

/* ── The conditional follow-ups ─────────────────────────────────────
   Datastar hides the non-matching groups at runtime; with JavaScript off they
   all render, which is why each carries its own heading.

   Neutral, not amber. This block is 400px tall on a phone, and the signal
   accent is for kickers, chips and defect markers — never a surface this size.
   An amber panel on an inspector's site reads as "something is wrong here",
   which is an odd thing to say about four questions we are asking. */
.lead-followups {
  border-left: 2px solid var(--navy-300);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--paper-1);
  padding: var(--sp-4) var(--sp-5);
  margin-top: var(--sp-4);
}
.lead-followups-title {
  margin-bottom: var(--sp-3);
  font: var(--kicker);
  letter-spacing: var(--kicker-tracking);
  text-transform: uppercase;
  color: var(--ink-500);
}
.lead-followups .lead-grid { grid-template-columns: minmax(0, 1fr); }

/* ── Attachments ───────────────────────────────────────────────────
   A row rather than a 150px-tall dashed panel. It is the one control on the
   form that most visitors skip, and it was taking more vertical space than the
   description of the problem. */

.lead-upload { display: grid; gap: var(--sp-3); }
.dropzone {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-4);
  border: 1px dashed var(--line-1);
  border-radius: var(--radius-sm);
  background: var(--paper-1);
  cursor: pointer;
  transition: border-color var(--speed) var(--ease), background var(--speed) var(--ease);
}
.dropzone:hover, .dropzone[data-over] { border-color: var(--navy-400); background: var(--navy-100); }
.dropzone input[type="file"] { position: absolute; width: 1px; height: 1px; opacity: 0; }
.dropzone-icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line-1);
  background: var(--paper-0);
  color: var(--navy-600);
}
.dropzone-body { display: grid; gap: 2px; min-width: 0; }
.dropzone-text { font: var(--label); color: var(--navy-700); }
.dropzone-hint { font: var(--body-sm); color: var(--ink-500); }

.upload-list { list-style: none; display: grid; gap: 6px; }
.upload-list li {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font: var(--body-sm);
  background: var(--paper-0);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
}
.upload-list .upload-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.upload-list .upload-size { color: var(--ink-500); font-variant-numeric: tabular-nums; }
.upload-list button {
  border: 0;
  background: none;
  color: var(--ink-500);
  cursor: pointer;
  display: grid;
  place-items: center;
}
.upload-list button:hover { color: var(--danger); }
.upload-list li[data-pending] { opacity: .6; }
.upload-error, .lead-error { font: var(--body-sm); color: var(--danger); }
.lead-error:empty, .upload-error:empty { display: none; }

/* ── Consent, challenge, submit ────────────────────────────────── */

.consent {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--sp-3);
  align-items: start;
  margin-top: var(--sp-5);
  font: var(--body-sm);
  color: var(--text-body);
}
.consent input {
  width: 18px;
  height: 18px;
  margin-top: 2px;
  accent-color: var(--navy-600);
}
.consent a { color: var(--link); text-decoration: underline; text-underline-offset: 2px; }

.lead-submit {
  display: grid;
  gap: var(--sp-3);
  margin-top: var(--sp-6);
}
.lead-form .btn-primary--block { padding: 15px var(--sp-5); }
.cf-turnstile { min-height: 65px; }

/* ── Success ───────────────────────────────────────────────────── */

.lead-success { text-align: center; padding: var(--sp-7) var(--sp-4); }
.lead-success-icon {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  margin: 0 auto var(--sp-4);
  border-radius: 50%;
  background: var(--navy-100);
  color: var(--success);
}
.lead-success h3 { font: var(--display-md); }
.lead-success p { font: var(--body-md); color: var(--text-muted); margin-top: var(--sp-3); }

/* ── Responsive ────────────────────────────────────────────────── */

@media (max-width: 980px) {
  .contact { grid-template-columns: minmax(0, 1fr); gap: var(--sp-6); }
  /* Nothing to stick to once the form is below rather than beside it. */
  .contact-copy { position: static; }
  .contact-copy h2 { max-width: none; }
}

@media (max-width: 620px) {
  .lead-form-wrap { padding: var(--sp-4); }
  /* Two 130px columns are not two columns. Everything goes full width. */
  .lead-grid { grid-template-columns: minmax(0, 1fr); }
  .field--half { grid-column: 1 / -1; }
  .lead-followups { padding: var(--sp-4); }
}
