/* garten.css — Grundtokens (E1.1).
 *
 * Diese Datei legt KEIN Design fest. Sie legt die NAMEN fest, und zwar aus einem messbaren Grund:
 * mehrere Bausteine aus `_app-template/building-blocks/` (uploader_checklist.css,
 * editor_richtext.css, leadsheet_editor.css) benutzen laut ihrer Dokumentation genau diese
 * Custom Properties — `--border`, `--card-bg`, `--ink`, `--ink-soft`, `--maroon`, `--shadow-sm`.
 * Wer sie hier nicht definiert, bekommt beim ersten kopierten Baustein unsichtbare Rahmen und
 * schwarze Schrift auf schwarzem Grund — und sucht den Fehler im Baustein statt im Fundament.
 *
 * Die WERTE sind Platzhalter (neutrale Grauwerte, ein Gruen als Akzent). Die Gartenpalette
 * entsteht mit den Ansichten ab E3; wer sie festlegt, aendert hier die Werte und sonst nichts.
 * `--maroon` behaelt seinen Baustein-Namen, obwohl im Garten nichts kastanienbraun ist: eine
 * Umbenennung waere eine Abweichung in JEDER kopierten Baustein-CSS und damit ein
 * W21-Ausschlusseintrag je Datei — ein schlechter Tausch fuer einen huebscheren Namen.
 */

:root {
  --ink: #1d2419;         /* Fliesstext */
  --ink-soft: #545e50;    /* Nebentext, Beschriftungen */
  --border: #c4cbbc;      /* Trennlinien, Rahmen */
  --card-bg: #ffffff;     /* Kartenflaechen */
  --maroon: #3c6e35;      /* Akzent-/Aktionsfarbe (Baustein-Name, s. Kopf) */
  --shadow-sm: 0 1px 2px rgba(29, 36, 25, .07), 0 2px 8px rgba(29, 36, 25, .06);
}

/* ↺ 2026-09-18, GESTALT STUFE 1 (docs/draufsicht-entwurf.md §5): DIE PALETTE IST FESTGELEGT.
 * Bis heute standen oben „Platzhalter"; gemessen hob sich eine Karte um 1,08:1 vom Seitengrund
 * ab — im Tageslicht am Telefon ist das keine Karte. Jeder Wert unten ist GERECHNET (WCAG-Formel),
 * nicht nach Augenmass gewaehlt:
 *
 *   Karte gegen Seite       1,17:1  (vorher 1,08)   — die Flaeche selbst
 *   Rahmen gegen Karte      1,66:1  (vorher 1,43)   — die Kante, die sie wirklich traegt
 *   Text        auf Seite  13,6:1
 *   Nebentext   auf Seite   5,8:1  (#545e50; #5c6657 waere auf dem dunkleren Grund auf 5,1 gefallen)
 *   Gruen       auf Seite   5,2:1,  auf Karte 6,1:1
 *   Gruen auf Zeilenknopf   5,0:1
 *
 * KEINE NEUE FARBFAMILIE: alles bleibt Gruen, Grau-Gruen und Weiss. Neu sind nur Helligkeitsstufen
 * davon, und die Warnfarbe, die der Baustein ohnehin verlangt. */
:root {
  --seite: #ebeee6;          /* Seitengrund — getoent, damit Weiss darauf eine Flaeche ist */
  --maroon-hell: #e3ecde;    /* Getoente Akzentflaeche: Zeilenknoepfe, Auswahl */
  --shadow-lg: 0 8px 24px rgba(29, 36, 25, .14);  /* Schwebendes: das Kontomenue */

  /* DIE VIER, DIE DER BAUSTEIN VON DER GAST-APP ERWARTET (user_management.css, gemessen:
   * --erfolg Z. 242/265, --warnung Z. 86/266, --card-bg-2 Z. 390, --accent-ink Z. 402). Ohne sie
   * fiel er auf seine Ersatzwerte zurueck — ein zweites Gruen (#15803d) und ein fremdes Orange
   * (#b45309), ausgerechnet auf den Seiten, die ein neues Mitglied als erstes sieht. */
  --erfolg: #3c6e35;         /* = --maroon; ein Garten hat EIN Gruen */
  --warnung: #8a5a00;        /* Ocker, 5,9:1 auf Weiss */
  --card-bg-2: #f4f6f1;      /* Zweitflaeche IN einer Karte */
  --accent-ink: #ffffff;     /* = --on-maroon */

  /* DIE SCHRIFTSKALA — fuenf Stufen, jede mit einem Zweck. Gemessen stand die App bei NEUN
   * gerenderten Groessen, drei davon Browser-Vorgaben, die nie jemand gewaehlt hat (h2 war auf
   * /beete 24 px und auf /triebe 17,6 px). Eine sechste Stufe braucht einen Zweck, den man
   * hierhin schreiben kann. */
  --schrift-titel: 1.75rem;      /* 28 px — die EINE Ueberschrift der Seite (h1) */
  --schrift-abschnitt: 1.25rem;  /* 20 px — Abschnitte (h2) */
  --schrift-unter: 1.0625rem;    /* 17 px — Unterabschnitte (h3), Einleitungssatz */
  --schrift-text: 1rem;          /* 16 px — Fliesstext, Felder, Knoepfe; darunter zoomt iOS */
  --schrift-klein: .875rem;      /* 14 px — Hinweise, Brotkrume, Beschriftungen */

  /* DIE ABSTANDSSKALA — sechs Stufen. Gemessen waren es 22 verschiedene Werte, manche 1,6 px
   * auseinander: das liest das Auge als Zufall, nicht als Ordnung. */
  --abstand-1: .25rem;   /*  4 px — innerhalb einer Zeile */
  --abstand-2: .5rem;    /*  8 px — zwischen Geschwistern */
  --abstand-3: .75rem;   /* 12 px — Innenrand kleiner Flaechen */
  --abstand-4: 1rem;     /* 16 px — Innenrand von Karten, Seitenrand */
  --abstand-5: 1.5rem;   /* 24 px — zwischen Bloecken */
  --abstand-6: 2rem;     /* 32 px — zwischen Abschnitten */
}

body {
  margin: 0;
  color: var(--ink);
  background: var(--seite);
  font: 16px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* DIE UEBERSCHRIFTEN — bis heute ohne Regel und damit Browser-Vorgabe. Die Baustein-Seiten setzen
 * `.um h1` mit eigener Staffel; das ist spezifischer als `h1` und gewinnt dort, wie es soll. */
h1 { font-size: var(--schrift-titel); line-height: 1.2; letter-spacing: -.01em;
     margin: var(--abstand-2) 0 var(--abstand-4); }
h2 { font-size: var(--schrift-abschnitt); line-height: 1.3; margin: var(--abstand-6) 0 var(--abstand-3); }
h3 { font-size: var(--schrift-unter); line-height: 1.35; margin: var(--abstand-5) 0 var(--abstand-2); }

/* DIE VERWEISE — bis heute ohne jede Regel: gemessen 46 von 138 Verweisen auf /draufsicht in
 * Browser-Blau #0000EE, das zu keinem der Tokens gehoert. Der Unterstrich BLEIBT: an ihm erkennt
 * man einen Verweis im Fliesstext, auch wenn man die Farbe nicht unterscheidet. */
a { color: var(--maroon); text-decoration-thickness: 1px; text-underline-offset: .18em; }
a:hover { text-decoration-thickness: 2px; }
/* ↺ 2026-09-18, KONTRASTWAECHTER: HIER STAND `a:visited { color: var(--maroon); }`, und sie war
 * die unsichtbare Knopfschrift. Tills Fund am Telefon: „Heute im Garten" ganz gruen, die Schrift
 * erst beim Antippen. Gemessen (Chrome, echter Besuch UND erzwungenes :visited, gegen
 * Bildschirmpixel): `a:visited` hat die Spezifitaet (0,1,1) und schlaegt `.um-knopf--haupt`
 * (0,1,0) — jeder BESUCHTE Hauptknopf-Link wurde gruen auf gruen, 1:1, an 16 Vorlagenstellen.
 * Beim Antippen gewann `.um-knopf--haupt:hover` (0,2,0), darum kam die Schrift dann zurueck.
 * Die Regel war UNNOETIG: `a { color }` oben schlaegt das Browser-Violett schon ueber die
 * HERKUNFT (Autor vor Browser), nicht ueber die Spezifitaet — gemessen an 21 Seiten: mit ihr
 * 142 Messungen, in denen ein Verweis nach dem Besuch die Farbe wechselt (auch die Marke, die
 * Gartenkarten und die weissen Wegeknoepfe wurden gruen), ohne sie 0.
 * Eine Zustandsregel auf ein NACKTES Element (a:visited, a:hover, button:focus …), die Farbe
 * setzt, schliesst `tests/test_kontrast_struktur.py` aus; `tests/test_kontrast.py` misst jede
 * Seite im echten Browser, besucht und unbesucht. */

/* ── Dashboard und Gartenseiten (Etappe EG, 2026-09-03) ──────────────────────────────────────
 *
 * DAS IST IMMER NOCH KEIN DESIGN, und der Kopf dieser Datei bleibt gueltig: die Gartenpalette
 * entsteht mit den Ansichten ab E3. Was hier dazukommt, ist die kleinste Menge Layout, ohne die
 * eine Liste von Karten keine Liste von Karten ist — Wichtels Dashboard ist eine Kachelwand, und
 * eine unformatierte <ul> waere nicht „schlicht", sondern eine andere Sache.
 *
 * Alle Regeln benutzen ausschliesslich die Tokens von oben. Wer die Palette festlegt, aendert
 * dort die Werte und hier nichts.
 */
.seiten-wrap { max-width: 46rem; margin: 0 auto; padding: var(--abstand-4); }
.garten-gruppe { margin: var(--abstand-6) 0; }
/* ↺ 2026-09-18 (Gestalt): die Abschnittsueberschrift ist Text-Schwarz und nicht mehr
 * Nebentext-Grau. In Grau las sie sich als Beschriftung, nicht als Gliederung. */
.garten-gruppe h2 { font-size: var(--schrift-abschnitt); color: var(--ink); margin-top: 0; }

.garten-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--abstand-3); }
.garten-karte {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--abstand-2) var(--abstand-4);
  background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--um-radius);
  box-shadow: var(--shadow-sm); padding: var(--abstand-3) var(--abstand-4);
}
.garten-karte__name { flex: 1 1 12rem; font-weight: 600; color: var(--ink); }
.garten-karte__rolle { color: var(--ink-soft); font-size: var(--schrift-klein); }

