/* Bauteile des CRM: Knopf, Karte, Meldung, Liste, Tabelle, Feldgruppe,
   Werkzeugleiste, Leer-Zustand, Kopierfeld, Zustandsbalken.

   Kennt keine einzelne Seite. Wer hier eine Regel für genau eine Maske
   unterbringen will, hat sich vertan: das gehört in die Feature-CSS.
   Farben kommen ausschließlich aus tokens.css, Ebene 2. */

/* --- Knopf ---------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 2.5rem;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  cursor: pointer;
  padding: .5rem 1.2rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--txt-md);
  line-height: 1.2;
  text-decoration: none;
  text-align: center;
  transition: filter var(--tempo), background var(--tempo), border-color var(--tempo);
}
.btn:active { transform: translateY(1px); }

.btn-primary { background: var(--akzent); color: var(--akzent-text); }
.btn-primary:hover { filter: brightness(1.08); color: var(--akzent-text); }

.btn-secondary { background: var(--zweit); color: var(--zweit-text); }
.btn-secondary:hover { filter: brightness(1.15); color: var(--zweit-text); }

.btn-ghost { background: transparent; color: var(--text); border-color: var(--linie-feld); }
.btn-ghost:hover { background: var(--flaeche-2); color: var(--text); }

/* Löschen, sperren, absagen. Rot erst am Knopf, nicht schon in der Liste. */
.btn-gefahr { background: transparent; color: var(--gefahr); border-color: var(--gefahr); }
.btn-gefahr:hover { background: var(--gefahr-bg); color: var(--gefahr); }

.btn-block { display: flex; width: 100%; }
.btn-sm { min-height: 2rem; padding: .3rem .8rem; font-size: var(--txt-sm); }

/* Ein Knopf, der erst nach kurzem Halten ausloest (static/lange-druecken.js).
   Die Fuellung ist der Hintergrund des Knopfes selbst und liegt damit hinter
   der Schrift; ein ::after darueber wuerde die Beschriftung verdecken, genau
   in dem Moment, in dem man sie lesen will.

   `-webkit-touch-callout` und `user-select`: langes Druecken auf einen Link
   markiert sonst den Text oder oeffnet die Vorschau des Systems. */
.halten { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
.halten-laeuft {
  background-image: linear-gradient(to right, var(--akzent-leise) 0 100%);
  background-repeat: no-repeat;
  background-size: 0 100%;
  animation: halten-fuellen .5s linear forwards;
}
@keyframes halten-fuellen { to { background-size: 100% 100%; } }

@media (prefers-reduced-motion: reduce) {
  .halten-laeuft { animation-duration: .01s; }
}

/* --- Karte ---------------------------------------------------------------- */
.card {
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  box-shadow: var(--schatten-2);
  padding: var(--sp-5) var(--sp-5);
  margin-bottom: var(--sp-5);
}
.card > h2:first-child, .card > h3:first-child { margin-top: 0; }
/* Zweiter Teil innerhalb einer Karte: gehört noch dazu, ist aber eine eigene
   Sache. Linie und Luft davor, damit die Knöpfe nicht aneinanderkleben. */
.karten-teil {
  margin-top: var(--sp-4);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--linie);
}
.karten-teil > :first-child { margin-top: 0; }
.card h2 { font-size: var(--txt-lg); }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--sp-4); }
.card-wide { grid-column: 1 / -1; }
.center-card { max-width: 460px; margin: var(--sp-5) auto; text-align: center; }

/* Kachel: eine Karte, die als Ganzes ein Link ist. Startseite des
   Adminbereichs. Das Raster liefert .cards, am Handy also von selbst
   einspaltig. */
.kachel {
  display: flex; flex-direction: column; gap: var(--sp-1);
  background: var(--flaeche);
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius);
  box-shadow: var(--schatten-1);
  padding: var(--sp-4);
  color: var(--text); text-decoration: none;
}
.kachel:hover {
  background: var(--flaeche-hover);
  box-shadow: var(--schatten-2);
  color: var(--text);
}
.kachel strong { font-size: var(--txt-lg); }
.kachel span { color: var(--text-leise); font-size: var(--txt-sm); }

