/* ===========================================================================
   forms.css - EINE Quelle für alle Formulare (Frontend + Admin)
   ---------------------------------------------------------------------------
   Anlass (Dennis, 23.07.2026): "wir brauchen einheitliche formulare!"
   Vorher liefen drei Welten nebeneinander, die dasselbe leisteten und dabei
   auseinanderdrifteten:
     .db-field   (dashboard.css) - Termin anlegen/bearbeiten
     .auth-field (auth.css)      - Login, Registrierung, Mein Konto
     .ee-field   (lokal in admin/event-edit.php) - Admin-Terminbearbeitung
   Jede Ergänzung musste dreimal gemacht werden; wurde eine vergessen, fiel das
   Feld lautlos auf Browser-Vorgaben zurück (genau so verschwanden tel/email/
   number aus der Breitenregel).

   Diese Datei ist ab sofort die einzige Stelle, an der Formularfelder gestaltet
   werden. Die drei Klassennamen bleiben als Einstiegspunkte bestehen - das
   Markup musste dafür nicht angefasst werden -, teilen sich hier aber dieselben
   Deklarationen. Wer ein Feld ändert, ändert es für alle Formulare.

   Reihenfolge beim Einbinden: NACH components.css, VOR dashboard.css/auth.css
   (die dürfen einzelne Werte bewusst überschreiben, tun es aber nicht mehr für
   die Basis). Im Admin direkt nach admin.css.

   Schriftgrößen laufen über die --fs-*-Token, damit der A-A-A-Schalter im
   Header greift (WCAG 1.4.4). Die Festwerte hinter den Token sind reine
   Sicherheitsnetze, KEINE Admin-Sonderregel: Der Admin-Head lädt tokens.css seit
   dem 30.07.2026 mit (admin/_head.php), die Token lösen dort also ebenso auf.
   Der frühere Kommentar behauptete das Gegenteil ("Der Admin lädt tokens.css
   nicht - deshalb ... im Admin stabil") - genau diese Annahme hatte dazu geführt,
   dass admin.css Token OHNE Fallback nutzte und der primäre Admin-Knopf mit
   weißer Schrift auf transparenter Fläche stand (Master-Review 30.07.2026).
   =========================================================================== */

:root {
  /* Eingetragene Werte: dunkel und gut lesbar. Ein Formularwert ist Inhalt,
     kein Hinweis - er darf nie wie ein Platzhalter aussehen. 15,3:1 auf Weiß. */
  --form-value: var(--text-body);
  /* Platzhalter: klar heller als der Wert, aber noch lesbar (4,64:1 - über der
     4,5:1-Schwelle für Fließtext). Vorher stand hier gar nichts, also entschied
     der Browser: Chrome #757575, Safari und Firefox abweichend - dieselbe Seite
     sah je nach Browser anders aus. */
  --form-placeholder: var(--text-soft);
  --form-line: #e3e7ee;
  --form-line-strong: var(--border-2);
  --form-hint: #5f6b78;          /* 5,44:1 auf Weiß */
  --form-navy: var(--brand-navy);
  --form-gold: var(--brand-gold);
  --form-gold-soft: #FFF7E3;   /* helle Kachel (wie .portal-mfa__ic "Konto absichern") */
  --form-radius: 10px;
  --form-pad-y: 12px;
  --form-pad-x: 14px;
}

/* ---------------------------------------------------------------------------
   1 · Feld-Container
   --------------------------------------------------------------------------- */
.db-field,
.auth-field,
.adm-field { margin: 0 0 16px; }

/* ---------------------------------------------------------------------------
   2 · Beschriftung
   Zweite Ebene (> div >) mitnehmen: zweispaltige Zeilen legen die Felder in
   eigene Container, das Label sitzt dann eine Ebene tiefer.
   --------------------------------------------------------------------------- */
.db-field label,
.db-field > div > label,
.auth-field label,
.auth-field > div > label,
.adm-field label,
.adm-field > div > label {
  display: block;
  /* Feldüberschriften standen auf 0,92 rem und waren damit KLEINER als der Eingabetext (1 rem),
     den sie benennen - dadurch wirkten sie untergeordnet statt führend (Dennis 28.07.2026).
     Jetzt auf Fließtextgröße und in Brand-Navy, wie die übrigen Überschriften. */
  font-size: var(--fs-md, 1.02rem);
  font-weight: 700;
  color: var(--brand-navy);
  margin: 0 0 6px;
  line-height: 1.35;
}