/* Der Zustand steht als `data-zustand` am Element und nicht als eigene Klasse je Fall: die
 * Fallunterscheidung gehoert in `garten_dashboard.zustand()`, und eine zweite in CSS waere die
 * Stelle, an der „verwaist" irgendwann anders aussieht als es heisst. */
.garten-karte__lage {
  font-size: .8rem; border: 1px solid var(--border); border-radius: 1rem; padding: .1rem .6rem;
}
.garten-karte__lage[data-zustand="gesperrt"] { color: var(--maroon); border-color: var(--maroon); }
.garten-karte__lage[data-zustand="vorbei"] { color: var(--ink-soft); }
.garten-karte--geloescht .garten-karte__name { text-decoration: line-through; }

.garten-form { display: grid; gap: .35rem; max-width: 28rem; }
.garten-form label { margin-top: .75rem; font-weight: 600; }
.feld-frei { font-weight: 400; color: var(--ink-soft); }
.feld-hinweis { margin: .2rem 0 0; font-size: .85rem; color: var(--ink-soft); }
.garten-daten { display: grid; grid-template-columns: max-content 1fr; gap: .25rem 1rem; }
.garten-daten dt { color: var(--ink-soft); }
.garten-daten dd { margin: 0; }
.brotkrume { font-size: var(--schrift-klein); }

/* ────────────────────────────────────────────────────────────────────────────────────────────
 * E3.2 — Beete, Abschnitte, Anker
 *
 * DIESELBEN TOKENS WIE OBEN, keine neuen Farben. Was hier dazukommt, sind vier Bausteine, die es
 * vor E3.2 nicht brauchte: eine Tabelle (Beetliste, Abschnitte, Belegungen), ein Formularfeld mit
 * Beschriftung UND Erklaerung, eine Reihe von Feldern nebeneinander (die Faehigkeits-Schalter je
 * Abschnitt) und der Hinweistext.
 *
 * `.hinweis` traegt in diesen Ansichten mehr als Kosmetik: „noch nicht angeordnet", „geschaetzt",
 * „2 ohne Mass" und „(geerbt)" sind ALLE Aussagen ueber Unsicherheit, und sie muessen sich vom
 * Wert selbst unterscheiden lassen. Ein leeres Feld an derselben Stelle saehe nach einem Fehler
 * aus — das ist der ganze Grund, warum die Vorlagen diese Faelle ausschreiben.
 * ──────────────────────────────────────────────────────────────────────────────────────────── */
.hinweis { color: var(--ink-soft); font-size: var(--schrift-klein); }

.liste { width: 100%; border-collapse: collapse; margin: .75rem 0 1.5rem; }
.liste th, .liste td { text-align: left; padding: .4rem .6rem; border-bottom: 1px solid var(--border); vertical-align: top; }
.liste th { color: var(--ink-soft); font-size: .85rem; font-weight: 600; }
.liste tr.unterzeile td { border-bottom: 1px solid var(--border); background: var(--card-bg); }

.liste-schmal { list-style: none; margin: .5rem 0 1.5rem; padding: 0; display: grid; gap: .35rem; }

.feld { display: grid; gap: .25rem; margin: .75rem 0; }
.feld label { font-weight: 600; }
.feld input, .feld select { padding: .35rem .5rem; border: 1px solid var(--border); border-radius: .3rem; }

.beetform fieldset { border: 1px solid var(--border); border-radius: .5rem; margin: 1rem 0; padding: .5rem 1rem 1rem; }
.beetform legend { font-weight: 600; padding: 0 .35rem; }

.reihe { display: flex; flex-wrap: wrap; align-items: end; gap: .5rem .75rem; margin: .5rem 0; }
.reihe label { display: grid; gap: .2rem; font-size: .85rem; color: var(--ink-soft); }

.flaeche-live { background: var(--card-bg); border: 1px solid var(--border); border-radius: .5rem; padding: .5rem .75rem; }
.flaechen { margin: 1rem 0 1.5rem; }

/* ────────────────────────────────────────────────────────────────────────────────────────────
 * E3.3 — die Draufsicht
 *
 * KEINE NEUEN FARBEN. Die sechs Tokens von oben sind die ganze Palette, und der Kopf dieser
 * Datei sagt: wer sie festlegt, aendert dort die Werte und sonst nichts. Was hier dazukommt,
 * ist Geometrie-Beiwerk (Rahmen, Schraffur, Trefferfeld) und die ERSTEN drei Regeln des Hauses,
 * die nicht Kosmetik sind, sondern Bedienung:
 *
 *   `:focus-visible`  — bis heute hatte diese Datei 0 Fokusregeln. Eine SVG-Flaeche in einem
 *                       <a> ist ohne sichtbaren Fokus mit der Tastatur nicht bedienbar; die
 *                       Zeichnung waere ein Bild mit unsichtbaren Knoepfen darin.
 *   `--um-tap`        — DIE ZAHL DES BAUSTEINS, nicht eine zweite. `user_management.css` fuehrt
 *                       48 px als Tippzielgroesse; sie hier ein zweites Mal zu erfinden waere
 *                       genau der Fall, gegen den W21 gebaut ist. Die eigentliche Arbeit macht
 *                       ohnehin `garten_draufsicht._trefferfeld()` — CSS-Pixel koennen eine
 *                       SVG-Nutzerkoordinate nicht vergroessern, ohne die Form zu verzerren.
 *   `@media (prefers-reduced-motion)` — steht NICHT hier, weil sich in dieser Ansicht nichts
 *                       bewegt. Eine leere Regel „fuer die Vollstaendigkeit" waere eine Zusage
 *                       ohne Gegenstand.
 *
 * DIE SCHRAFFUR IST DIE KENNZEICHNUNG, NICHT DIE FARBE. E3.3 verlangt „sichtbar gekennzeichnet";
 * eine Kennzeichnung, die nur aus einem Farbton besteht, ist fuer niemanden lesbar, der Farben
 * nicht unterscheidet. Sie steht als Muster im SVG und daneben als ausgeschriebener Satz.
 * ──────────────────────────────────────────────────────────────────────────────────────────── */
:root { --um-tap: 48px; }

.draufsicht { margin: .75rem 0; }
.draufsicht__bild {
  display: block; max-width: 100%; height: auto;
  background: var(--card-bg); border: 1px solid var(--border); border-radius: .5rem;
}

/* Beetflaeche, Abschnittsflaeche, Kontur. Die Abschnitte liegen ueber dem Beet und sind nur
 * umrandet — gefuellt verdeckten sie die Aussparung, die das Beet selbst erzeugt (B01). */
.draufsicht__flaeche { fill: var(--card-bg); stroke: var(--ink-soft); stroke-width: 2; }
.draufsicht__abschnitt { fill: none; stroke: var(--border); stroke-width: 2; }
.draufsicht__beet--hervor .draufsicht__flaeche { stroke: var(--maroon); stroke-width: 3; }
.draufsicht__naeherung { stroke: var(--ink-soft); stroke-width: 2; stroke-dasharray: 8 6; }
.draufsicht__schraffur { stroke: var(--ink-soft); stroke-width: 2; }

/* DAS TREFFERFELD IST DURCHSICHTIG UND FAENGT TROTZDEM. `fill: transparent` trifft, `fill: none`
 * nicht — der Unterschied ist der ganze Zweck dieses Rechtecks. */
.draufsicht__treffer { fill: transparent; stroke: none; }