/* --- Tab-Leiste ------------------------------------------------------------
   Waagerechte Unternavigation innerhalb eines Bereichs (Adminbereich).
   .tour-tabs in static/tour.css ist der aeltere, seitenlokale Zwilling; er
   soll hier aufgehen, sobald die Tagestour ohnehin angefasst wird. */
.tabs {
  display: flex; flex-wrap: wrap; gap: var(--sp-2);
  margin-bottom: var(--sp-5);
}
/* Wechselt die Leiste nicht die Seite, sondern nur den sichtbaren Bereich
   (Buchungsmaske: freie Zeiten / in der Nähe), sind es Knöpfe statt Links. */
.tabs a, .tabs button {
  display: inline-flex; align-items: center; min-height: 2.25rem;
  padding: var(--sp-2) .9rem;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--flaeche-2); color: var(--text);
  text-decoration: none; font-weight: 600; font-size: var(--txt-md);
  font-family: inherit; cursor: pointer;
}
.tabs a:hover, .tabs button:hover { background: var(--flaeche-hover); color: var(--text); }
.tabs a.aktiv, .tabs button.aktiv { background: var(--zweit); color: var(--zweit-text); }

/* --- Seitenkopf ----------------------------------------------------------- */
.page-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4); margin-bottom: var(--sp-5); flex-wrap: wrap;
}
.page-head h1, .page-head h2 { margin: 0; }

/* --- Meldung -------------------------------------------------------------- */
.alert {
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius);
  border-left: var(--balken) solid transparent;
  margin-bottom: var(--sp-4);
  font-weight: 500;
}
.alert-success { background: var(--ok-bg); color: var(--ok); border-left-color: var(--ok); }
.alert-error   { background: var(--gefahr-bg); color: var(--gefahr); border-left-color: var(--gefahr); }
.alert-warnung { background: var(--warnung-bg); color: var(--warnung); border-left-color: var(--warnung); }
.alert-info    { background: var(--info-bg); color: var(--info); border-left-color: var(--info); }

/* --- Marke: Abzeichen und Chip --------------------------------------------
   Abzeichen sagt etwas über den Datensatz (Quelle, Stufe, Zustand).
   Chip ist ein Wert zum Ansehen, kein Zustand. */
.badge {
  display: inline-block;
  background: var(--zustand);
  color: var(--auf-teal);
  border-radius: var(--radius-pill);
  font-size: var(--txt-xs);
  font-weight: 600;
  padding: .1rem .55rem;
}
.badge-quelle { background: var(--flaeche-2); color: var(--text-leise); }
.badge-ok { background: var(--ok-bg); color: var(--ok); }
.badge-warnung { background: var(--warnung-bg); color: var(--warnung); }
.badge-gefahr { background: var(--gefahr-bg); color: var(--gefahr); }
.badge-info { background: var(--info-bg); color: var(--info); }
/* Beta: was noch in Erprobung ist. Signal-Lila der Marke, damit es sich von den
   Zustands-Abzeichen (ok, warnung, gefahr) klar unterscheidet. */
.badge-beta {
  background: var(--flaeche-2); color: var(--marke-signal);
  border: 1px solid var(--marke-signal); text-transform: uppercase;
  letter-spacing: .04em; font-size: var(--txt-xs);
}

.chip {
  display: inline-block;
  background: var(--flaeche-2);
  color: var(--text);
  border-radius: var(--radius-pill);
  font-size: var(--txt-sm);
  padding: .1rem .6rem;
}

/* Chip mit Entfernen-Knopf, z.B. die weiteren Zuständigen am Kunden. Das
   Kreuz sitzt in einem eigenen <form>, weil jedes Entfernen ein eigener POST
   ist; deshalb muss der Chip flex sein, sonst bräche das Form die Zeile um.
   Die Trefferfläche ist bewusst 1.5rem groß: am Handy trifft man ein nacktes
   Kreuz nicht. */
.chip-mit-weg { display: inline-flex; align-items: center; gap: .3rem; }
.chip-mit-weg form { display: inline-flex; margin: 0; }
.chip-weg {
  border: 0; background: none; cursor: pointer; padding: 0;
  min-width: 1.5rem; min-height: 1.5rem;
  color: var(--text-leise); font-size: var(--txt-md); line-height: 1;
}
.chip-weg:hover { color: var(--gefahr); }

