/* ═══════════════════════════════════════════════════════════════════════════
   form.css — Kontaktformulare (DEV-LOG [120]).

   Geladen von der Seite (nach sections.css) UND vom Bedienfeld (Vorschau im
   Tab „Formulare"). Das Markup baut formRender() in lib/forms.php — für beide
   Orte dasselbe.

   FARBEN KOMMEN AUS DER SEKTION, nicht aus einem Wert: Schrift und Rahmen aus
   --sec-fg, der Button aus seinem Preset. Was der Betreiber am Formular
   einstellt, kommt als --fm-* an der Formularklasse an (formLookCss(), per
   ckStyle()); fehlt eine Variable, gilt der Rückfall hier. Ein Token wird dort
   zu var(--ci-N) — hier steht kein Farbwert (Regel 2).

   SCHRIFTEN KOMMEN AUS DEN ROLLEN: Beschriftung und Eingabe tragen .t-<rolle>
   (typoRolesCss() erzeugt die Regel). Hier steht deshalb keine Schriftgröße.

   Der Mobilblock steht bei BP_MOBILE (566 px) — der Selbsttest hält die Zahl
   mit layout.css, sections.css, carousel.css und nav.js zusammen.
   ═══════════════════════════════════════════════════════════════════════════ */

.fmw { position: relative; min-width: 0; }

.fm {
  display: grid;
  gap: var(--fm-rgap, 1.3rem);
  margin: 0;
}
/* display:grid schlägt [hidden] (DEV-LOG [81]). Seit DEV-LOG [125] bleibt das
   Formular nach dem Absenden stehen (is-sent); die Zeile schützt nur noch
   jeden, der es von Hand ausblendet. */
.fm[hidden] { display: none; }

.fm__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--fm-rgap, 1.3rem) var(--fm-cgap, 1.6rem);
  align-items: end;
}
.fm__row--c2 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }

.fm__f { display: flex; flex-direction: column; gap: 0.4em; min-width: 0; }

/* Beschriftung über dem Feld. Der Stern ist die einzige Kennzeichnung einer
   Pflicht — required am Feld sagt es dem Screenreader. */
.fm__l { display: block; }
.fm__req { margin-left: 0.15em; }

/* DAS FELD. Die Fläche ist leicht getönt aus der Schriftfarbe der Sektion —
   so steht sie auf hellem wie auf dunklem Grund, ohne eigene Farbe. */
.fm__in {
  display: block;
  width: 100%;
  margin: 0;
  padding: 0.7em 0.85em;
  border: 1px solid var(--fm-bc, color-mix(in srgb, var(--sec-fg, currentColor) 35%, transparent));
  border-radius: var(--fm-rad, 0.25rem);
  background: var(--fm-bg, color-mix(in srgb, var(--sec-fg, currentColor) 5%, transparent));
  color: inherit;
  box-shadow: none;
  appearance: none;
}
textarea.fm__in { resize: vertical; min-height: 6em; }
.fm__in::placeholder { color: currentColor; opacity: 0.45; }
.fm__in:focus { outline: none; }
.fm__in:focus-visible {
  outline: 2px solid var(--sec-fg, currentColor);
  outline-offset: 2px;
}
/* Nur eine Linie unten: keine Fläche, kein seitlicher Innenabstand. */
.fm--f-line .fm__in {
  border-width: 0 0 1px;
  border-radius: 0;
  background: var(--fm-bg, transparent);
  padding-inline: 0;
}

/* Haken mit Text daneben. Der Haken nimmt die Schriftfarbe der Sektion. */
.fm__cb { display: flex; align-items: flex-start; gap: 0.65em; cursor: pointer; }
.fm__box {
  flex: none;
  width: 1.1em; height: 1.1em;
  margin: 0.2em 0 0;
  accent-color: var(--sec-fg, currentColor);
}
.fm__cb a, .fm__note a { color: inherit; text-decoration: underline; text-underline-offset: 0.15em; }

.fm__note { margin: 0; opacity: 0.8; }

/* Nur Text (DEV-LOG [122]): eine oder zwei Zeilen, jede in ihrer Rolle. Keine
   eigenen Abstände an der Überschrift - den Abstand zur
   nächsten Zeile gibt das Raster (--fm-rgap). */