.draufsicht__ziel { cursor: pointer; }
.draufsicht__ziel:hover .draufsicht__flaeche { fill: #eef2ea; }
.draufsicht__ziel:focus-visible { outline: none; }
.draufsicht__ziel:focus-visible .draufsicht__flaeche {
  stroke: var(--maroon); stroke-width: 4;
}

.draufsicht__unterschrift {
  display: flex; flex-wrap: wrap; align-items: center; gap: .35rem .75rem; margin-top: .4rem;
}
.draufsicht__balken {
  display: inline-block; height: .5rem; border: 1px solid var(--ink-soft); border-top: 0;
}
.draufsicht__nord { color: var(--ink-soft); }
.draufsicht__nord line, .draufsicht__nord circle { stroke: var(--ink-soft); stroke-width: 6; fill: var(--ink-soft); }
.draufsicht__nord text { fill: var(--ink-soft); font-size: 26px; text-anchor: middle; }
.draufsicht__satz { flex: 1 1 14rem; }
.draufsicht__marke { display: block; }

.draufsicht-feld { margin: 2rem 0; }
.draufsicht-kacheln {
  list-style: none; margin: .75rem 0 0; padding: 0;
  display: grid; gap: .75rem; grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
}
.draufsicht-kachel {
  background: var(--card-bg); border: 1px solid var(--border); border-radius: .5rem;
  box-shadow: var(--shadow-sm); padding: .6rem .75rem;
}
.draufsicht-kachel__name { margin: 0 0 .35rem; font-weight: 600; }
.draufsicht-kachel .draufsicht__bild { border: 0; border-radius: 0; }
.draufsicht-kachel__weg { display: inline-block; min-height: var(--um-tap); line-height: var(--um-tap); }

/* Der Fokusring der TEXTwege dieser Seite. Er steht hier und nicht global, weil eine globale
 * Fokusregel eine Entscheidung ueber die ganze Oberflaeche waere — und die gehoert Till,
 * nicht diesem Los. Was hier steht, gilt fuer die Wege, die E3.3 selbst baut. */
.draufsicht-feld a:focus-visible, .draufsicht-kachel a:focus-visible {
  outline: 2px solid var(--maroon); outline-offset: 2px;
}


/* ────────────────────────────────────────────────────────────────────────────────────────────
 * UX-WELLE 2 (2026-09-07) — UX-24: KOPFZEILE, KNOEPFE, MELDUNGEN
 *
 * DER BEFUND, GEMESSEN (docs/ux-befunde.md UX-24): diese Datei enthielt **0 Regeln** zu
 * `.kopfzeile`, `.kopfzeile__marke`, `.kopfzeile__wege`, `.kopfzeile__abmelden` — die Kopfzeile
 * jeder Seite war ein Markenlink, drei Textlinks und ein nackter `<button>Abmelden</button>` in
 * einer Zeile. `.um-knopf` lebte NUR in `user_management.css`, und die laden ausschliesslich die
 * Baustein-Seiten: alle „Knoepfe" der App-Seiten waren nackte Links, dieselben Knoepfe sahen auf
 * `/settings/team` fertig aus. Und `.meldungen/.meldung/.meldung--error` waren ebenfalls nicht
 * definiert — eine FEHLERMELDUNG erschien als gewoehnlicher Listenpunkt, von Inhalt nicht zu
 * unterscheiden. Insgesamt **20 benutzte Klassen ohne Regel**.
 *
 * KEIN FRAMEWORK, KEIN JAVASCRIPT. Was hier dazukommt, ist CSS und sonst nichts; die App bleibt
 * bei ihren wenigen Zeilen Skript. Die Klappen aus UX-16/UX-18 sind `<details>`, die Kopfzeile
 * ist eine Flexzeile, das Menue ist keins.
 *
 * DIE FARBEN BLEIBEN DIE SECHS TOKENS VON OBEN. Dazu kommen genau drei, und keines davon ist
 * erfunden: `--border-stark`, `--on-maroon` und `--gefahr` verlangt `user_management.css` in
 * seinem eigenen Kopf ausdruecklich VON DER GAST-APP („CSS-Variablen der Gast-App … und die
 * Zustandsfarben"). Sie fehlten hier — die Baustein-Seiten fielen deshalb bisher auf ihre
 * eingebauten Ersatzwerte zurueck, also auf ein Rot, das mit der Gartenpalette nichts zu tun hat.
 * ──────────────────────────────────────────────────────────────────────────────────────────── */
:root {
  --border-stark: #a9b3a2;   /* Rahmen, der sich vom Hintergrund abheben muss (Knoepfe) */
  --on-maroon: #ffffff;      /* Schrift AUF der Akzentflaeche */
  --gefahr: #a4302a;         /* Loeschen, Entfernen, unwiderrufliche Wege */
  --um-radius: 12px;         /* derselbe Radius wie im Baustein — nicht ein zweiter */
}

/* WOHIN EINE SPRUNGMARKE WIRKLICH SPRINGT. Die Kopfzeile darunter klebt oben (`position: sticky`,
 * gemessen 57 px). Ohne diese Zeile setzt der Browser das Sprungziel auf y = 0 — also HINTER die
 * Kopfzeile: sichtbar bleibt ein Formular ohne seine Ueberschrift. GEMESSEN (2026-09-20, headless
 * Chrome ueber CDP, 375x812, echter Server auf einer Wegwerf-DB), dieselbe Regel einmal mit und
 * einmal ohne Wirkung: `/binderfarben#planen` -> Ziel bei y = 0 (verdeckt) gegen y = 72;
 * `#jahr-2028` -> y = 0 gegen y = 72. Es trifft JEDE Marke der App, nicht nur diese Seite.
 * `:target` steht in `tests/test_ux2_gestalt.py` schon als Zustand (`_ZUSTAENDE`) — der
 * Gestalt-Waechter misst die Seite in Ruhe und laesst diese Regel deshalb richtig liegen. */
:target { scroll-margin-top: 4.5rem; }

/* ── Die Kopfzeile ───────────────────────────────────────────────────────────────────────────
 * Marke links, „Konto" rechts. Sie klebt oben, weil die Beetseite lang ist und der Rueckweg
 * sonst am Ende der Seite steht.
 *
 * ↺ 2026-09-18, GESTALT STUFE 1: EINE ZEILE, AUF JEDER BREITE. Gemessen war sie am Telefon
 * 150 px hoch und kostete mit Titel und Brotkrume 36 % des ersten Bildschirms. `nowrap` ist hier
 * die Zusage: was nicht in eine Zeile passt, gehoert ins Kontomenue und nicht in eine zweite. */
.kopfzeile {
  position: sticky; top: 0; z-index: 30;
  display: flex; flex-wrap: nowrap; align-items: center; justify-content: space-between;
  gap: var(--abstand-4); min-height: 3.5rem;
  /* Marke und Konto stehen ueber der Inhaltsspalte (`.seiten-wrap`, 46rem), nicht an den
   * Fensterraendern — am Telefon wird daraus der gewoehnliche Seitenrand. */
  padding: 0 max(var(--abstand-4), calc((100% - 46rem) / 2));
  background: var(--card-bg); border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
}
.kopfzeile__marke {
  font-weight: 700; font-size: var(--schrift-unter); color: var(--ink); text-decoration: none;
  letter-spacing: .01em;
}
.kopfzeile__marke:hover { color: var(--maroon); }

/* DAS KONTOMENUE. `<details>` statt eines Skripts: es klappt auf, es klappt zu, die Tastatur
 * erreicht es, die Vorlesehilfe nennt es „ausgeklappt". Was es NICHT kann: sich beim Tippen
 * daneben schliessen — dafuer braeuchte es Skript, und das ist die Stufe-1-Grenze. */
.kopfzeile__konto { position: relative; }
.kopfzeile__konto > summary {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; gap: var(--abstand-2);
  min-height: var(--um-tap); padding: 0 var(--abstand-3);
  border: 1px solid var(--border-stark); border-radius: var(--um-radius);
  color: var(--ink-soft);
}
.kopfzeile__konto > summary::-webkit-details-marker { display: none; }
.kopfzeile__konto > summary::after { content: "\25BE"; font-size: .85em; }
.kopfzeile__konto[open] > summary::after { content: "\25B4"; }
/* ↺ 2026-09-18, Kontrastwaechter: die Zustandsregeln der Kopfzeile haengen an KLASSEN
 * (`kopfzeile__konto-knopf`, `kopfzeile__punkt`), nicht mehr an `summary:hover`, `a:hover`,
 * `button:hover` im Kontext. Eine Zustandsregel auf ein nacktes Element erreicht jedes solche
 * Element darunter — auch einen Knopf mit eigener Flaeche, der dann Schrift und Grund aus zwei
 * verschiedenen Regeln bekommt (die Fehlerklasse von `a:visited`, siehe oben bei den Verweisen). */
.kopfzeile__konto-knopf:hover { color: var(--maroon); border-color: var(--maroon); }
.kopfzeile__konto > summary:focus-visible { outline: 2px solid var(--maroon); outline-offset: 2px; }

.kopfzeile__wege {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--abstand-1) var(--abstand-4);
}
/* Im Menue: eine Spalte, schwebend unter dem Knopf, rechtsbuendig. */
.kopfzeile__konto .kopfzeile__wege {
  position: absolute; right: 0; top: calc(100% + var(--abstand-2));
  flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 0;
  min-width: 13rem; padding: var(--abstand-2);
  background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--um-radius);
  box-shadow: var(--shadow-lg);
}
.kopfzeile__wege a {
  color: var(--ink); text-decoration: none;
  display: flex; align-items: center; min-height: var(--um-tap);
  padding: 0 var(--abstand-3); border-radius: .5rem;
}
.kopfzeile__punkt:hover { color: var(--maroon); background: var(--maroon-hell); }
.kopfzeile__abmelden {
  margin: var(--abstand-1) 0 0; padding-top: var(--abstand-1);
  border-top: 1px solid var(--border); display: flex;
}
/* DER ABMELDE-KNOPF IST EIN POST-FORMULAR und bleibt es (ein GET-Abmeldeweg laesst sich als
 * <img src> in eine fremde Seite haengen). Im Menue sieht er aus wie ein Menuepunkt. */