/* Die Zeile der weiteren Zuständigen unter der Zuständigkeit am Kunden. */
.zustaendige { margin-bottom: var(--sp-5); }
.zustaendige p { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }

/* --- Zustandsbalken -------------------------------------------------------
   Die eine Zustandssprache des CRM: ein Balken links am Element sagt, was los
   ist. Überall dieselbe Breite, nur die Farbe wechselt. Wird auf Karten,
   Listenzeilen und Wizard-Schritte gelegt. */
.mark { border-left: var(--balken) solid transparent; padding-left: var(--sp-3); }
.mark-hier     { border-left-color: var(--zustand-stark); }  /* hier stehst du */
.mark-zutun    { border-left-color: var(--akzent); }    /* hier ist etwas zu tun */
.mark-achtung  { border-left-color: var(--warnung); }   /* Frist, Lücke */
.mark-fehler   { border-left-color: var(--gefahr); }    /* überfällig, ungültig */
.mark-uebernommen { border-left-color: var(--info); }   /* kommt von woanders her */

/* --- Liste ----------------------------------------------------------------
   Der meistgebrauchte Baustein des CRM und bis jetzt der am wenigsten
   vorhandene: mehrere Templates benutzten eine Listenklasse, die es in keiner
   CSS-Datei gab, und bekamen die Browser-Aufzählung mit Punkten.

   Aufbau je Zeile: links der Inhalt, rechts die Aktionen, darunter optional
   ein aufklappbarer Bereich. Am Handy bricht das um, statt zu quetschen. */
.liste { list-style: none; padding: 0; margin: 0; }
.liste > li {
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--linie);
}
.liste > li:last-child { border-bottom: 0; }
/* Eine leere Liste sagt, was zu tun ist, statt nur "keine Einträge". */
.leer-zeile { color: var(--text-leise); font-size: var(--txt-md); }

/* Kopfzeile eines Eintrags: Titel links, Aktionen rechts. */
.zeile {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); flex-wrap: wrap;
}
.zeile-haupt { flex: 1 1 12rem; min-width: 0; }
.zeile-haupt strong { display: block; }
.zeile-neben { color: var(--text-leise); font-size: var(--txt-sm); }
.zeile form { margin: 0; }

/* Ausgegraut, aber lesbar: abgesagt, inaktiv, erledigt. */
.liste > li.inaktiv .zeile-haupt { opacity: .6; }

/* --- Werkzeugleiste -------------------------------------------------------
   Die Knopfketten, die vorher als <form style="display:inline"> ineinander
   flossen. Ein Container, feste Abstände, bricht am Handy um. */
.werkzeugleiste {
  display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
}
.werkzeugleiste form { margin: 0; display: contents; }

/* --- Kopierfeld -----------------------------------------------------------
   Ein langer Link zum Weitergeben. Vorher ein readonly-Input mit width:100%,
   das die Zeile sprengte. Jetzt Feld und Knöpfe in einer Reihe, das Feld
   schrumpft mit. */
.kopierfeld {
  display: flex; align-items: center; gap: var(--sp-2);
  flex-wrap: wrap; margin-top: var(--sp-2);
}
.kopierfeld form { margin: 0; display: contents; }
.kopierfeld input[readonly] {
  flex: 1 1 12rem; min-width: 0; margin: 0;
  font-family: var(--font-mono);
  font-size: var(--txt-sm);
  background: var(--flaeche-2);
  color: var(--text-leise);
}
.kopierfeld input[readonly]:focus { color: var(--text); }
/* Rückmeldung des Kopieren-Knopfs, gesetzt von static/kopieren.js. */
.kopierfeld button.kopiert { color: var(--ok); border-color: var(--ok); }

/* --- Feldgruppe -----------------------------------------------------------
   Formularabschnitt mit Überschrift, Feldern und einem erklärenden Satz. */