.fm__f--head {
  /* Abstand zwischen den beiden Zeilen: Faktor auf 0.2em (--fm-lg). */
  gap: calc(0.2em * var(--fm-lg, 1));
  /* Abstand oben/unten als Faktor auf den Zeilenabstand (DEV-LOG [124]):
     der Rasterabstand steht schon da, der Rand gibt nur die Differenz dazu -
     unter 1× negativ, und das Raster rückt die Nachbarzeile heran. */
  margin-top: calc(var(--fm-rgap, 1.3rem) * (var(--fm-mt, 1) - 1));
  margin-bottom: calc(var(--fm-rgap, 1.3rem) * (var(--fm-mb, 1) - 1));
}
.fm__h { margin: 0; overflow-wrap: anywhere; }
/* Am Element selbst, nicht vererbt: die Bündigkeit der Zelle trifft h1/h2/p
   direkt (:is(.mcell--a-*) :where(p, h1, h2, li), 0,1,0) und schlüge sonst
   die Einstellung hier. */
.fm__f--a-start  .fm__h { text-align: start; }
.fm__f--a-center .fm__h { text-align: center; }
.fm__f--a-end    .fm__h { text-align: end; }

/* Der Button. Bündigkeit der Zelle, nicht des Rasters. */
.fm__act { display: flex; }
.fm__act--start  { justify-content: flex-start; }
.fm__act--center { justify-content: center; }
.fm__act--end    { justify-content: flex-end; }

/* FEHLER: nur die Kontur, kein Text am Feld (Betreiber, DEV-LOG [125]) - ein
   Satz darunter verschob das Raster. Sichtbar steht die Meldung unter dem
   Button; der Satz je Feld bleibt für Screenreader (aria-describedby) und ist
   nur optisch ausgeblendet. Das Rot ist KEIN CI-Token, sondern ein festes
   Signalrot (Vorgabe des Betreibers) - es soll auf jeder Sektionsfarbe gleich
   „Fehler" heißen. */
.fmw { --fm-err: #e3000f; }
.fm__err {
  position: absolute;
  width: 1px; height: 1px;
  margin: 0; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.fm__err[hidden] { display: none; }
/* Die zweite Pixelreihe ist ein Schatten, kein breiterer Rand - der machte
   jedes Feld 2 px höher und schob das Raster. */
.fm__f.is-bad .fm__in { border-color: var(--fm-err); box-shadow: 0 0 0 1px var(--fm-err); }
.fm--f-line .fm__f.is-bad .fm__in { box-shadow: 0 1px 0 var(--fm-err); }
.fm__f.is-bad .fm__box { outline: 2px solid var(--fm-err); outline-offset: 2px; }

.fm__status { margin: 0; font-weight: 600; }
.fm__status[hidden] { display: none; }

/* NACH DEM ABSENDEN (DEV-LOG [125]): Rumpf und Erfolgsmeldung liegen in EINER
   Rasterzelle. Der Rumpf wird nur unsichtbar - er hält die Höhe, das Segment
   springt nicht zusammen. Der Kopf (.fm__row--keep) steht davor und bleibt. */
.fm__stack { display: grid; min-width: 0; }
.fm__stack > * { grid-area: 1 / 1; min-width: 0; }
.fm__body { display: grid; gap: var(--fm-rgap, 1.3rem); }
.fm.is-sent .fm__body { visibility: hidden; }

/* Die Erfolgsmeldung steht an Stelle des Formulars, oben in dessen Fläche. */
.fm__ok { outline: none; align-self: start; }
.fm__ok[hidden] { display: none; }
.fm__ok > p { margin: 0; }
.fm__ok > p + p { margin-top: 0.9em; }

/* DER KÖDER: ausgelagert, nicht display:none — manche Bots überspringen
   unsichtbare Felder und füllen ausgelagerte (DEV-LOG [41]). */
.fm__trap {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* Admin: ein Formular-Modul ohne Preset. */
.fm-empty {
  display: flex; align-items: center; justify-content: center;
  min-height: 6rem;
  border: 1px dashed color-mix(in srgb, var(--sec-fg, currentColor) 40%, transparent);
  opacity: 0.7;
}

@media (max-width: 566px) {
  .fm__row--c2 { grid-template-columns: minmax(0, 1fr); }
}