.kopfzeile__abmelden button {
  flex: 1; min-height: var(--um-tap); padding: 0 var(--abstand-3); text-align: left;
  border: 0; border-radius: .5rem;
  background: transparent; color: var(--ink); font: inherit; cursor: pointer;
}

/* ── Meldungen ───────────────────────────────────────────────────────────────────────────────
 * DER TEURE FALL IST `--error`: eine Fehlermeldung, die aussieht wie ein Listenpunkt, ist keine.
 * Die Unterscheidung traegt deshalb NICHT nur die Farbe, sondern auch der linke Balken und die
 * fette Schrift — wer Farben nicht unterscheidet, sieht den Unterschied trotzdem. */
.meldungen { list-style: none; margin: .75rem auto; padding: 0 1rem; max-width: 46rem; }
.meldung {
  border: 1px solid var(--border); border-left: 4px solid var(--ink-soft);
  border-radius: .35rem; background: var(--card-bg);
  padding: .6rem .9rem; margin: .4rem 0;
}
.meldung--error { border-left-color: var(--gefahr); color: var(--gefahr); font-weight: 600; }
.meldung--warning { border-left-color: var(--warnung); font-weight: 600; }
.meldung--success, .meldung--info { border-left-color: var(--maroon); }

/* ── Knoepfe ─────────────────────────────────────────────────────────────────────────────────
 * `.um-knopf` UND `.um-knopf--haupt` STEHEN HIER MIT DEN WERTEN DES BAUSTEINS, und das ist eine
 * bewusste Entscheidung mit zwei Alternativen dahinter:
 *
 *   (a) `user_management.css` in `base.html` mitladen — dann traegt JEDE App-Seite ein
 *       Stylesheet mit ueber 400 Zeilen fuer Dialoge, Schalter und Rechtetabellen, die es hier
 *       nicht gibt, und jede Aenderung am Baustein aendert das Aussehen der ganzen App.
 *   (b) die vier Regeln hier fuehren.
 *
 * (b) gewinnt, und W21 bleibt unberuehrt: `user_management/` wird nicht angefasst. Was hier fuer
 * `.um-knopf` und `.um-knopf--haupt` steht, ist eine ABSCHRIFT der Baustein-Werte
 * (user_management.css Z. 286-305) und keine zweite Erfindung — dieselben Tokens, dasselbe
 * `--um-tap`, derselbe Radius. Weicht der Baustein eines Tages ab, sehen Knoepfe auf Baustein-
 * und App-Seiten verschieden aus; das ist sichtbar und damit reparierbar. Ein Framework waere an
 * dieser Stelle die dritte Wahrheit gewesen.
 *
 * ↺ 2026-09-18, RICHTIGGESTELLT: hier stand „die vier Regeln" seien insgesamt eine Abschrift. Das
 * stimmt nur fuer die beiden oben. `.um-knopf--gefahr` ist KEINE: der Baustein zeichnet ihn als
 * UMRISS (weisser Grund, Rand und Schrift in `--gefahr`, Z. 306), diese Datei als volle Flaeche
 * (Grund `--gefahr`, Schrift weiss). `--zeile` und sämtliche Zustandsregeln (`:hover`) sind
 * Eigenbau — der Baustein hat keine. Die Folge ist gemessen: auf den Verwaltungsseiten laden
 * beide Dateien, der Baustein ZULETZT und gleich spezifisch, also gilt dort sein Umriss — und die
 * Zustandsregeln dieser Datei (0,2,0) greifen trotzdem. `.um-knopf--gefahr:hover` setzte nur die
 * Schrift (weiss), der Grund kam aus dem `.um-knopf` des Bausteins (weiss). Gemessen an allen
 * fuenf Stellen des Bausteins — „Zugang beenden" und „An … übergeben" (/settings/team/<Konto>),
 * „Widerrufen" (API-Zugaenge), „Abschalten" (Anmeldeschutz), „… wieder trennen" (Rueckgaengig-
 * Link): beim Zeigen und Druecken weiss auf weiss, 1:1.
 *
 * DARAUS DIE REGEL: JEDE ZUSTANDSREGEL EINES KNOPFS SETZT SCHRIFT UND GRUND GEMEINSAM. Dann ist
 * sie fuer sich lesbar, gleich welche Regel den Ruhezustand des Knopfs gewonnen hat. Das gilt
 * auch fuer den Grundknopf `.um-knopf:hover`: er erreicht JEDEN Flaechenknopf, der keine eigene
 * Zustandsregel hat, und saehe dort sonst gruene Schrift auf seinem gruenen Grund.
 * `tests/test_kontrast_struktur.py` prueft die Paarung, `tests/test_kontrast.py` misst sie. */
.um-knopf {
  display: inline-flex; align-items: center; justify-content: center;
  gap: .4rem; min-height: var(--um-tap); padding: .6rem 1.1rem;
  border-radius: var(--um-radius); border: 1px solid var(--border-stark);
  background: var(--card-bg); color: inherit;
  font: inherit; cursor: pointer; text-decoration: none;
}
.um-knopf:hover { border-color: var(--maroon); color: var(--maroon); background: var(--card-bg); }
.um-knopf--haupt {
  background: var(--maroon); color: var(--on-maroon); border-color: transparent;
  font-weight: 600;
}
.um-knopf--haupt:hover { background: var(--maroon); color: var(--on-maroon); filter: brightness(1.08); }
/* ↺ 2026-09-18, GESTALT STUFE 1: DER ZEILENKNOPF. Gemessen trugen auf /heute 76 von 77 Knoepfen
 * `--haupt` — zwei vollflaechig gruene je Pflanze, 6,6 Bildschirme lang. Wo alle Hauptknopf sind,
 * ist es keiner. Eine Handlung, die sich in JEDER Zeile einer Liste wiederholt, ist getoent:
 * sichtbar eine Handlung (Farbe, Gewicht), aber keine Wand. `--haupt` bleibt der EINE Knopf,
 * der eine Seite abschliesst. Gruen auf der Toenung: 5,0:1. */
.um-knopf--zeile {
  background: var(--maroon-hell); color: var(--maroon); border-color: transparent;
  font-weight: 600;
}
.um-knopf--zeile:hover { background: var(--maroon-hell); color: var(--maroon); border-color: var(--maroon); }
.um-knopf:focus-visible, .kopfzeile__abmelden button:focus-visible {
  outline: 2px solid var(--maroon); outline-offset: 2px;
}
.knopfreihe { display: flex; flex-wrap: wrap; gap: var(--abstand-2); margin: var(--abstand-4) 0; }
/* ↺ 2026-09-18, Gestalt Stufe 1: die Wege eines Gartens als EINE Auswahl. Zwei Spalten ab
 * 20rem — darunter eine. Die Knoepfe fuellen ihre Zelle; ein Text, der nicht in eine Zeile
 * passt („Mitglieder und Einladungen"), bricht um, statt die Zelle zu sprengen. */
.garten-wege {
  display: grid; gap: var(--abstand-2); margin: var(--abstand-4) 0 var(--abstand-5);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 10rem), 1fr));
}
.garten-wege > .um-knopf { justify-content: flex-start; text-align: left; box-shadow: var(--shadow-sm); }

/* ── Die Anmelde- und Fehlerseiten ───────────────────────────────────────────────────────────
 * `auth-wrap`, `auth-btn`, `auth-note`, `auth-hinweis`, `magic-form`, `lead` und `um-formular`
 * waren die restlichen der 20 Klassen ohne Regel — die Anmeldeseite bestand komplett daraus. */
