/* ============================================================
   Form Elements
   Inputs, selects, textareas, buttons, fieldsets, dialogs.
   Matches FormElements.php output.
   ============================================================ */

/* --- Inputs & Textareas --- */

input[type="text"],
input[type="email"],
input[type="tel"],
input[type="number"],
input[type="date"],
input[type="password"],
input[type="url"],
input[type="search"],
textarea,
select {
  width: 100%;
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-base);
  line-height: var(--leading-tight);
  border: 0.0625rem solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-bg);
  transition: border-color var(--transition), box-shadow var(--transition);
}

/* Pflichtfelder dezent hervorheben: etwas dunklerer Rahmen als optionale Felder.
   Bewusst VOR :focus und :user-invalid (gleiche Spezifität, beide später im
   File) → Fokus- und Fehler-Status gewinnen weiterhin. */
input:required,
textarea:required,
select:required {
  border-color: var(--color-border-dark);
}

input:focus,
textarea:focus,
select:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 0.1875rem color-mix(in srgb, var(--color-primary) 20%, transparent);
}

textarea {
  resize: vertical;
  min-height: 6rem;
}

select {
  cursor: pointer;
}

/* --- Labels --- */

label {
  display: block;
  font-size: var(--text-sm);
  font-weight: 500;
  margin-block-end: var(--space-1);
  color: var(--color-text);
}

/* Label + input stacking — gilt für Legacy-Forms ohne .field-Wrapper.
   Innerhalb .field wird das im .field-Block weiter unten überschrieben,
   damit nicht doppelt mit form-gap addiert wird. */
label + input,
label + select,
label + textarea {
  margin-block-end: var(--gap-inline);
}

/* Wrapping label (checkbox/radio) */
label:has(input[type="checkbox"]),
label:has(input[type="radio"]) {
  font-weight: 400;
  cursor: pointer;
  margin-block-end: var(--space-3);
}

/* --- .field-Wrapper (FormElements::field/textarea/select/property_select) ---
   Gruppiert Label + Input als visuelles Paar. Der äußere Form-Container kann
   beliebig mit flex-gap arbeiten, ohne dass Label und Input doppelt auseinander
   gezogen werden. Innerhalb .field reicht die kleine label-margin-bottom
   (var(--space-1)); zusätzliche margin am input/select/textarea wird genullt. */
.field {
  display: block;
}

.field label + input,
.field label + select,
.field label + textarea {
  margin-block-end: 0;
}

input[type="checkbox"],
input[type="radio"] {
  /* WCAG 2.5.5 "Target Size": min. 24x24px Hit-Area. Browser-Default ist
     ~13x13px, deshalb explizit hochsetzen. */
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
  vertical-align: middle;
  accent-color: var(--color-primary);
  margin-inline-end: var(--space-2);
  cursor: pointer;
}

/* Inline-Links im legal-fieldset: vergrößerte Hit-Area + Underline.
   Underline löst gleichzeitig WCAG 1.4.1 "Use of Color" — Link nicht nur
   durch Farbe vom umliegenden Text unterscheidbar. */