.feldgruppe { margin-bottom: var(--sp-5); }
.feldgruppe > h3 { margin: 0 0 var(--sp-2); font-size: var(--txt-md); }
.feldinfo {
  display: block; margin-top: calc(var(--sp-1) * -1); margin-bottom: var(--sp-2);
  color: var(--text-leise); font-size: var(--txt-sm); font-weight: 400;
}
/* Zahlenfelder brauchen keine volle Zeilenbreite. */
.eingabe-kurz { max-width: 90px; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--sp-4); }
.grid2 .span2 { grid-column: 1 / -1; }
.form-actions { display: flex; gap: var(--sp-2); margin-top: var(--sp-2); flex-wrap: wrap; }
.check { display: flex; align-items: center; gap: var(--sp-2); font-weight: 500; }

/* --- Feld mit Knopf daneben ----------------------------------------------
   Notiz + „Notieren", Wiedervorlage + „+", Besuchsnotiz + „Besucht": dieselbe
   Zeile stand im Projekt fünfmal in fünf Bauarten, mal quetschte sie das Feld
   auf Streichholzbreite, mal schob sie den Knopf in eine eigene Zeile. Das
   Feld nimmt den Platz, der Knopf so viel wie er braucht. */
.feld-zeile { display: flex; gap: var(--sp-2); align-items: flex-end; flex-wrap: wrap; }
/* Was den Satz trägt, wächst; was eine feste Breite hat (Datum, Auswahl,
   Knopf), bleibt so schmal wie nötig. */
.feld-zeile > input[type=text],
.feld-zeile > input[type=email],
.feld-zeile > textarea,
.feld-zeile > .feld-wachs { flex: 1 1 12rem; min-width: 0; margin: 0; }
.feld-zeile > .feld-wachs > input,
.feld-zeile > .feld-wachs > textarea { width: 100%; margin: 0; }
.feld-zeile > input[type=date], .feld-zeile > select { flex: 0 0 auto; width: auto; margin: 0; }
.feld-zeile > textarea { resize: vertical; }
.feld-zeile > label { flex: 0 0 auto; margin: 0; }
.feld-zeile > .btn, .feld-zeile > button { flex: 0 0 auto; }

/* --- Statuskarte am Kunden ------------------------------------------------
   Stufe, Kontaktstand und Zuständigkeit: drei Auswahlfelder, die vorher als
   drei einzelne Leisten über der ersten Karte schwebten, jede mit eigenem
   Abstand. Ein Raster, eine Karte. */
.status-raster { display: grid; gap: var(--sp-3); }
/* Ein Feld je Zelle. In der Statuskarte ist jedes ein eigenes Formular (es
   schickt beim Umschalten ab), in der Karte „Zu klären" liegen alle drei in
   einem gemeinsamen Formular und werden per <div> gruppiert. */
.status-raster > form, .status-raster > div { display: grid; gap: var(--sp-1); margin: 0; }
.status-raster label {
  margin: 0; font-size: var(--txt-sm); font-weight: 500; color: var(--text-leise);
}
.status-raster select, .status-raster input { width: 100%; margin: 0; }
/* Die Spaltenzahl richtet sich nach dem Platz **der Karte**, nicht nach der
   Fensterbreite: eine Media Query auf 640px legt in einer schmalen Karte auf
   einem breiten Schirm drei Spalten nebeneinander und quetscht jedes Feld auf
   Streichholzbreite. `auto-fit` nimmt so viele, wie hineinpassen. */
.status-raster { grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }

/* --- Dateiauswahl ---------------------------------------------------------
   Der native Knopf trägt die Sprache des Browsers („Choose File", grau,
   eckig) und stand mitten zwischen unseren Knöpfen. `datei-feld.js` baut zur
   Laufzeit diese Hülle darum: das Feld selbst bleibt, es wird nur unsichtbar
   und über das Label bedient. Ohne JavaScript bleibt der native Knopf. */