.auth-wrap { max-width: 34rem; margin: 2.5rem auto; padding: 0 1rem; }
.auth-wrap h1 { font-size: var(--schrift-titel); margin: 0 0 var(--abstand-2); }
.lead { color: var(--ink); font-size: var(--schrift-unter); line-height: 1.55; margin: 0 0 var(--abstand-4); }
.auth-note { color: var(--ink-soft); font-size: var(--schrift-klein); margin: var(--abstand-4) 0 0; }
.auth-hinweis {
  background: var(--card-bg); border: 1px solid var(--border);
  border-left: 4px solid var(--maroon); border-radius: .35rem;
  padding: .7rem .9rem; margin: 1rem 0;
}
.magic-form, .um-formular { display: grid; gap: .5rem; margin: 1rem 0; }
.magic-form label, .um-formular label { font-weight: 600; }
.magic-form input, .magic-form textarea, .um-formular input, .um-formular select {
  padding: .55rem .6rem; border: 1px solid var(--border); border-radius: .35rem;
  font: inherit; width: 100%; box-sizing: border-box;
}
/* Der Absendeknopf der Formulare sieht aus wie der Hauptknopf — er IST der Hauptknopf. */
.auth-btn {
  align-self: start;
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--um-tap); padding: .6rem 1.2rem;
  border: 1px solid transparent; border-radius: var(--um-radius);
  background: var(--maroon); color: var(--on-maroon);
  font: inherit; font-weight: 600; cursor: pointer;
}
.auth-btn:hover { filter: brightness(1.08); }
.auth-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* ── Klappen (UX-16, UX-17, UX-18) ───────────────────────────────────────────────────────────
 * `<details>` und kein JavaScript. Die Zusammenfassung ist ein Tippziel in voller Groesse —
 * ohne `min-height` ist sie auf dem Telefon eine Textzeile von 20 Pixeln.
 *
 * ↺ 2026-09-17, UX-Befunde 2, K3: `.nachtrag` ist die Klappe „Menge nachtragen" auf /heute und
 * hatte KEINE Regel — ihrer Zusammenfassung fehlte damit das Tippziel von oben. Sie bekommt
 * hier keine dritte Gestalt, sondern steht in denselben Selektoren wie
 * `.klappe.klappe--schmal`: dieselbe Klappe, dieselben Werte, eine Wahrheit. `.nachtrag` steht
 * dabei VOR `.klappe`, damit die Grundregel `.klappe {` fuer sich lesbar bleibt (`_grundregel`
 * in `tests/test_ux_formulare.py` sucht genau diese Form). */
.nachtrag, .klappe {
  border: 1px solid var(--border); border-radius: .5rem;
  background: var(--card-bg); margin: 1rem 0; padding: 0 1rem;
}
.nachtrag > summary, .klappe > summary {
  display: flex; align-items: center; gap: var(--abstand-2); min-height: var(--um-tap);
  margin: 0 -1rem; padding: 0 1rem;
  font-weight: 600; cursor: pointer; list-style-position: inside;
}
/* ↺ 2026-09-23, Los „Neu gebunden verstaendlich" (B): DAS DREIECK. GEMESSEN im Browser an der
 * Klappe auf /triebe: `display: flex` in der Regel darueber macht die Zusammenfassung zu einem
 * Flex-Container — und ein Flex-Container zeichnet KEINEN `::marker`. Chrome meldete
 * `list-style-type: disclosure-closed` und `::marker { content: normal }`, gezeichnet wurde
 * nichts: die Klappe sah aus wie eine graue Textzeile, nicht wie etwas zum Aufklappen.
 * `list-style-position: inside` in der Regel darueber aendert daran nichts und bleibt stehen —
 * sie gilt wieder, sobald jemand den Flex-Kontext entfernt.
 *
 * DIESELBE BAUFORM WIE DAS KONTOMENUE oben in dieser Datei: ein `::after` mit U+25BE, bei offener
 * Klappe U+25B4. Kein Bild, keine neue Farbe — das Zeichen erbt die Schriftfarbe der
 * Zusammenfassung. Der `gap` darueber setzt den Abstand zum Text. */
.nachtrag > summary::-webkit-details-marker, .klappe > summary::-webkit-details-marker { display: none; }
.nachtrag > summary::after, .klappe > summary::after { content: "\25BE"; font-size: .85em; }
.nachtrag[open] > summary::after, .klappe[open] > summary::after { content: "\25B4"; }
.nachtrag > summary:focus-visible, .klappe > summary:focus-visible { outline: 2px solid var(--maroon); outline-offset: -2px; }
.nachtrag[open] > summary, .klappe[open] > summary { border-bottom: 1px solid var(--border); }
.nachtrag[open], .klappe[open] { padding-bottom: 1rem; }
.nachtrag, .klappe--schmal { margin: .25rem 0; background: transparent; border-color: transparent; }
.nachtrag > summary, .klappe--schmal > summary { font-weight: 400; color: var(--ink-soft); font-size: .9rem; }

/* ── Die Rückfrage vor Papierkorb und Archiv (↺ 2026-09-15, Tills „kleines Nachfrage-Modal“) ──
 * `<details class="rueckfrage">` aus `_makros.rueckfrage` — warum `<details>` und nicht
 * `:target` oder eine eigene Seite, steht dort. Hier nur, wie sie aussieht:
 *
 *   ZU:   die Zusammenfassung ist ein gewoehnlicher `.um-knopf` (ohne Dreieck).
 *   OFFEN: die ganze Klappe wird zur Karte — Rahmen, Balken in der Gefahrfarbe, Schatten, und
 *         ein abgedunkeltes Umfeld aus einem riesigen Schattenring (`0 0 0 100vmax`). Das dunkelt
 *         ab, ohne ein Overlay ueber die Seite zu legen: die Karte bleibt im Fluss, nichts wird
 *         unerreichbar verdeckt, und ein Klick daneben trifft weiter, was darunter liegt.
 *         Die Zusammenfassung wandert als „Nein, abbrechen" nach rechts oben, wo ein Dialog
 *         seinen Schliessen-Knopf hat.
 *
 * GRENZE, gewusst: in einem rollenden Tabellencontainer (`.tabelle-rollt`, Abschnittszeilen)
 * schneidet `overflow` den Schattenring ab — dort dunkelt nur die Tabelle ab. Die Rueckfrage
 * funktioniert trotzdem gleich. */
.rueckfrage { display: inline-block; vertical-align: top; }
.rueckfrage > summary { list-style: none; }
.rueckfrage > summary::-webkit-details-marker { display: none; }
.rueckfrage__auf { display: none; }
.rueckfrage[open] {
  display: block; position: relative; z-index: 20;
  flex: 1 1 100%; max-width: 30rem; margin: .5rem 0; padding: .75rem 1rem 1rem;
  background: var(--card-bg); color: var(--ink);
  border: 1px solid var(--border-stark); border-left: 4px solid var(--gefahr);
  border-radius: var(--um-radius);
  box-shadow: 0 0 0 100vmax rgba(29, 36, 25, .22), 0 8px 24px rgba(29, 36, 25, .28);
}
.rueckfrage[open] > summary {
  float: right; margin: 0 0 .5rem .75rem;
  background: var(--card-bg); color: var(--ink); border-color: var(--border-stark); font-weight: 400;
}
.rueckfrage[open] > summary .rueckfrage__zu { display: none; }
.rueckfrage[open] > summary .rueckfrage__auf { display: inline; }
.rueckfrage--sanft[open] { border-left-color: var(--maroon); }
.rueckfrage__frage { margin: .35rem 0 .5rem; font-size: 1.05rem; }
.rueckfrage__karte .reihe { clear: both; }
.um-knopf--gefahr { background: var(--gefahr); color: var(--on-maroon); border-color: transparent; font-weight: 600; }
/* ↺ 2026-09-18, K2: der Grund steht jetzt MIT in der Zustandsregel. Ohne ihn war der Knopf auf den
 * Verwaltungsseiten beim Zeigen weiss auf weiss (Begruendung und Messung oben bei den Knoepfen).
 * Dort sieht er in Ruhe aus wie im Baustein (Umriss) und fuellt sich beim Zeigen — lesbar in
 * beiden Zustaenden, gemessen auf /settings/team/<Konto>: in Ruhe #a4302a auf Weiss 6,9:1, beim
 * Zeigen und Druecken Weiss auf #b1342d (`--gefahr` mit brightness(1.08)) 6,2:1. */
.um-knopf--gefahr:hover { background: var(--gefahr); color: var(--on-maroon); border-color: transparent; filter: brightness(1.08); }

/* ── Tabellen, die breiter sind als das Telefon (UX-22) ──────────────────────────────────────
 * DER CONTAINER ROLLT, NICHT DIE SEITE. Ohne ihn zieht eine Zeile mit Formular die ganze Seite
 * breit, und der Fliesstext daneben wird unlesbar. */
.tabelle-rollt { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: .75rem 0 1.5rem; }
.tabelle-rollt > .liste { margin: 0; min-width: 34rem; }

/* ── Kleinteile, die bisher ohne Regel benutzt wurden ────────────────────────────────────────
 * `.masse` und `.ort` sind die Bloecke, die das Skript nach der gewaehlten Form bzw. Ortsart
 * ein- und ausblendet (`hidden`); sie brauchen eine Regel, weil sie sonst als lose Absaetze
 * zwischen den Feldern stehen. `[hidden]` wird ausdruecklich gesetzt: ein `display: grid`
 * ueberschriebe die eingebaute Wirkung von `hidden` und das Skript waere wirkungslos. */