/* Pflicht-Sternchen und der graue Zusatz "(optional)" in der Beschriftung */
.db-field label .db-req,
.auth-field label .db-req,
.adm-field label .db-req { color: #a32c22; }
.db-hint-inline { font-weight: 400; color: var(--form-hint); }

/* ---------------------------------------------------------------------------
   3 · Eingabefelder
   Die Typenliste ist bewusst vollständig - fehlt ein Typ, fällt das Feld ohne
   Fehlermeldung auf die Browser-Standardbreite zurück und wirkt winzig.
   --------------------------------------------------------------------------- */
.db-field input[type="text"],
.db-field input[type="email"],
.db-field input[type="password"],
.db-field input[type="tel"],
.db-field input[type="url"],
.db-field input[type="number"],
.db-field input[type="search"],
.db-field input[type="date"],
.db-field input[type="time"],
.db-field input[type="datetime-local"],
.db-field select,
.db-field textarea,
.auth-field input[type="text"],
.auth-field input[type="email"],
.auth-field input[type="password"],
.auth-field input[type="tel"],
.auth-field input[type="url"],
.auth-field input[type="number"],
.auth-field input[type="search"],
.auth-field input[type="date"],
.auth-field input[type="time"],
.auth-field input[type="datetime-local"],
.auth-field select,
.auth-field textarea,
.adm-field input[type="text"],
.adm-field input[type="email"],
.adm-field input[type="password"],
.adm-field input[type="tel"],
.adm-field input[type="url"],
.adm-field input[type="number"],
.adm-field input[type="search"],
.adm-field input[type="date"],
.adm-field input[type="time"],
.adm-field input[type="datetime-local"],
.adm-field select,
.adm-field textarea {
  width: 100%;
  box-sizing: border-box;
  padding: var(--form-pad-y) var(--form-pad-x);
  /* 1,02rem = 16,3px: bleibt über der 16px-Schwelle, ab der iOS beim Fokus in
     das Feld hineinzoomt - und skaliert trotzdem mit dem A-A-A-Schalter. */
  font-size: var(--fs-md, 1.02rem);
  font-family: inherit;
  line-height: 1.4;
  color: var(--form-value);
  background: var(--surface-0);
  border: 1px solid var(--form-line);
  border-radius: var(--form-radius);
  -webkit-appearance: none;
  appearance: none;
}

.db-field textarea,
.auth-field textarea,
.adm-field textarea { min-height: 110px; resize: vertical; }

/* Platzhalter - siehe --form-placeholder oben. */
.db-field ::placeholder,
.auth-field ::placeholder,
.adm-field ::placeholder { color: var(--form-placeholder); opacity: 1; }

/* Ein Auswahlfeld, das noch auf "Bitte wählen …" steht, ist inhaltlich ein
   Platzhalter - also wird es auch so dargestellt. Greift über :invalid nur bei
   required-Feldern mit leerem Wert; echte Vorauswahlen wie "Alle" bei der
   Zielgruppe bleiben in der dunklen Wertfarbe. */
.db-field select:invalid,
.auth-field select:invalid,
.adm-field select:invalid { color: var(--form-placeholder); }
.db-field select:invalid option,
.auth-field select:invalid option,
.adm-field select:invalid option { color: var(--form-value); }

.db-field input:focus,
.db-field select:focus,
.db-field textarea:focus,
.auth-field input:focus,
.auth-field select:focus,
.auth-field textarea:focus,
.adm-field input:focus,
.adm-field select:focus,
.adm-field textarea:focus {
  outline: none;
  border-color: var(--form-navy);
  box-shadow: 0 0 0 3px rgba(1, 66, 106, 0.14);
}

/* Fehlerhafte Felder nach dem Absenden (aria-invalid setzen die Formulare). */
.db-field [aria-invalid="true"],
.auth-field [aria-invalid="true"],
.adm-field [aria-invalid="true"] { border-color: var(--color-error); }

/* Zahlenfelder ohne Spinner - die Pfeilchen sind auf Mobilgeräten unbrauchbar
   klein und verkürzen das Eingabefeld. */
.db-field input[type="number"],
.auth-field input[type="number"],
.adm-field input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
.db-field input[type="number"]::-webkit-outer-spin-button,
.db-field input[type="number"]::-webkit-inner-spin-button,
.auth-field input[type="number"]::-webkit-outer-spin-button,
.auth-field input[type="number"]::-webkit-inner-spin-button,
.adm-field input[type="number"]::-webkit-outer-spin-button,
.adm-field input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* ---------------------------------------------------------------------------
   4 · Hilfetext unter dem Feld
   --------------------------------------------------------------------------- */
.db-field .db-hint,
.db-field > div > .db-hint,
.auth-field .auth-hint,
.auth-field > div > .auth-hint,
.auth-field .db-hint,
.adm-field .db-hint,
.adm-field > div > .db-hint {
  display: block;
  margin: 6px 0 0;
  font-size: var(--fs-xs, 0.82rem);
  line-height: 1.5;
  color: var(--form-hint);
}

/* ---------------------------------------------------------------------------
   5 · Zwei Felder nebeneinander (z. B. Uhrzeit von/bis, Telefon/E-Mail)
   Mobile First: unter 540px gestapelt.
   --------------------------------------------------------------------------- */
.db-grid2 { display: grid; grid-template-columns: 1fr; gap: 14px 16px; }
@media (min-width: 540px) {
  .db-grid2 { grid-template-columns: 1fr 1fr; }
}

/* ---------------------------------------------------------------------------
   6 · Abschnitts-Trenner in langen Formularen
   Die Ziffer ist keine Dekoration: Wer einen Termin einstellt oder sein Konto
   pflegt, arbeitet eine Reihenfolge ab und sieht so, wo er steht.

   Gold mit Navy-Ziffer (Dennis, 23.07.2026) - dasselbe Paar wie auf der
   Datumskachel der Terminseite, 6,5:1 Kontrast.

   .db-sec__t ist im Markup ein echtes Überschriften-Element (h3), damit die
   Abschnitte auch beim Navigieren mit Screenreader in der Gliederung stehen.
   --------------------------------------------------------------------------- */
.db-sec {
  display: flex;
  align-items: center;
  gap: 12px;
  /* Der Abstand nach oben trennt zwei Abschnitte, der nach unten bindet die
     Überschrift an ihre Felder - deshalb oben deutlich mehr. */
  margin: 40px 0 18px;
}
/* Erster Abschnitt direkt unter dem Karten-Titel: kein doppelter Abstand.
   Bewusst als eigene Klasse statt :first-child - die Formulare beginnen mit
   einem versteckten CSRF-Feld, wodurch :first-child je nach Seite mal griff
   und mal nicht (in "Mein Konto" fehlte dadurch der Abstand komplett). */
/* Erster Abschnitt: weniger als zwischen zwei Abschnitten, aber genug Luft zum
   Karten-Titel darüber - direkt darunter geklebt wirkt er wie dessen Unterzeile. */
.db-sec--first { margin-top: 18px; }
/* Die Überschrift trägt die Ziffer in sich (siehe nb_form_sec() in
   includes/form-helpers.php) - deshalb ist sie selbst der Flex-Container. */
.db-sec__t {
  flex: 0 1 auto;
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  font-family: var(--font-display, 'Literata', Georgia, 'Times New Roman', serif);
  /* Eine Stufe unter dem Karten-Kopf, aber klar über Fließtext. Die goldene Kachel
     davor trägt inzwischen einen Teil der Aufmerksamkeit - deshalb reicht --fs-lg
     wieder, wo vorher --fs-xl nötig schien (Dennis 23.07.2026: "sehr groß"). */
  font-size: var(--fs-lg, 1.18rem);
  font-weight: 600;
  line-height: 1.25;
  color: var(--form-navy);
}
.db-sec__n {
  /* Die Kachel wächst mit der Ziffer mit - sonst sprengt diese sie auf Stufe "A+ +"
     des Schriftgrößenschalters. */
  flex: 0 0 auto;
  width: calc(30px * var(--fs-scale, 1));
  height: calc(30px * var(--fs-scale, 1));
  border-radius: 50%;
  /* Weiche, helle Kachel statt Vollgold (Dennis 23.07.2026, Variante C) - dieselbe
     Optik wie die "Konto absichern"-Box (.portal-mfa__ic): heller Grund #fff7e0.
     Die ZIFFER bleibt Navy (9,87:1 - lesbar, weil sie eine Reihenfolge trägt);
     das SYMBOL läuft in Röstbraun (siehe .db-sec__n--icon). */
  background: var(--form-gold-soft);
  color: var(--form-navy);
  /* Die Ziffer läuft nicht in der Display-Schrift und nicht in der Größe der
     Überschrift mit: in der Kachel soll sie kompakt sitzen, nicht sie sprengen. */
  font-family: var(--font-body, 'DM Sans', -apple-system, sans-serif);
  font-size: var(--fs-sm, 0.92rem);
  font-weight: 700;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Symbol statt Ziffer: abgerundetes Quadrat statt Kreis - so ist auf einen Blick
   erkennbar, ob ein Abschnitt Teil einer Reihenfolge ist (Kreis mit Nummer) oder
   ein eigenständiger Bereich (Symbol). Icon in --gold-deep (#806400) - dasselbe
   dunkle Oliv-Gold, mit dem auch die Gemeinde-Icons (.gem-card__ic/.gem-tip__ic)
   gezeichnet sind (Wunsch Dennis 23.07.2026). Auf der hellen Kachel 5,25:1. */
.db-sec__n--icon { border-radius: 9px; color: var(--gold-deep); }
.db-sec__n--icon > svg {
  width: calc(17px * var(--fs-scale, 1));
  height: calc(17px * var(--fs-scale, 1));
  display: block;
}
.db-sec__x { min-width: 0; }
.db-sec__l {
  flex: 1 1 auto;
  height: 1px;
  background: linear-gradient(90deg, #E3E7EE, transparent);
}

/* Kopf einer ganzen Karte (z. B. "Meine Veranstaltungen", "Passwort ändern") - eine
   Stufe über den Abschnitts-Köpfen, die innerhalb einer Karte stehen. Vorher hatte
   jede Karte im Kundenbereich ihre eigene Größe und Schrift: das Dashboard 1,02rem
   in DM Sans, "Mein Konto" 1,38rem in Literata, das Termin-Formular 1,3rem. */
.db-sec--card { margin: 0 0 20px; }
/* Im Karten-Kopf ist die border-bottom die Trennlinie - der Gradient-Stummel des
   Formular-Abschnitts (db-sec__l) wäre daneben eine zweite, halbe Linie. Weg damit.
   Die nummerierten Formular-Abschnitte (.db-sec ohne --card) behalten ihren Stummel. */
.db-sec--card .db-sec__l { display: none; }
/* Sitzt der Kopf direkt in einer .card, bringt er deren Innenabstand selbst mit: die
   Karte hat keinen eigenen (das leistete zuvor .card-title). Ohne diese Regel klebte
   "Meine Veranstaltungen" am Kartenrand und die goldene Kachel ragte heraus.
   Seitenabstand = var(--sp-6), damit der Kopf auf die Textkante der .portal-pad-Karten trifft. */
.card > .db-sec--card {
  margin: 0;
  padding: 18px var(--sp-6, 24px) 14px;
  border-bottom: 1px solid var(--border-1);
}
/* Karten MIT eigenem Innenabstand (.portal-pad): dessen Polster liegt sonst NOCHMAL über und
   neben dem Kopf (gemessen: 21px Luft oben, 24px Extra-Einzug, Fehler von mir am 23.07.2026).
   Negative Ränder ziehen den Kopf an die Kartenkanten - dann sitzt er bündig wie bei
   .portal-list. Der Inhalt darunter hält über die Bodenkante seinen Abstand. */
.portal-pad > .db-sec--card {
  margin: calc(-1 * var(--sp-5, 20px)) calc(-1 * var(--sp-6, 24px)) var(--sp-4, 16px);
}
/* Der Listen-Inhalt der .portal-list-Karte auf dieselbe Textkante (sp-6) wie der Kopf -
   sonst startet der Kopf bei 24px, der Text darunter bei 16px. */
.portal-list > .card-body { padding: var(--sp-4, 16px) var(--sp-6, 24px); }
.db-sec--card .db-sec__t { font-size: var(--fs-xl, 1.38rem); }
.db-sec--card .db-sec__n {
  width: calc(34px * var(--fs-scale, 1));
  height: calc(34px * var(--fs-scale, 1));
}
.db-sec--card .db-sec__n--icon > svg {
  width: calc(19px * var(--fs-scale, 1));
  height: calc(19px * var(--fs-scale, 1));
}

@media (max-width: 560px) {
  .db-sec { margin: 32px 0 16px; gap: 10px; }
  .db-sec--card { margin: 0 0 16px; }
  .db-sec__t { gap: 10px; }
}

/* ---------------------------------------------------------------------------
   7 · Ankreuzfelder in einer Zeile mit ihrer Beschriftung
   Ersetzt die style="display:flex;align-items:center;…"-Wiederholungen, die in
   jedem Formular einzeln standen.
   --------------------------------------------------------------------------- */
/* Die Selektoren tragen den Feld-Kontext mit: ".db-field label { display:block }"
   (Spezifität 0,1,1) schlägt ein blosses ".db-check" (0,1,0) und würde die Zeile
   wieder umbrechen lassen - die Checkbox klebte dann am Text. */
.db-check,
.db-field label.db-check,
.auth-field label.db-check,
.adm-field label.db-check {
  display: flex;
  align-items: center;
  gap: 9px;
  font-weight: 400;
  font-size: var(--fs-md, 1.02rem);
  margin: 2px 0 8px;
  cursor: pointer;
}
.db-check input[type="checkbox"] {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--form-navy);
}

/* --- Formatier-Editor (assets/js/rte.js) ---
   Optik am Newsletter-Editor im Backend orientiert: gestaltete Symbolknöpfe, Gruppierung mit
   Trennern und ein sichtbarer aktiver Zustand. Ohne JavaScript bleibt das textarea sichtbar -
   deshalb wird es erst per Klasse versteckt, die das Skript selbst setzt. */
.rte {
  border: 1px solid var(--border-1); border-radius: var(--radius-md, 12px);
  background: var(--surface-0); overflow: hidden;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.rte:focus-within { border-color: var(--brand-navy); box-shadow: 0 0 0 3px rgba(1, 66, 106, .10); }
.rte__leiste {
  display: flex; align-items: center; gap: 2px; padding: 7px 8px; flex-wrap: wrap;
  background: linear-gradient(var(--surface-0), #F6F7F9);
  border-bottom: 1px solid var(--border-1);
}
.rte__trenner { width: 1px; height: 20px; background: var(--border-1); margin: 0 5px; }
.rte__b {
  width: 32px; height: 32px; padding: 0; border: 0; border-radius: var(--radius-xs, 6px);
  background: transparent; color: var(--text-muted); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .12s ease, color .12s ease;
}
.rte__b svg { width: 18px; height: 18px; }
.rte__b:hover { background: #e7eef5; color: var(--brand-navy); }
.rte__b:focus-visible { outline: 2px solid var(--brand-gold); outline-offset: 1px; }
/* Aktiver Zustand - zeigt, ob der Cursor gerade in fettem/kursivem Text steht. */
.rte__b.is-an { background: var(--brand-navy); color: var(--text-on-brand); }

/* CI-Farbknöpfe: das "A" trägt die Farbe, die es setzt - wie im Newsletter-Editor. */
.rte__b--farbe { font: 800 15px var(--font-body); }
.rte__b--navy { color: var(--brand-navy); }
.rte__b--gold { color: var(--business); }
.rte__b--mark { color: var(--business-text); background: var(--brand-gold); }
.rte__b--navy:hover { background: #e7eef5; color: var(--brand-navy); }
.rte__b--gold:hover { background: #FFF7E3; color: var(--business); }
.rte__b--mark:hover { background: #ffd94a; color: var(--business-text); }
.rte__b--navy.is-an, .rte__b--gold.is-an { background: var(--brand-navy); color: var(--text-on-brand); }
.rte__b--mark.is-an { background: var(--brand-gold); color: var(--business-text); box-shadow: inset 0 0 0 2px var(--brand-navy); }
.rte__b.is-an:hover { background: #02507e; color: var(--text-on-brand); }
.rte__feld {
  min-height: 160px; padding: 14px 16px; line-height: 1.65;
  font: 400 calc(1rem * var(--fs-scale)) var(--font-body); color: var(--text-body);
  overflow-wrap: break-word;
}
.rte__feld:focus { outline: none; }
/* base.css setzt global list-style:none - im Editor sollen Aufzählungszeichen sichtbar sein,
   sonst sieht eine Liste aus wie eingerueckter Text. */
.rte__feld ul, .rte__feld ol { margin: 8px 0 8px 22px; padding-left: 18px; }
.rte__feld ul { list-style: disc; }
.rte__feld ol { list-style: decimal; }
.rte__feld li { margin-bottom: 3px; }
.rte__feld strong { font-weight: 700; }
.rte__feld .nb-navy, .rte__feld .nb-gold, .rte__feld .nb-mark { border-radius: 2px; }
.rte__feld:empty::before { content: attr(data-platzhalter); color: var(--text-muted); }
textarea.rte__quelle { display: none; }

/* Kontrollkästchen und Auswahlknöpfe stehen in base.css - sie werden auf Seiten gebraucht,
   die forms.css gar nicht laden (Kalender-Abo, Newsletter, Filterleiste der Startseite). */