.datei-feld { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.datei-feld input[type=file] {
  position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none;
}
.datei-feld .datei-name {
  font-size: var(--txt-sm); color: var(--text-leise);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}

/* --- Tabelle --------------------------------------------------------------
   Nur da, wo wirklich verglichen wird. Alles andere ist eine Liste. */
.tabelle { width: 100%; border-collapse: collapse; }
.tabelle th, .tabelle td {
  text-align: left; padding: var(--sp-2) var(--sp-1);
  border-bottom: 1px solid var(--linie); vertical-align: top;
}
.tabelle th {
  font-size: var(--txt-sm); color: var(--text-leise); font-weight: 600;
  white-space: nowrap;
}
.tabelle td.zahl, .tabelle th.zahl { text-align: right; font-variant-numeric: tabular-nums; }
.tabelle tr.inaktiv { opacity: .6; }
.tabelle form { margin: 0; }
/* Am Handy darf eine breite Tabelle wandern, statt die Seite zu sprengen. */
.tabelle-scroll { overflow-x: auto; }

/* --- Leer-Zustand ---------------------------------------------------------
   Eine leere Seite ist eine Aufforderung, nicht eine Fehlermeldung. */
.leer { color: var(--text-leise); text-align: center; margin: var(--sp-2) 0; }
.leer-zustand {
  text-align: center; padding: var(--sp-6) var(--sp-4);
  color: var(--text-leise);
}
.leer-zustand p { margin: 0 0 var(--sp-4); }

/* --- Aufklappbereich ------------------------------------------------------ */
.aufklapp > summary {
  cursor: pointer; font-weight: 600; font-size: var(--txt-md);
  padding: var(--sp-1) 0; color: var(--akzent);
}
.aufklapp > summary::marker { color: var(--text-leise); }
.aufklapp[open] > summary { margin-bottom: var(--sp-2); }
.aufklapp form { margin-top: var(--sp-2); }

/* Das Erklärvideo zur Seite hat mit v2.63 die Form gewechselt: aus dem Balken
   über dem Inhalt wurde eine Filmklappe an der Überschrift. Das Styling steht
   jetzt in static/seiten-video.css. */

/* --- Kleine Helfer --------------------------------------------------------
   Bewusst kurz gehalten. Sie ersetzen die style="..."-Attribute, die sich über
   die Templates verteilt hatten. Wer hier etwas Drittes anlegen will, braucht
   in Wahrheit ein Bauteil. */
.form-inline { display: inline-block; margin: 0; }
.versteckt { display: none; }
/* Honigtopf gegen Spam: für Menschen unsichtbar, für Vorleseprogramme da. */
.honigtopf { position: absolute; left: -9999px; }
.reihe { display: flex; gap: var(--sp-2); flex-wrap: wrap; align-items: center; }
.reihe-verteilt {
  display: flex; gap: var(--sp-2); flex-wrap: wrap;
  align-items: center; justify-content: space-between;
}
.eng { max-width: 8rem; }
.normalgewicht { font-weight: 400; }
.abstand-oben { margin-top: var(--sp-2); }
.abstand-unten { margin-bottom: var(--sp-2); }
.abstand-links { margin-left: var(--sp-2); }

/* Wiederholte Bearbeitungszeile, z.B. je Inhalt einer Kundenwebseite. */
.feld-zeile {
  align-items: end;
  border-bottom: 1px solid var(--linie);
  padding-bottom: var(--sp-2);
  margin-bottom: var(--sp-2);
}

/* --- Bestandsklassen ------------------------------------------------------
   Diese Namen standen im Markup, ohne dass es je eine Regel dazu gab: die
   Browser-Aufzählung mit Punkten, ineinanderfließende Knöpfe, ein readonly-Feld
   über die ganze Zeile. Sie bekommen hier die Grundlage der Bausteinfamilie,
   statt dass 13 Templates umgeschrieben werden. Neue Masken benutzen die
   allgemeinen Namen oben (.liste, .zeile, .werkzeugleiste), nicht diese. */

.dok-liste { list-style: none; padding: 0; margin: 0; }
.dok-liste > li {
  display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
  padding: var(--sp-3) 0; border-bottom: 1px solid var(--linie);
}
.dok-liste > li:last-child { border-bottom: 0; }
.dok-liste form { margin: 0; }
/* Die Bearbeiten-Klappe gehört unter die Zeile, nicht in sie hinein. */
.dok-liste > li > details { flex: 1 1 100%; }
.dok-liste > li > details > summary { cursor: pointer; color: var(--akzent); font-weight: 600; }

/* Der Dateiname trägt die Zeile und bekommt sie ganz; Etikett und Knöpfe
   stehen darunter in einer Reihe. Vorher stritten Name, Etikett und zwei
   Knöpfe um dieselben 390 Pixel, und je nach Namenslänge brach es woanders. */
.dok-liste > li > a { flex: 1 1 100%; }

/* Formular, das eine ganze Maske trägt. */
.formular { display: block; }
.formular > .form-actions { margin-top: var(--sp-4); }
.check-form { display: block; }
/* Zwischenüberschrift innerhalb eines Formulars. */
.abschnitt { margin-top: var(--sp-5); font-size: var(--txt-lg); }
.kv { margin-bottom: var(--sp-3); }

.manuell-block, .ordner-block { margin-top: var(--sp-4); }
.manuell-block > summary, .ordner-block > summary {
  cursor: pointer; font-weight: 600; color: var(--akzent);
}

.slot-tage { display: grid; gap: var(--sp-4); }

/* Erstaufnahme-Assistent: Frage mit Optionen und Weiter-Knopf. */
.feldlabel {
  display: block; font-weight: 500; font-size: var(--txt-md); margin-bottom: var(--sp-1);
}
.optionen { display: flex; flex-direction: column; gap: .3rem; }
.opt {
  display: flex; align-items: flex-start; gap: var(--sp-2);
  font-weight: 400; margin: 0; cursor: pointer; line-height: 1.35;
}
.opt input { margin-top: .2rem; flex: 0 0 auto; }
.wizard-nav {
  display: flex; justify-content: space-between; gap: var(--sp-2); margin-top: var(--sp-4);
}
/* Auf Schritt 1 gibt es kein Zurück, der Weiter-Knopf bleibt trotzdem rechts. */
.wizard-nav > .btn:only-child { margin-left: auto; }
/* Zurück steht im Markup **nach** Weiter, damit die Enter-Taste vorwärts geht
   (der Browser nimmt den ersten Submit des Formulars). Gesehen wird trotzdem
   die gewohnte Reihenfolge. */
.wizard-nav .wizard-zurueck { order: -1; }

/* Erstaufnahme: was die jetzige Heizung ueber 10 und 20 Jahre kostet. Rechnet
   beim Tippen mit (erstaufnahme-kosten.js) und ist bewusst abgesetzt: das ist
   die Zahl, die man dem Kunden zeigt. */
.heizkosten {
  background: var(--flaeche-2); border-radius: var(--radius);
  padding: var(--sp-3); margin-top: var(--sp-2);
}
.heizkosten .heizkosten-werte {
  display: grid; grid-template-columns: auto 1fr; gap: var(--sp-1) var(--sp-3);
  margin: var(--sp-2) 0 var(--sp-1);
}
.heizkosten dt { color: var(--text-leise); align-self: baseline; }
.heizkosten dd {
  margin: 0; font-weight: 600; font-size: var(--txt-lg); font-variant-numeric: tabular-nums;
}
.heizkosten p:last-child { margin: 0; }

/* Fotostrecke am Lead. */
.foto-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--sp-3); }
.foto { margin: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.foto img {
  display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--radius-sm); border: 1px solid var(--linie);
  background: var(--flaeche-2);
}
.foto form { margin: 0; }

/* --- Fenster ueber der Seite ----------------------------------------------
   Die Seite darunter soll nicht mitscrollen, solange ein Fenster offen ist
   (Bildergalerie, PDF-Betrachter). Die Regel stand bis v3.14 in galerie.css
   und damit nur auf den drei Seiten, die diese Datei einbinden; sie gilt fuer
   jedes Fenster, deshalb steht sie hier. Der Name bleibt, damit nicht zwei
   Klassen dieselbe Sache tun. */
body.lightbox-offen { overflow: hidden; }

/* --- Mobil ---------------------------------------------------------------- */
@media (max-width: 640px) {
  .card { padding: var(--sp-4); }
  .grid2 { grid-template-columns: 1fr; }
  /* Am Finger bedienbar: 44px ist die Untergrenze. */
  .btn { min-height: 2.75rem; padding: .62rem 1rem; }
  .btn-sm { min-height: 2.25rem; }
  .tabs a { min-height: 2.75rem; }
  /* Aktionen einer Listenzeile stehen unter dem Inhalt, nicht daneben. */
  .zeile { align-items: flex-start; }
  .zeile-haupt { flex: 1 1 100%; }
}