.masse, .ort { display: grid; gap: 0; }
.masse[hidden], .ort[hidden] { display: none; }
.feld-schmal { display: block; font-size: .85rem; color: var(--ink-soft); font-weight: 600; }
.garten-kopf { display: flex; flex-wrap: wrap; align-items: baseline; gap: .35rem .75rem; }
.garten-karte--aktiv { border-left: 4px solid var(--maroon); }
/* ↺ 2026-09-17, UX-Befunde 2, K3 und W-9 gegen die Vorlagen: `garten-karte--verwaist` kommt aus
 * `garten_dashboard.zustand()` (Feld `css`) und landet in uebersicht.html als `{{ z.css }}` —
 * im Quelltext der Vorlage steht der Name gar nicht, und der Abzug-Waechter sah ihn nie, weil
 * der Seed keinen verwaisten Garten hat. Er hatte KEINE Regel. Ein verwaister Garten ist im
 * selben Zustand wie eine unklare Zugehoerigkeit (`gesperrt`) und sieht deshalb auch so aus. */
.garten-karte--unklar, .garten-karte--verwaist { border-left: 4px solid var(--border-stark); }
/* ↺ 2026-09-17, UX-Befunde 2, K3: `.abstand-oben` (beet_abgelegt.html, die Wege „Archiv ·
 * Papierkorb" unter den Knoepfen) hatte keine Regel und klebte am letzten Formular. */
.abstand-oben { margin-top: 1.5rem; }
main { padding-bottom: 3rem; }

/* ── Die Anordnungs-Ansicht (E5) ─────────────────────────────────────────────────────────────
 * DREI KLASSEN, UND ALLE DREI HABEN EINEN GRUND IN PIXELN.
 *
 * `.anordnen-raster__feld` ist das Setz-Feld. Es traegt `--um-tap` als MINDESTbreite UND
 * -hoehe: ein Knopf, der nur hoch genug ist, ist auf einem Telefon trotzdem kein Tippziel.
 * Fuenf davon nebeneinander plus die Meterangabe am Zeilenanfang sind genau die sechs
 * Tippziele, die in die 288 px eines 320er-Telefons passen (garten_draufsicht.RASTER_SPALTEN
 * rechnet dieselbe Zahl aus, und der Waechter prueft beide gegeneinander). Das Polster der
 * `.liste`-Zellen faellt hier weg, sonst waere die Tabelle breiter als ihre Knoepfe.
 *
 * `.anordnen-pfeile` ist ein 3x3-Gitter mit vier besetzten Feldern — die Pfeile stehen als
 * Kreuz und nicht als Reihe, weil „hoch" ueber „runter" gehoert und nicht daneben. Wer die
 * Anordnung eines Beetes mit vier Knoepfen in einer Zeile bedient, tippt den falschen.
 *
 * `.anordnen-leiste` und `.anordnen-knoepfe` sind die Umschlaege: eine Leiste je Handgriff,
 * mit ihrer Beschriftung davor. Sie umbrechen (`flex-wrap`), damit auf dem Telefon nichts aus
 * dem Bild laeuft. */
.anordnen-leiste {
  border: 1px solid var(--border); border-radius: .5rem;
  background: var(--card-bg); padding: .6rem .75rem; margin: .75rem 0;
}
.anordnen-leiste__name { margin: 0 0 .35rem; font-weight: 600; }
.anordnen-knoepfe { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin: .5rem 0; }
.anordnen-knoepfe__was { flex: 1 1 9rem; color: var(--ink-soft); font-size: .9rem; }

.anordnen-pfeile {
  display: grid; grid-template-columns: repeat(3, var(--um-tap));
  grid-template-rows: repeat(3, var(--um-tap)); gap: .3rem; margin: .5rem 0;
}
.anordnen-pfeile .um-knopf { min-width: var(--um-tap); padding: 0; }
.anordnen-pfeile__hoch   { grid-column: 2; grid-row: 1; }
.anordnen-pfeile__links  { grid-column: 1; grid-row: 2; }
.anordnen-pfeile__rechts { grid-column: 3; grid-row: 2; }
.anordnen-pfeile__runter { grid-column: 2; grid-row: 3; }

.anordnen-raster { min-width: 0; }
.tabelle-rollt > .anordnen-raster { min-width: 0; }
.anordnen-raster th, .anordnen-raster td { padding: .1rem; border-bottom: 0; text-align: center; }
.anordnen-raster caption { caption-side: bottom; text-align: left; padding: .35rem 0 0; }
.anordnen-raster__feld { min-width: var(--um-tap); padding: 0; }

/* ────────────────────────────────────────────────────────────────────────────────────────────
   DIE FOTOS (Los E4.4). Eine Reihe von Vorschaubildern, die auf einem Handy umbricht.

   `max-width` UND `height: auto` ZUSAMMEN, und beides ist noetig: die Vorlage schreibt die
   ECHTEN Pixelmasse in `width`/`height` (damit die Seite beim Nachladen nicht springt), und ohne
   `height: auto` verzerrte die begrenzte Breite jedes Bild. Gerechnet wird hier — nicht in der
   Vorlage und nicht im Python: die Anzeigegroesse ist eine Frage der Darstellung.

   `object-fit: cover` beschneidet NUR DIE VORSCHAU auf ein gleichmaessiges Kaestchen; die
   DATEI bleibt unbeschnitten, und ein Klick auf das Bild zeigt sie vollstaendig. Das ist der
   Unterschied zu Wichtels Avatarweg, der beim Speichern beschneidet: an einer noch zu
   bestimmenden Pflanze nimmt Beschneiden genau das Merkmal weg, an dem sie zu bestimmen waere.
   ──────────────────────────────────────────────────────────────────────────────────────────── */
.fotoreihe { list-style: none; margin: .5rem 0; padding: 0; display: flex; flex-wrap: wrap; gap: .5rem; }
.fotoreihe li { display: grid; gap: .15rem; justify-items: start; }
.fotoreihe img { max-width: 10rem; max-height: 10rem; width: auto; height: auto;
                 object-fit: cover; border: 1px solid var(--border); border-radius: .3rem;
                 display: block; background: var(--card-bg); }

/* ────────────────────────────────────────────────────────────────────────────────────────────
   DIE BINDERFARBEN (Los E6, J1).

   Das Farbfeld ist ein SVG-Rechteck mit `fill` und KEIN Hintergrund: Browser lassen
   Hintergrundfarben beim Drucken weg, eine Fuellung nicht. Die Farbe steht nie allein — der Name
   steht immer daneben (§3.8, Rot-Gruen-Schwaeche).
   ──────────────────────────────────────────────────────────────────────────────────────────── */
.farbfeld { display: inline-block; vertical-align: middle; width: 1.5rem; height: 1.5rem; }
.farbwahl { border: 1px solid var(--border); border-radius: .5rem; margin: .75rem 0; padding: .25rem .75rem .5rem; }
.farbwahl legend { font-weight: 600; padding: 0 .35rem; }
/* ↺ 2026-09-17, UX-Welle 3, K18: hier stand `min-height: 2rem` = 32 px — laut Befund die
   einzige von sieben `min-height`-Regeln der Datei ohne `--um-tap`, gemessen an 32 Farbfeldern
   auf /binderfarben. Die Beschriftung ist das Tippziel des Auswahlknopfs darin. */
.farbwahl__farbe { display: inline-flex; align-items: center; gap: .35rem; margin: .25rem 1rem .25rem 0; min-height: var(--um-tap); }

/* ↺ 2026-09-15, Los E6, Vervollstaendigung: die Triebe-Seite und die Legende.
   ↺ 2026-09-17, UX-Welle 3, K28: der eigene Unterstrich ist weg. `.triebe-strauch` steht auf
   beiden Seiten in einer `.liste-schmal`, und deren Eintraege trennt jetzt EINE Regel (unten,
   „Gestalt"). Mit beiden stuenden zwischen zwei Straeuchern zwei Linien im Abstand von 5,6 px. */
.triebe-strauch { padding: .5rem 0 .75rem; }
.bestand { margin: .25rem 0 .5rem; padding-left: 1.25rem; }
.bestand-unsicher { color: var(--ink); }

/* ↺ 2026-09-23, Los „Neu gebunden verstaendlich" — die drei Stuecke, die die Triebe-Seite dazu
   bekommt. KEINE NEUE FARBE: alle drei nehmen vorhandene Tokens.

   `.strauch-meldung` ist die Quittung (oder die Abweisung) AM STRAUCH. Sie traegt `.meldung` und
   deren Variante mit — hier steht nur, was sie im Fluss einer Strauchzeile braucht: etwas Luft
   und Absaetze, die nicht auseinanderfallen. GEMESSEN vor der Reparatur bei 375 px: die Quittung
   stand nach dem Eintragen 522 bis 1.388 px UEBER dem Bildrand, je nach Datenstand.

   `.erster-schritt` ist der Satz im leeren Garten. Er ist bewusst NICHT `.hinweis` (14 px, grau):
   er ist die einzige Handlungsanweisung auf einer Seite, auf der sonst 15-mal „Noch nichts
   eingetragen." steht.

   `.jahrwahl__jahr` ist das Tippziel des Jahrgangswechsels — GEMESSEN 30 x 19 px als
   Fliesstextlink; die Hausregel ist `--um-tap`. Das laufende Jahr (`--hier`) ist kein Verweis,
   sondern ein Feld: es traegt deshalb die Textfarbe und einen staerkeren Rahmen, nicht nur eine
   andere Farbe (§3.8, Farbe nie allein). */