fieldset[data-section="legal"] a {
  display: inline-block;
  padding-block: var(--space-1);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

/* --- Fieldsets & Legends --- */

fieldset {
  margin-block-end: var(--gap-block);
}

legend {
  font-family: var(--font-heading), serif;
  font-size: var(--text-lg);
  font-weight: 600;
  margin-block-end: var(--gap-inline);
  color: var(--color-text);
}

/* --- Einheitliches Form-Layout (Single Source of Truth) ---
   Jedes Formular trägt .form-stack (automatisch via FormElements::form(),
   sonst explizit am <form>) → konsistenter Feldabstand UNABHÄNGIG vom Kontext
   (Dialog / main.narrow-Seite / normale Section). Ersetzt die früheren
   kontextabhängigen Regeln (dialog form / main.narrow form:has(fieldset) /
   section.narrow form). NICHT auf .leadgenerator_form / #property-search-form
   (eigene Layouts). */
.form-stack {
  display: flex;
  flex-direction: column;
  gap: var(--gap-block);
}

/* Inhalts-Gruppen-Fieldsets verhalten sich wie das Form selbst (gleicher Gap).
   Ausgenommen: Legal-Fieldset (eigenes Layout) + [data-step] (Leadgenerator-Steps). */
.form-stack fieldset:not([data-section="legal"]):not([data-step]) {
  display: flex;
  flex-direction: column;
  gap: var(--gap-block);
}

/* Direkte Fieldset-Kinder bringen keinen Eigenabstand mit — der Stack-Gap regelt
   den Abstand (sonst doppelt, z.B. vor dem Submit beim Legal-Fieldset). */
.form-stack > fieldset {
  margin-block-end: 0;
}

/* .narrow statt main.narrow: greift sowohl auf Schmal-Seiten (main.narrow) als
   auch wenn der Kern-Block in einem .narrow-Wrapper steckt (z.B. /kontakt mit
   beigefügten full-bleed-Sections → main wird full-bleed, Formular bleibt narrow). */
.narrow fieldset {
  padding: var(--padding-card);
  background: var(--color-bg-alt);
  border: 0.0625rem solid var(--color-panel-border);
  border-radius: var(--radius);
}

/* Legal-Fieldset: globaler einheitlicher Look — schlicht, kein Card-Background,
   kein Border, kein Padding. Inhalt läuft am Form-Stack mit. Gilt überall
   (main.narrow-Pages + Modals + Section-Forms) damit AGB/Datenschutz/Widerruf
   konsistent dargestellt werden. */
fieldset[data-section="legal"] {
  padding: 0;
  background: transparent;
  border: none;
}

.narrow legend {
  font-size: var(--text-base);
  padding-block-end: var(--space-3);
  margin-block-end: var(--space-3);
  border-bottom: 0.0625rem solid var(--color-border);
  width: 100%;
}

/* Buttons → see 05-buttons.css (.btn / .btn.primary classes) */

/* --- Range inputs (PropertySearch sliders) --- */

fieldset[data-range] {
  margin-block-end: var(--gap-inline);
}

fieldset[data-range] > div:first-of-type {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
  gap: var(--space-2);
  align-items: end;
}

input[type="range"] {
  width: 100%;
  accent-color: var(--color-primary);
}

/* --- Inline select (.select wrapper from FormElements) --- */

.range {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-block-end: var(--space-3);
}

.range input[type="number"] {
  width: 6rem;
}

/* --- Appointment time slots --- */

[data-section="appointments"] .slot {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: var(--space-2);
  margin-block-end: var(--space-3);
}

[data-section="appointments"] .slot label {
  flex: 1;
  min-width: 8rem;
}

[data-section="appointments"] .slot span {
  padding-block-end: var(--space-3);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

[data-section="appointments"] .slot select {
  width: auto;
  min-width: 6rem;
}

/* Wrapper für die alternativen Termine — optisch abgesetzt vom Wunschtermin */
[data-section="appointments"] .alt-appointments {
  margin-block-start: var(--space-4);
  padding: var(--space-4);
  background: var(--color-bg-alt, #f7f7f7);
  border-radius: var(--radius);
}

[data-section="appointments"] .alt-appointments .slot {
  padding-block-end: var(--space-2);
  border-bottom: 1px solid var(--color-border, #e5e5e5);
}

[data-section="appointments"] .alt-appointments .slot:last-of-type {
  border-bottom: 0;
  padding-block-end: 0;
}

/* --- Dialogs --- */


dialog {
  width: min(95vw, 50rem);
  min-height: min(20rem, 80vh);
  max-height: 90vh;
  max-height: 90dvh;
  margin: auto;
  padding: 0;
  border: none;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  opacity: 0;
  transform: translateY(1rem);
  transition: opacity 0.3s, transform 0.3s, height 0.3s,
              display 0.3s allow-discrete,
              overlay 0.3s allow-discrete;
}

dialog[open] {
  opacity: 1;
  transform: translateY(0);
}

@starting-style {
  dialog[open] {
    opacity: 0;
    transform: translateY(1rem);
  }
}

dialog::backdrop {
  background: var(--overlay-bg);
  backdrop-filter: blur(var(--overlay-blur));
  -webkit-backdrop-filter: blur(var(--overlay-blur));
  opacity: 0;
  transition: opacity 0.3s,
              display 0.3s allow-discrete,
              overlay 0.3s allow-discrete;
}

dialog[open]::backdrop {
  opacity: 1;
}

@starting-style {
  dialog[open]::backdrop {
    opacity: 0;
  }
}

dialog > header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--gap-inline) var(--padding-card);
  border-bottom: 0.0625rem solid var(--color-border);
  position: sticky;
  top: 0;
  background: var(--color-bg);
  z-index: 1;
}

dialog > header h2 {
  font-size: var(--text-xl);
  margin: 0;
}

/* Toolbar im Header (Copy + Print + Close) — z.B. bei Legal-Dialogs. */
dialog > header .dialog-tools {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

dialog > header .dialog-tools .btn {
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
}

/* Mobile: Copy + Print im Legal-Dialog ausblenden — der Header ist dort
   zu eng für drei Buttons + Titel. Close-Button bleibt sichtbar. */
@media (max-width: 45rem) {
  dialog > header .dialog-tools [data-copy-modal],
  dialog > header .dialog-tools [data-print-modal] {
    display: none;
  }
}


[data-closes] {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--color-bg-alt);
  font-size: var(--text-xl);
  color: var(--color-text-muted);
  cursor: pointer;
  transition: color var(--transition), background var(--transition);
}

[data-closes]:hover {
  color: var(--color-text-inverse);
  background: var(--color-bg-dark);
}

[data-closes]::before {
  content: '\00d7';
}

dialog > article,
dialog > div {
  padding: var(--padding-card);
  padding-block-end: calc(var(--padding-card) * 2);
  overflow-y: auto;
  max-height: calc(90dvh - 4rem);
}

/* Modal-Form-Layout + Inhalts-Fieldset-Spacing kommen jetzt zentral aus
   .form-stack (siehe oben) — gilt einheitlich für Dialog- und Seiten-Formulare.
   Hier bleiben nur die wirklich dialog-spezifischen Sonderfälle (Submit-Margin
   gegen overflow-Clipping + Legend-Hide im Modal). */

/* Submit-Button im Modal-Form bekommt eigenen unteren Abstand. Hintergrund:
   Bei overflow-y:auto Containern ignorieren Chromium/Firefox bekanntermaßen
   das padding-block-end des Containers im scrollbaren Bereich — der letzte
   Inhalt klebt am unteren Rand, sobald gescrollt werden muss. Vor allem im
   Landscape-Modus mit knapper viewport-Höhe sichtbar. Margin am Button
   gehört zum scrollbaren Inhalt und wird zuverlässig dargestellt. */
dialog form button[type="submit"] {
  margin-block-end: var(--space-3);
}

/* In Modals dupliziert das Form-legend in der Regel den Dialog-Header.
   Visuell ausblenden, semantisch (für Screen-Reader) reicht das h2 im header. */
dialog form fieldset > legend {
  display: none;
}

/* --- Validation states --- */

/* :user-invalid statt des früheren :invalid:not(:placeholder-shown)-Hacks:
   markiert ein ungültiges Feld erst NACH User-Interaktion (Fokus + Verlassen /
   Eingabe) rot — beim Laden also nie, und unabhängig davon ob ein Placeholder
   gesetzt ist. Behebt das Problem, dass Pflichtfelder ohne Placeholder sofort
   rot waren. */
input:user-invalid,
textarea:user-invalid,
select:user-invalid {
  border-color: var(--color-error);
}

[role="alert"] {
  color: var(--color-error);
  font-weight: 500;
}

/* --- AJAX Form-Result (vom forms.js dynamisch befüllt) ---
   Markup vom zentralen FormElements::form()-Renderer:
   <p class="form-result" hidden></p> → wird sichtbar mit .success oder .error Klasse */

.form-result {
  margin-block-start: var(--gap-inline);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius);
  font-size: var(--text-sm);
  font-weight: 500;
}

.form-result.success {
  background: color-mix(in srgb, var(--color-success) 10%, transparent);
  color: var(--color-success);
  border: 0.0625rem solid var(--color-success);
}

.form-result.error {
  background: color-mix(in srgb, var(--color-error) 10%, transparent);
  color: var(--color-error);
  border: 0.0625rem solid var(--color-error);
}