.strauch-meldung { margin: .5rem 0 .75rem; }
.strauch-meldung p { margin: .25rem 0; }
.erster-schritt {
  background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--um-radius);
  padding: var(--abstand-3) var(--abstand-4); margin: var(--abstand-4) 0;
}
.jahrwahl { display: flex; flex-wrap: wrap; gap: var(--abstand-2); list-style: none;
            margin: var(--abstand-2) 0 var(--abstand-4); padding: 0; }
.jahrwahl__jahr {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--um-tap); min-width: var(--um-tap); padding: 0 var(--abstand-3);
  border: 1px solid var(--border-stark); border-radius: var(--um-radius);
  text-decoration: none;
}
.jahrwahl__jahr--hier { color: var(--ink); border-width: 2px; font-weight: 600; }
/* ↺ 2026-09-26, Nutzerfreundlichkeit Schritt 3 (A5): DIE BEETLISTE AUF /triebe und der Weg
   zurueck zu ihr. Die Seite war bei 375 px 13.933 px lang, ohne einen einzigen Sprunglink. Jeder
   Eintrag ist ein Tippziel von `--um-tap`; zwei Spalten, sobald zwei Namen nebeneinander passen —
   sonst waeren acht Beete acht volle Zeilen vor dem ersten Strauch. */
.sprungliste { display: grid; grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
               gap: 0 var(--abstand-3); list-style: none; margin: 0 0 var(--abstand-4); padding: 0; }
.sprungliste a, .nach-oben a { display: inline-flex; align-items: center; min-height: var(--um-tap); }
.nach-oben { margin: var(--abstand-2) 0 0; }
.legende-tabelle { border-collapse: collapse; margin: .75rem 0 1rem; }
.legende-tabelle th, .legende-tabelle td { text-align: left; padding: .3rem 1.25rem .3rem 0; border-bottom: 1px solid var(--border); }

/* ↺ 2026-09-16, Los E7.4: DER BEITRITTSCODE IN DREI GESTALTEN — Zahl, Link, Bild.
   `.beitrittscode` stand seit E7.1 in der Vorlage und hatte KEINE Regel (UX-Befund K3); die
   zwoelf Zeichen liefen damit im Fliesstext mit und waren beim Abschreiben leicht zu verlesen.
   Feste Zeichenbreite und Sperrung sind hier kein Geschmack: I und 1, O und 0 sind aus dem
   Alphabet zwar verbannt, B und 8 aber nicht.
   Das Bild bekommt einen weissen Grund, auch wenn die Seite schon weiss ist — ein QR-Code auf
   farbigem Papier wird sonst beim Ausdrucken unlesbar, und genau dafuer ist er da. */
.beitrittscode { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
                 font-size: 1.5rem; letter-spacing: .12em; margin: .5rem 0; }
.beitrittslink { overflow-wrap: anywhere; }
.qr { margin: .75rem 0 0; max-width: 15rem; }
.qr svg { display: block; width: 100%; height: auto; background: #fff; padding: .5rem;
          border: 1px solid var(--border); border-radius: var(--um-radius); }
.qr figcaption { margin-top: .35rem; font-size: .85rem; color: var(--ink-soft); }

/* ────────────────────────────────────────────────────────────────────────────────────────────
 * UX-WELLE 3 „GESTALT" (2026-09-17, docs/ux-befunde-2.md, Abschnitt E, Welle 3)
 *
 * DER MASSSTAB IST TILLS TELEFON, und die Zahlen hier sind VOR dem Bau in einem Chromium bei
 * 375 px Breite gemessen (Seiten gegen eine Wegwerf-Datenbank gerendert, 25 Seiten):
 *   * jedes Eingabefeld ausser `.magic-form`/`.um-formular` hatte 13,33 px Schrift und war
 *     17 bis 30 px hoch — iOS Safari zoomt beim Antippen jedes Feldes unter 16 px (V29);
 *   * die Farbfelder der Binderfarben waren 32 px hoch (K18), die 34 Beetlinks auf /anordnen 21 px
 *     (K17), und die Eintraege von `.liste-schmal` standen 5,6 px auseinander, ohne Linie (K28, V24).
 * NICHT gemessen ist ein echtes iPhone: kein Safari, kein Zoom, kein Daumen. Was Safari mit
 * `min-height` an einem `<select>` tut, steht hier deshalb nicht als Tatsache.
 *
 * EIN BREITEN-HALTEPUNKT STEHT HIER NICHT, und das ist gemessen, nicht vergessen: vor und nach
 * dem Bau war keine der 25 Seiten bei 375 px breiter als das Bild (bei 320 px nur /einstellungen,
 * um 1 px, schon vorher). Was nicht passt, rollt absichtlich in `.tabelle-rollt` — und die
 * Papierkorbtabelle ist Tills offene Entscheidung E9. Die klebende Kopfzeile ist bei 375 px
 * 150 px hoch; ob sie am Telefon kleben soll, ist eine Abwaegung und keine Passform.
 *
 * KEINE NEUEN FARBEN — nur Tokens von oben (`tests/test_ux2_gestalt.py` zaehlt die Farbwerte).
 * ──────────────────────────────────────────────────────────────────────────────────────────── */

/* ── V29 · Schrift der Eingabefelder ─────────────────────────────────────────────────────────
 * `font: inherit` ALLEIN REICHT NICHT, und das ist gemessen: `.reihe label` setzt `.85rem`, ein
 * Feld darin erbte also 13,6 px — wieder unter der Schwelle. Deshalb die Untergrenze
 * `max(16px, 1em)`: nie kleiner als 16 px, groesser, wenn die Umgebung groesser ist.
 *
 * DIE LISTE SIND ALLE UMGEBUNGEN, in denen eine Vorlage ein Feld traegt (gezaehlt an den
 * Vorlagen, nicht am Abzug): `.feld`, das Geschwister einer `.feld-schmal`-Beschriftung (so
 * stehen die 20 Felder auf /zu-bestimmen und die Makros `pflanzenwahl`/`verschiebeziel`),
 * `.reihe`, `.garten-form`, die Tabellenzellen von `.liste` (Umschneiden), dazu `.magic-form`
 * (Anmeldung, 403) und `.um-formular` (Einladung auf /mitglieder), die mit `font: inherit` schon
 * 16 px hatten, aber nur 42-43 px hoch waren. Ein Feld in einer NEUEN Umgebung faellt
 * `tests/test_ux2_gestalt.py` auf, nicht erst dem Daumen. */
.feld input, .feld select, .feld textarea,
.feld-schmal + input, .feld-schmal + select, .feld-schmal + textarea,
.reihe input, .reihe select, .reihe textarea,
.garten-form input, .garten-form select, .garten-form textarea,
.liste input, .liste select, .liste textarea,
.magic-form input, .magic-form textarea,
.um-formular input, .um-formular select, .um-formular textarea {
  font: inherit; font-size: max(16px, 1em);
}

/* ── V29 · Tippzielhoehe derselben Felder ────────────────────────────────────────────────────
 * Dieselben Umgebungen, ohne Kontrollkaestchen und Auswahlknoepfe: deren Tippziel ist ihre
 * Beschriftung (`.farbwahl__farbe`), und ein 48 px hohes Kaestchen waere ein anderes Bauteil. */
.feld input:not([type="checkbox"]):not([type="radio"]), .feld select, .feld textarea,
.feld-schmal + input:not([type="checkbox"]):not([type="radio"]), .feld-schmal + select,
.feld-schmal + textarea,
.reihe input:not([type="checkbox"]):not([type="radio"]), .reihe select, .reihe textarea,
.garten-form input:not([type="checkbox"]):not([type="radio"]), .garten-form select,
.garten-form textarea,
.liste input:not([type="checkbox"]):not([type="radio"]), .liste select, .liste textarea,
.magic-form input:not([type="checkbox"]):not([type="radio"]), .magic-form textarea,
.um-formular input:not([type="checkbox"]):not([type="radio"]), .um-formular select,
.um-formular textarea {
  min-height: var(--um-tap); box-sizing: border-box;
}

/* ── Häkchen · Kästchen und Text auf EINER Zeile ─────────────────────────────────────────────
 * ↺ 2026-09-26, Nutzerfreundlichkeit Schritt 3. GEMESSEN im Browser bei 375 px über alle 51
 * Seiten: 15 Kontrollkästchen standen allein in ihrer Zeile (6 auf /beet, 8 auf dem großen Beet,
 * 1 auf /heute) — das Kästchen als bis zu 302 px breiter Streifen, in dessen Mitte es sitzt,
 * sein Text 7 px unter dessen Unterkante und dahinter ohne Abstand schon die nächste Frage
 * („Die Zahl ist nur geschätzt / Seit welchem Jahr steht es schon da?“). Man las beides als
 * einen Block und sah nicht, wozu das Häkchen gehört. Die Ursache ist EINE Regel:
 * `.reihe label { display: grid }` macht aus Kästchen und Text zwei Zeilen eines Rasters und
 * zieht das Kästchen auf die Spaltenbreite. Alle 15 standen in einer `.reihe`; die übrigen
 * Häkchen und Auswahlknöpfe der App (Binderfarben, Wiederherstellen) standen schon richtig.
 *
 * `label.haekchen` und nicht `.haekchen`: (0,1,1) wie `.reihe label` — und weil diese Regel
 * SPÄTER steht, gewinnt sie. Das Tippziel ist die ganze Beschriftung (ein Tipp auf den Text
 * setzt das Häkchen), deshalb `--um-tap` an ihr und nicht am Kästchen. Der Abstand darunter ist
 * größer als der darüber: das Häkchen gehört zu dem Feld, unter dem es steht, und nicht zu der
 * Frage, die danach kommt. Bewacht im Browser: `test_kontrast.py`,
 * `test_jedes_haekchen_steht_auf_der_zeile_seines_texts`. */
label.haekchen {
  display: flex; align-items: center; gap: var(--abstand-2);
  min-height: var(--um-tap); margin: 0 0 var(--abstand-3);
}
label.haekchen input { flex: none; width: 1.25rem; height: 1.25rem; margin: 0; }

/* ── V29 · Eine groessere Schrift macht ein Auswahlfeld breiter ──────────────────────────────
 * Ein `<select>` ist so breit wie seine laengste Option. Gemessen: „Baumscheibe
 * Johannisbeer-Stämmchen" als Traegerbeet wuchs mit 16 px von 278 auf 317 px und schob die Seite
 * bei 320 px Breite auf 350 px. In `.feld` (Grid) und `.reihe` (Flex) hilft `max-width` allein
 * nicht — die Spur waechst mit dem Inhalt; erst `min-width: 0` laesst das Feld schrumpfen. */
.feld select, .feld-schmal + select, .reihe select, .garten-form select, .liste select,
.um-formular select {
  min-width: 0; max-width: 100%;
}

/* ── K28 / V24 · Eintraege von `.liste-schmal` trennen ───────────────────────────────────────
 * Eine Linie ZWISCHEN den Eintraegen, nicht darunter: nach dem letzten folgt ohnehin der
 * naechste Abschnitt. Gilt fuer jede `.liste-schmal` (Archiv, Heute, Triebe, Beetseite …) —
 * dieselbe Liste sieht ueberall gleich aus. */
.liste-schmal > li + li { border-top: 1px solid var(--border); padding-top: .5rem; }

/* ── K17 · Die Beetwahl auf /anordnen als Tippziele ──────────────────────────────────────────
 * Die Zeilen liegen dicht aneinander (kein Abstand, nur die Linie), weil jede selbst 48 px hoch
 * ist — wie eine Auswahlliste am Telefon. Das gewaehlte Beet steht als `<strong>` in derselben
 * Hoehe, damit die Zeile beim Umschalten nicht springt. */
.anordnen-beetwahl { gap: 0; }
.anordnen-beetwahl > li {
  display: flex; flex-wrap: wrap; align-items: center; column-gap: .35rem;
  min-height: var(--um-tap);
}
.anordnen-beetwahl > li + li { padding-top: 0; }
.anordnen-beetwahl a, .anordnen-beetwahl strong {
  display: inline-flex; align-items: center; min-height: var(--um-tap);
}

/* ── V5 (nur der Teil ohne Entscheidung) · die ueberfaellige Papierkorbzeile ─────────────────
 * Der Balken sitzt an der ERSTEN Zelle, weil sie am Telefon als einzige sichtbar ist (gemessen:
 * Tabelle 544 px im 343-px-Container, Spalte „Wird entfernt" ab x=252). Er ist eine Form, nicht
 * nur eine Farbe — die Zeile hat ihn oder hat ihn nicht. Ob die Tabelle Tabelle bleibt, ist
 * Tills offene Entscheidung E9; daran aendert diese Regel nichts. */
.papierkorb-frist-um > td:first-child { border-left: 4px solid var(--gefahr); }

/* ↺ 2026-09-28, Welle C (V6) · DER BEETNAME IN ARCHIV UND PAPIERKORB IST EIN WEG zur Seite des
 * Beetes. Als Fliesstextlink waere er so hoch wie seine Zeile; die Hausregel fuer Tippziele ist
 * `--um-tap`, dieselbe Form wie die Beetwahl auf /anordnen (K17). */
.ablage-name { display: inline-flex; align-items: center; min-height: var(--um-tap); }

/* ↺ 2026-09-18, K3 · EHEMALIGE MITGLIEDER AUF /settings/team — GEDAEMPFT UEBER FARBE, NICHT
 * UEBER DECKKRAFT. Der Baustein daempft die Karte mit `.um-karte--inaktiv { opacity: .6 }`, und
 * Deckkraft wirkt auf ALLES darin: auch auf den Knopf „Wieder aufnehmen". Gemessen: 4,45:1 in Ruhe,
 * 2,68:1 beim Zeigen — ausgerechnet der Knopf, mit dem man den Zustand aufhebt, war der blasseste.
 * Der Baustein bleibt unberuehrt (W21); diese Regel ist (0,2,0) und schlaegt seine (0,1,0), obwohl
 * er spaeter laedt. Die Karte bleibt erkennbar „nicht mehr dabei" — durch die Zweitflaeche, den
 * gestrichelten Rand (eine FORM, nicht nur ein Farbton) und den Namen in Nebentextfarbe
 * (#545e50 auf #f4f6f1, gerechnet 6,2:1); der Knopf behaelt seine volle Farbe. */
.um-karte.um-karte--inaktiv { opacity: 1; background: var(--card-bg-2); border-style: dashed; }
.um-karte--inaktiv .um-karte__name { color: var(--ink-soft); }

/* DER EINZIGE DRUCKBLOCK DER APP (gemessen vor dem Bau: null `@media print`). Er blendet aus, was
   auf Papier nichts bedeutet — Kopfzeile, Meldungen, Brotkrume, Formulare, Klappen — und fuehrt
   KEINE neue Farbe ein. Die Farbfelder sind SVG-Fuellungen und drucken deshalb auch dann, wenn
   der Browser Hintergrundfarben weglaesst.

   ↺ 2026-09-18, K4 · DIE FLAECHENKNOEPFE AUF PAPIER. Chrome druckt in der Vorgabe ohne
   „Hintergrundgrafiken" (andere Browser nicht nachgemessen) — die gruene Flaeche von
   „Heute im Garten" fiel weg, die weisse Schrift blieb: weiss auf Papier (gemessen im
   Druckmedium auf /garten und /draufsicht: Schrift #ffffff, `print-color-adjust: economy`).
   Chrome dunkelt fast weisse Schrift beim Drucken zwar selbst ab — gemessen im PDF von /garten
   ohne Hintergruende: die Knopfschrift steht dort in #ababab, und das sind auf Papier 2,3:1.
   Im Druck wird aus jedem Flaechenknopf deshalb ein Umriss mit Schrift in Tinte.
   (0,2,0), weil der Baustein seinen `.um-knopf--haupt` auf den Verwaltungsseiten SPAETER laedt
   und bei gleicher Spezifitaet gewaenne. */
.nicht-drucken { }
@media print {
  .kopfzeile, .meldungen, .brotkrume, .nicht-drucken, form, details { display: none !important; }
  body { background: #fff; color: #000; }
  a { color: inherit; text-decoration: none; }
  .um-knopf.um-knopf--haupt, .um-knopf.um-knopf--gefahr, .um-knopf.um-knopf--zeile {
    background: none; color: #000; border: 1px solid #000; filter: none;
  }
}

/* ↺ 2026-09-17, Tills Auftrag: DIE GRENZE DES GRUNDSTUECKS.
 * „Vor allem sollte die Draufsicht immer die volle eingestellte Groesse des Gartens abbilden
 * (zB 10 m x 20 m) mit einer sichtbaren Grenze, da sonst bei noch nicht allen eingetragenen
 * beeten/Objekten unmoeglich beurteilbar ist, ob die Sachen korrekt angeordnet sind."
 *
 * KEINE NEUE FARBE (der Dateikopf: die sechs Tokens sind die Palette). Gestrichelt und nicht
 * durchgezogen, damit die Linie nicht mit dem Umriss eines Beetes zu verwechseln ist — sie ist
 * eine Angabe des Menschen ueber sein Grundstueck, keine gemessene Kante im Garten. */
.draufsicht__grundstueck {
  fill: none;
  stroke: var(--ink-soft);
  stroke-width: 1.5;
  stroke-dasharray: 6 4;
}
