/*
 * DLRG Brot-Shop – Basis-Styles (mobile-first).
 * Farben als CSS-Variablen, damit das Verbands-Farbschema zentral
 * anpassbar ist. DLRG-Rot/Gelb nur als dezente Akzente.
 */

:root {
    --dlrg-red:    #e2001a;
    --dlrg-yellow: #ffec00;
    --color-text:  #1c1c1c;
    --color-muted: #5b5b5b;
    --color-bg:    #fafafa;
    --color-card:  #ffffff;
    --color-border:#e0e0e0;

    /* Endgueltige Handlungen: Stornieren, Loeschen. Bewusst NICHT --dlrg-red -
       das Verbandsrot ist Marke, und als Textfarbe auf hellem Grund zu hell.
       Kontrast: 6.3:1 auf Weiss, 5.5:1 auf --color-danger-soft. */
    --color-danger:      #c0121b;
    --color-danger-soft: #fdecec;

    --radius: 10px;
    --gap: 1rem;
    --maxw: 960px;
    --maxw-admin: 1280px;   /* gemeinsame Breite des Admin-Bereichs */
    --font: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
}

/*
 * Waermere Flaechen, damit Produktfoto und Karten ruhiger sitzen - im
 * oeffentlichen Bereich und seit 1.33.1 auch in der Verwaltung
 * (body.admin-body, auch Anmeldung und Scanner), damit sich beide Seiten
 * der Aktion gleich anfuehlen. Die Marke bleibt unberuehrt - Rot, Gelb,
 * Systemschrift und Logo wie gehabt, Karten bleiben weiss. :root behaelt
 * die neutralen Werte als Rueckfall fuer Seiten ohne eine der beiden Klassen.
 */
.shop-body,
.admin-body {
    --color-bg:     #f2ece2;
    --color-border: #e2d9c9;
    --color-muted:  #5d5549;
}
.shop-body {
    --maxw:         1040px;   /* etwas mehr Luft für die zwei Spalten */
    --radius-card:  16px;     /* nur die grossen Karten; Buttons bleiben bei 10px */
    --shadow-card:  0 1px 2px rgba(61, 46, 26, 0.06), 0 10px 28px rgba(61, 46, 26, 0.07);
}

/* Nur für Screenreader: aus dem Bild genommen, aber vorgelesen. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* `hidden` muss `hidden` bedeuten.
 *
 * Das Attribut versteckt nur ueber eine Regel des BROWSERS
 * (`[hidden] { display: none }`). Jede Autorenregel mit eigenem `display`
 * sticht sie aus - Autorenstile gehen dem Browserstil vor, unabhaengig von
 * der Spezifitaet. Auf /admin/locations stand deshalb unten links ein leeres,
 * anklickbar aussehendes Kaestchen: der Aktionsknopf der Sortierung
 * (`.btn` + `hidden`), der erst bei einem Speicherfehler seinen Text
 * bekommt. `!important` ist hier das mildeste Mittel, das die ganze Klasse
 * dieses Fehlers erledigt.
 *
 * Genau EINE Stelle ueberstimmt `hidden` mit Absicht - die Bot-Falle im
 * Bestellformular. Sie sagt das weiter unten mit einem eigenen `!important`
 * und einer Begruendung. */
[hidden] { display: none !important; }

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--font);
    color: var(--color-text);
    background: var(--color-bg);
    line-height: 1.5;
}

.container {
    width: 100%;
    max-width: var(--maxw);
    margin: 0 auto;
    padding: var(--gap);
}

.site-header {
    display: flex;
    align-items: center;
    gap: var(--gap);
    padding: var(--gap);
    max-width: var(--maxw);
    margin: 0 auto;
    border-bottom: 4px solid var(--dlrg-yellow);
}

.site-header h1 {
    font-size: 1.4rem;
    margin: 0;
}

.site-header .logo {
    flex: 0 0 auto;          /* nicht schrumpfen – sonst quetscht es den Titel */
    height: 60px;            /* groesseres Logo am PC */
    width: auto;
    max-width: 360px;
}

.notice {
    background: var(--color-card);
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--dlrg-red);
    border-radius: var(--radius);
    padding: 0.75rem 1rem;
}

.notice--warn {
    border-left-color: var(--dlrg-yellow);
}

.product-card {
    background: var(--color-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-card, var(--radius));
    box-shadow: var(--shadow-card, none);
    padding: 1rem;
}

.site-footer {
    max-width: var(--maxw);
    margin: 2rem auto 1rem;
    padding: var(--gap);
    color: var(--color-muted);
    border-top: 1px solid var(--color-border);
}

.site-footer .legal-links a { color: var(--color-muted); }
.site-footer .footer-note { font-size: 0.85rem; }
.site-footer .footer-note p { margin: 0.3rem 0; }

/* --- Header / Brand --- */
.site-header { justify-content: space-between; }
.brand {
    display: flex;
    flex-direction: row;        /* Logo links, Titel/Datum rechts daneben */
    align-items: center;
    gap: 1rem;
    text-decoration: none;
    color: inherit;
}
.brand-text { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.brand-text strong { white-space: nowrap; font-size: 1.15rem; }
.brand-text small { color: var(--color-muted); font-weight: normal; }

/* Schmale Screens: Logo oben, Titel/Datum darunter (gestapelt) */
@media (max-width: 600px) {
    .site-header { gap: 0.5rem; }
    .brand { flex-direction: column; align-items: flex-start; gap: 0.4rem; width: 100%; }
    .site-header .logo { height: auto; max-width: 100%; max-height: 52px; }
    .brand-text strong { white-space: normal; }
}

/* --- Partnerverein im Kopf (Admin -> Einstellungen -> Darstellung) ---
 * Aufbau mit Partner: das DLRG-Logo, daneben (am Handy darunter) eine Zeile
 * aus Titel und Partner. Titel und Partner sind getrennte Bereiche; passen
 * sie nicht nebeneinander - langer Event-Name, langer Vereinsname, grosse
 * Schrift -, rutscht der Partner rechtsbuendig unter den Titel. Nichts liegt
 * uebereinander, nichts wird abgeschnitten; der Kopf wird dann eben hoeher.
 * Die DLRG bleibt links und groesser: sie ist der Hauptverein.
 *
 * Eine erste Fassung setzte den Partner unter 900 px immer in eine eigene
 * Zeile unter das Datum. Am Handy sah das wie ein angehaengter Listeneintrag
 * aus - deshalb steht er jetzt neben dem Titel, solange der Platz reicht.
 *
 * Steht bewusst NACH den Kopfregeln oben: gleiche Spezifitaet, spaetere
 * Regel gewinnt. */
.brand-logo { flex: 0 0 auto; display: block; line-height: 0; }
.brand-zeile {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1rem;
}
.site-header--partner .brand { flex: 0 1 auto; min-width: 0; }
/* Ohne Partner haelt nowrap den Titel in einer Zeile, weil nichts neben ihm
   steht. Mit Partner darf er umbrechen, statt den Kopf zu sprengen - bei
   stark vergroesserter Schrift auch innerhalb eines langen Wortes wie
   "Brotbackaktion", das sonst neben dem Logo ueber den Rand liefe. */
.site-header--partner .brand-text strong {
    white-space: normal;
    overflow-wrap: anywhere;
    hyphens: auto;
}

.partner {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-left: auto;
    min-width: 0;
    max-width: 100%;
}
.partner-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    text-align: right;
    line-height: 1.25;
}
.partner-label { font-size: 0.8rem; color: var(--color-muted); }
.partner-name {
    max-width: 15rem;
    font-size: 0.9rem;
    font-weight: 600;
    text-wrap: balance;
    overflow-wrap: anywhere;   /* ein Name ohne Leerzeichen bricht trotzdem um */
    hyphens: auto;             /* <html lang="de"> - Trennung nach deutschen Regeln */
}
.partner-logo {
    flex: none;
    height: 60px;              /* feste Hoehe: ein SVG ohne Masse wuerde sonst 300 x 150 */
    width: auto;
    max-width: 160px;
    object-fit: contain;
}

/* Handy: DLRG-Logo oben, darunter Titel links und Partner rechts in einer
   Zeile - und die Zeile genau so breit wie das DLRG-Logo, damit beide Logos
   rechts buendig enden. Auf breiten Handys ist das DLRG-Logo durch seine
   Hoehe (max. 52 px) schmaler als der Platz; stuende der Partner am rechten
   Rand, ragte er ueber das Logo hinaus.

   Dafuer ist der Kopf hier ein Grid mit EINER Spalte, deren Breite nur das
   Logo bestimmt: `width: 0` nimmt die Zeile aus der Breitenberechnung,
   `min-width: 100%` laesst sie die Spalte dann trotzdem ganz ausfuellen.
   Die Untergrenze min(100%, 320px) haelt ein sehr schmales Logo (etwa den
   Platzhalter) davon ab, Titel und Partner zusammenzuquetschen - dann endet
   der Partner eben weiter rechts als das Logo. Bewusst px und nicht rem: in
   rem wuechse die Grenze mit vergroesserter Schrift ueber die Logobreite
   hinaus, und die Logos waeren genau dann nicht mehr buendig.

   Die Basisregel fuer schmale Screens gibt .brand die volle Breite - mit
   Partner wuerde das ihn immer in die naechste Zeile schieben, deshalb hier
   zurueck auf auto. */
@media (max-width: 600px) {
    .site-header--partner {
        display: grid;
        grid-template-columns: minmax(min(100%, 320px), max-content);
        justify-content: start;
    }
    .site-header--partner .brand-zeile { width: 0; min-width: 100%; }
    .site-header--partner .brand { width: auto; }
    .brand-zeile { gap: 0.5rem 0.75rem; }
    .partner { gap: 0.5rem; }
    .partner-label { font-size: 0.75rem; }
    .partner-name { font-size: 0.85rem; }
    .partner-logo { height: 44px; max-width: 110px; }
}
.cart-badge {
    text-decoration: none;
    background: var(--dlrg-yellow);
    color: #000;
    border-radius: 999px;
    padding: 0.35rem 0.7rem;
    font-weight: bold;
    white-space: nowrap;
}

h1 { font-size: 1.5rem; }
h2 { font-size: 1.2rem; }
.lead { color: var(--color-muted); }

/* --- Notices --- */
.notice--error {
    border-left-color: var(--dlrg-red);
    background: #fff5f5;
}
.notice--error ul { margin: 0; padding-left: 1.2rem; }

/* Ruhiger Hinweis ohne Alarm: kein rotes und kein gelbes Band, nur eine graue
   Kante und ein leicht abgesetzter Grund. Fuer Auskuenfte, die man einmal
   liest und danach nicht mehr sehen muss - etwa die Erklaerung der internen
   Bestellerfassung. */
.notice--info {
    border-left-color: var(--color-muted);
    background: var(--color-bg);
}

/* --- Toasts (Flash-Meldungen) --- */
.toast-stack {
    position: fixed;
    top: 12px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1000;
    width: min(92%, 460px);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    pointer-events: none;
}
.toast {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.7rem 0.9rem;
    border-radius: var(--radius);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
    color: #fff;
    pointer-events: auto;
    animation: toast-in 0.25s ease;
}
.toast--success { background: #2e7d32; }
.toast--error   { background: var(--dlrg-red); }
.toast--warning { background: #b8860b; }
.toast--info    { background: #37474f; }
.toast-icon {
    flex: none;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.25);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: bold;
    font-size: 0.9rem;
}
.toast-text { flex: 1; line-height: 1.35; }
.toast-close {
    flex: none;
    background: none;
    border: none;
    color: inherit;
    font-size: 1.3rem;
    line-height: 1;
    cursor: pointer;
    opacity: 0.85;
}
.toast-close:hover { opacity: 1; }
.toast--hide { opacity: 0; transform: translateY(-8px); transition: opacity 0.3s, transform 0.3s; }
@keyframes toast-in { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }

/* --- Produktkarte (Bestellseite) --- */
.ord-product {
    /* Das Foto sitzt randlos oben in der Karte; overflow rundet es mit. */
    padding: 0;
    overflow: hidden;
}
.product-media { line-height: 0; }
.product-img {
    display: block;
    width: 100%;
    height: auto;
    max-height: 320px;
    object-fit: cover;
    margin: 0;
}
.product-body { padding: 1.25rem; }

.product-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--gap);
}
.product-name { font-size: 1.15rem; }
.product-price { text-align: right; white-space: nowrap; }
.product-price strong {
    display: block;
    font-size: 1.5rem;
    line-height: 1.15;
    color: var(--dlrg-red);
}
.product-price small { color: var(--color-muted); font-size: 0.8rem; }

.product-desc { margin: 0.75rem 0 0; color: var(--color-muted); }
.product-foot { margin-top: 0.75rem; }
.stock { color: var(--color-muted); font-size: 0.9rem; }
.product-card.is-soldout { opacity: 0.65; }

/* Mengenzeile: gehört zur Produktkarte und ist nur durch eine Linie
   abgesetzt. Legende und Label sind .sr-only – sichtbar genügen Stepper,
   Einheit und Summe (siehe templates/order.php). */
.ord-menge {
    margin: 1.25rem 0 0;
    padding: 1.25rem 0 0;
    border: none;
    border-top: 1px solid var(--color-border);
    border-radius: 0;
}
.qty-row { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.qty-unit { color: var(--color-muted); }
.order-total {
    margin: 0 0 0 auto;      /* schiebt die Summe an den rechten Rand */
    text-align: right;
    line-height: 1.2;
}
.order-total small { display: block; color: var(--color-muted); font-size: 0.8rem; }
.order-total strong { font-size: 1.25rem; color: var(--dlrg-red); }

/* --- Formularkarte (Bestellseite) --- */
.form-card {
    background: var(--color-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-card, var(--radius));
    box-shadow: var(--shadow-card, none);
    padding: 1.25rem;
    /* Die Kontaktfelder richten sich nach der Kartenbreite, nicht nach der
       Fensterbreite – am PC ist die Karte nur halb so breit wie die Seite. */
    container-type: inline-size;
}
.req { color: var(--dlrg-red); }

/* Hinweis direkt unter dem Feld statt der Sprechblase des Browsers. Die Blase
   haengt am Feldrand, verschwindet beim Wegklicken und laesst sich nicht
   gestalten. Erzeugt wird der Absatz von public/assets/app.js; ohne
   JavaScript bleibt die native Blase, und geprueft wird ohnehin am Server. */
.field-error {
    margin: 0.3rem 0 0;
    color: var(--dlrg-red);
    font-size: 0.85rem;
    font-weight: 600;
}
input[aria-invalid="true"],
select[aria-invalid="true"],
textarea[aria-invalid="true"] { border-color: var(--dlrg-red); }

/* Die Karte trägt den Rahmen – die Feldgruppe darin braucht keinen eigenen. */
.form-card fieldset {
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 0;
}
.form-card legend { padding: 0; font-size: 1.05rem; }

/* Einwilligung und Button schliessen die Karte ab: am Handy untereinander,
   am PC nebeneinander (siehe Media Query weiter unten). */
.order-finish { margin-top: 1.5rem; }
.order-finish .ord-consent { margin: 0; }
.order-finish .ord-submit { margin: 1.25rem 0 0; }

/* --- Abholung: ein Eintrag je Zeitfenster --- */
.pickup-options { display: grid; gap: 0.5rem; margin-top: 0.75rem; }
.pickup-option {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 0;
    padding: 0.75rem 0.9rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-weight: normal;
    cursor: pointer;
}
.pickup-option:hover { border-color: var(--color-muted); }
/* :focus-visible statt :focus-within – ein Mausklick auf das Radio setzt es
   nicht. Sonst läge beim Anklicken der Fokusring auf dem roten Rahmen der
   Auswahl und es sähe nach einem doppelten Rand aus. Per Tastatur bleibt der
   Ring erhalten. */
.pickup-option:has(:focus-visible) { outline: 2px solid var(--dlrg-red); outline-offset: 1px; }
/* Gewählter Eintrag: EIN roter Rahmen plus leichte Tönung. Ohne :has() bleibt
   der Radiopunkt die Anzeige – die Auswahl ist trotzdem klar. */
.pickup-option:has(input:checked) {
    border-color: var(--dlrg-red);
    background: #fdf3f4;
}
.pickup-option input[type="radio"] {
    flex: 0 0 auto;
    width: 1.15rem;
    height: 1.15rem;
    margin: 0;
    accent-color: var(--dlrg-red);
}
/* Kein eigener Fokusrahmen um den kleinen Kreis – die globale input:focus-Regel
   zeichnete sonst ein zweites Rechteck mitten in die Kachel. Die Anzeige
   uebernimmt die ganze Zeile (siehe :has(:focus-visible) oben). */
.pickup-option input[type="radio"]:focus { outline: none; }
/* Drei Zeilen nach Wichtigkeit: Ort, Zeit, Adresse. Der Ort steht vorn, weil
   Besteller zuerst entscheiden, wo sie vorbeikommen; mehrere Zeitfenster am
   selben Ort trennt die zweite Zeile. */
.pickup-option__text { min-width: 0; }
.pickup-option__title { display: block; font-weight: 600; }
.pickup-option__when { display: block; margin-top: 0.1rem; }
.pickup-option__note {
    margin-left: 0.4rem;
    color: var(--color-muted);
    font-weight: normal;
    font-size: 0.85rem;
}
.pickup-option__where {
    display: block;
    margin-top: 0.15rem;
    color: var(--color-muted);
    font-size: 0.9rem;
}
.pickup-option.is-full { opacity: 0.55; cursor: not-allowed; }

/* --- Kontaktfelder ---
   align-items: start - ein Fehlerhinweis unter einem Feld (app.js haengt ihn
   IN den Feldblock) macht nur seine Zelle hoeher. Das Feld daneben bleibt
   oben stehen, die Eingabefelder einer Zeile bleiben auf einer Linie. */
.contact-grid { display: grid; gap: 0 1.2rem; margin-top: 0.5rem; align-items: start; }
.field { min-width: 0; }
/* Hinweis unter einem Feld (z. B. die Laengengrenze der Bemerkung). Ein <p>
   braucht diese Regel: der Browser-Default 1em oben und unten risse im
   Kontaktraster - dessen Zeilenabstand ist 0 - eine groessere Luecke auf als
   zwischen zwei Feldern. Die Farbe kommt weiter von .muted. */
.field-hint { margin: 0.3rem 0 0; font-size: 0.9rem; }
/* Seit 1.23.0 mit getrennten Namensfeldern: ab etwa 32rem Kartenbreite zwei
   gleich breite Spalten - Vorname | Nachname, E-Mail | Telefon, darunter die
   Bemerkung ueber die ganze Breite. Schmaler eine Spalte in genau dieser
   Reihenfolge. Die fruehere Dreispaltenregel (alle Pflichtfelder in einer
   Zeile) entfaellt: mit vier Pflichtfeldern bliebe dort eine Zelle allein. */
@container (min-width: 32rem) {
    .contact-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    .field--note { grid-column: 1 / -1; }
}

/* Ueberschrift "Deine Angaben" mit dem Hilfeknopf direkt daneben. Sichtbar
   ist nur der kleine Kreis; die Klickflaeche ist 44 x 44 px (WCAG 2.5.8 und
   Fingerkuppe). Die negativen Raender nehmen dieser Flaeche ihren Platz in
   der Zeile wieder weg - die Ueberschrift wird nicht hoeher. */
.help-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin: -12px -12px -12px -8px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--color-muted);
    font: inherit;
    vertical-align: middle;
    cursor: pointer;
}
.help-btn__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border: 1.5px solid currentColor;
    border-radius: 50%;
    font-size: 0.8rem;
    font-weight: 700;
    line-height: 1;
}
.help-btn:hover { color: var(--dlrg-red); }
/* Fokusring um den sichtbaren Kreis, nicht um die unsichtbare Flaeche. */
.help-btn:focus { outline: none; }
.help-btn:focus-visible .help-btn__icon { outline: 2px solid var(--dlrg-red); outline-offset: 2px; }

/* Der Hilfedialog: weisse Karte auf leicht abgedunkeltem Grund, am PC etwa
   460px breit, mobil mit 16px Abstand zum Rand und bei Bedarf scrollbar.
   padding: 0 ist tragend - help-dialog.js erkennt den Klick auf den
   Hintergrund daran, dass er das <dialog> selbst trifft; der Inhalt liegt
   deshalb vollstaendig in .help-dialog__inner. */
.help-dialog {
    width: min(460px, calc(100vw - 32px));
    max-width: none;
    max-height: calc(100vh - 32px);
    max-height: calc(100dvh - 32px);
    margin: auto;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-card, var(--radius));
    background: var(--color-card);
    color: var(--color-text);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18);
    overflow: auto;
    overscroll-behavior: contain;
}
.help-dialog::backdrop { background: rgba(28, 28, 28, 0.45); }
.help-dialog__inner { padding: 1.25rem; }
.help-dialog__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
}
.help-dialog__head h2 { margin: 0.35rem 0 0; font-size: 1.15rem; line-height: 1.3; }
.help-dialog__close {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin: -0.5rem -0.5rem 0 0;
    padding: 0;
    border: 0;
    border-radius: var(--radius);
    background: transparent;
    color: var(--color-muted);
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
}
.help-dialog__close:hover { color: var(--dlrg-red); }
.help-dialog__close:focus { outline: none; }
.help-dialog__close:focus-visible { outline: 2px solid var(--dlrg-red); outline-offset: -4px; }
.help-list { margin: 0.9rem 0 0; }
.help-list dt { margin-top: 0.75rem; font-weight: 700; }
.help-list dt:first-child { margin-top: 0; }
.help-list dd { margin: 0.15rem 0 0; }
.help-more { margin: 1.1rem 0 0; font-size: 0.9rem; }
.help-more a { color: var(--color-muted); }

/* Textalternative ohne JavaScript (help-dialog.js blendet sie aus, sobald
   der Dialog angebunden ist): zugeklappt nur eine unauffaellige Zeile. */
.help-fallback { margin: 0.5rem 0 0.25rem; font-size: 0.95rem; }
.help-fallback summary { color: var(--color-muted); cursor: pointer; }
.help-fallback .help-list { margin-top: 0.5rem; }

/* Abholerinnerung unter der E-Mail (1.32.0): Checkbox und Fragezeichen in
   einer Zeile. Der Hilfeknopf behaelt seine 44 x 44 px Klickflaeche; die
   Ausgleichsraender des Knopfs in der Legende gehoeren nicht hierher - hier
   steht er neben einem Label, nicht in einer Ueberschrift. Der erste
   .help-btn-Block oben bleibt unveraendert (tests/help_dialog_test.js). */
.field__zusatz { margin-top: 0.6rem; }
.erinnerung-zeile { display: flex; align-items: center; gap: 0.25rem; }
.erinnerung-zeile .consent-label { margin: 0; }
.help-btn--inline { flex: 0 0 auto; margin: -10px -10px -10px 0; }
.field__zusatz .help-fallback { margin-top: 0.3rem; }
.field__zusatz .help-fallback p { margin: 0.4rem 0 0; }

/* Bestell-Layout. Mobil: Produkt, Abholung, Angaben – untereinander. */
.order-grid { display: grid; gap: var(--gap); }

/* Ab 900px: oben Produkt und Abholung nebeneinander, darunter die Angaben
   über die volle Breite. Das halbiert die Scrollstrecke am PC. */
@media (min-width: 900px) {
    .order-grid {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        column-gap: 1.5rem;
        align-items: stretch;
        grid-template-areas:
            "product pickup"
            "contact contact";
    }
    .ord-product      { grid-area: product; }
    .ord-pickup-card  { grid-area: pickup; }
    .ord-contact-card { grid-area: contact; }

    /* Beide oberen Karten gleich hoch. Damit die gewonnene Höhe nicht als
       Restfläche unten stehen bleibt, verankert die Produktkarte ihre
       Mengenzeile am unteren Rand und die Abholkarte verteilt ihre Einträge
       gleichmässig. */
    .ord-product, .ord-pickup-card { display: flex; flex-direction: column; }
    .ord-product .product-body { flex: 1; display: flex; flex-direction: column; }
    .ord-product .ord-menge { margin-top: auto; }
    .ord-pickup-card .ord-pickup { flex: 1; display: flex; flex-direction: column; }
    .ord-pickup-card .pickup-options { flex: 1; align-content: space-between; }

    /* Einwilligung links, Button rechts – spart eine Bildschirmhöhe. */
    .order-finish {
        display: flex;
        align-items: center;
        gap: 1.5rem;
    }
    .order-finish .ord-consent { flex: 1 1 auto; }
    .order-finish .ord-submit { flex: 0 0 auto; margin: 0; }
    .order-form .order-finish .actions .btn--primary { width: auto; min-width: 20rem; }
}
.badge {
    display: inline-block;
    padding: 0.2rem 0.6rem;
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: bold;
}
.badge--soldout { background: #eee; color: #555; }

/* --- Mengen-Stepper --- */
.qty-stepper {
    display: inline-flex;
    align-items: stretch;
    /* Minus, Zahlenfeld und Plus sind EINE Bedieneinheit: nie umbrechen und
       nie schrumpfen, auch nicht auf schmalen Anzeigen. */
    flex-wrap: nowrap;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
}
.qty-stepper > * { flex: 0 0 auto; }
.qty-stepper input {
    width: 3.5rem;
    text-align: center;
    border: none;
    border-left: 1px solid var(--color-border);
    border-right: 1px solid var(--color-border);
    font-size: 1.1rem;
    -moz-appearance: textfield;
}
.qty-stepper input::-webkit-outer-spin-button,
.qty-stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.qty-btn {
    min-width: 2.75rem;
    min-height: 2.75rem;
    border: none;
    background: var(--color-bg);
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
}
.qty-btn:active { background: var(--dlrg-yellow); }
/* Fokusanzeige des Mengenfelds: 2px-Ring um den GANZEN Stepper, nicht um das
   Zahlenfeld darin – dessen Ring zerschnitt das overflow:hidden des Steppers
   zu zwei roten Balken links und rechts der Zahl. 2px und outline-offset,
   damit der Ring auch WCAG 2.2 SC 2.4.13 genuegt (mind. 2px, Kontrast 4,2:1
   gegen die Karte).
   Die zweite Regel blendet ihn nach Mausbedienung aus: Texteingabefelder
   erfuellen :focus-visible IMMER, auch beim Klick – sonst spränge der Ring bei
   jedem Klick ins Zahlenfeld an. Welche Bedienart zuletzt dran war, setzt
   app.js als Klasse am <html> (js / tastatur). Fehlt JavaScript, fehlt auch
   `js` – dann bleibt es bei der ersten Regel und die Anzeige geht nie
   verloren. */
.qty-stepper input:focus, .qty-stepper .qty-btn:focus { outline: none; }
.qty-stepper:has(:focus-visible) { outline: 2px solid var(--dlrg-red); outline-offset: 2px; }
.js:not(.tastatur) .qty-stepper:has(:focus-visible) { outline: none; }

/* Fehlerzustand des Mengenfelds: aus demselben Grund wie der Fokusring am
   GANZEN Stepper, nicht am Zahlenfeld darin. Das Feld hat border:none mit je
   einer Haarlinie links und rechts; die Sammelregel input[aria-invalid="true"]
   weiter oben faerbte deshalb nur diese beiden Linien rot - zwei Balken neben
   der Zahl statt eines Rahmens. Die zweite Regel nimmt ihr den Zugriff; alle
   anderen Formularfelder behalten ihren roten Rand.
   Der box-shadow macht den Rahmen deutlich sichtbar, ohne dass die Zeile
   umspringt (Rahmenbreiten aendern das Layout, Schatten nicht). */
.qty-stepper:has(input[aria-invalid="true"]) {
    border-color: var(--dlrg-red);
    box-shadow: 0 0 0 1px var(--dlrg-red);
}
.qty-stepper input[aria-invalid="true"] { border-color: var(--color-border); }

/* --- Buttons / Aktionen --- */
.actions {
    margin: 1.5rem 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    align-items: center;
}
.btn {
    display: inline-block;
    padding: 0.85rem 1.4rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-card);
    color: var(--color-text);
    font-size: 1rem;
    font-weight: bold;
    text-decoration: none;
    cursor: pointer;
}
.btn--primary {
    background: var(--dlrg-red);
    border-color: var(--dlrg-red);
    color: #fff;
}
/* Vollbreiter Haupt-Button nur im öffentlichen Bestellfluss und im Login. */
.order-form .actions .btn--primary,
.login-form .actions .btn--primary {
    width: 100%;
}
.link-back { color: var(--dlrg-red); }

/* --- Formulare --- */
fieldset {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    margin: var(--gap) 0;
    padding: var(--gap);
}
legend { font-weight: bold; padding: 0 0.4rem; }
label {
    display: block;
    margin: 0.75rem 0 0.25rem;
    font-weight: 600;
}
input, select, textarea {
    width: 100%;
    padding: 0.7rem;
    /* Ohne font-family erbt vor allem <textarea> die Browser-Schrift und
       steht als einziges Feld in Monospace da. */
    font-family: inherit;
    font-size: 1rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-card);
}
/* Platzhalter dunkel genug zum Lesen; opacity, weil Firefox sonst aufhellt. */
::placeholder { color: var(--color-muted); opacity: 1; }
input:focus, select:focus, textarea:focus {
    outline: 2px solid var(--dlrg-red);
    outline-offset: 1px;
}
.privacy-hint { color: var(--color-muted); font-size: 0.9rem; }

/* Abhängige Einstellungsfelder (per JS ein-/ausgeblendet) dezent eingerückt. */
.cond-fields { padding-left: 0.9rem; border-left: 2px solid var(--color-border); margin-top: 0.3rem; }

/* --- Mini-Editor (WYSIWYG) für HTML-Felder --- */
.richtext { margin: 0.25rem 0 0.5rem; }
.richtext-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    padding: 0.35rem;
    border: 1px solid var(--color-border);
    border-bottom: none;
    border-radius: var(--radius) var(--radius) 0 0;
    background: var(--color-bg);
}
.richtext-btn {
    min-width: 2rem;
    width: auto;
    padding: 0.3rem 0.55rem;
    font-size: 0.9rem;
    line-height: 1;
    background: #fff;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    cursor: pointer;
    color: var(--color-text);
}
.richtext-btn:hover { background: var(--color-bg); border-color: var(--color-muted); }
.richtext-area {
    min-height: 8rem;
    padding: 0.7rem;
    border: 1px solid var(--color-border);
    border-radius: 0 0 var(--radius) var(--radius);
    background: var(--color-card);
    overflow-wrap: anywhere;
}
.richtext-area:focus { outline: 2px solid var(--dlrg-red); outline-offset: -1px; }
.richtext-area:empty::before { content: attr(data-placeholder); color: var(--color-muted); }
.richtext-area h3 { margin: 0.5rem 0 0.3rem; font-size: 1.15rem; }
.richtext-area p { margin: 0.45rem 0; }
.richtext-area ul { margin: 0.45rem 0; padding-left: 1.4rem; }
.richtext-area a { color: var(--dlrg-red); }

/* --- Einwilligung (Checkbox) --- */
.consent { margin: var(--gap) 0; }
.consent-label {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    font-weight: normal;
    margin: 0;
    cursor: pointer;
}
.consent-label input[type="checkbox"] {
    width: 1.4rem;
    height: 1.4rem;
    min-width: 1.4rem;
    margin-top: 0.1rem;
    accent-color: var(--dlrg-red);
}

/* --- Tabellen (Warenkorb/Bestätigung) --- */
.cart-table {
    width: 100%;
    border-collapse: collapse;
    margin: var(--gap) 0;
}
.cart-table th, .cart-table td {
    padding: 0.5rem;
    border-bottom: 1px solid var(--color-border);
    text-align: left;
}
.cart-table .num { text-align: right; white-space: nowrap; }
.cart-table tfoot th { border-top: 2px solid var(--color-border); border-bottom: none; }

/* --- Bestätigung / Boxen --- */
.confirm-box, .summary {
    background: var(--color-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: var(--gap);
    margin: var(--gap) 0;
}
.confirm-section { margin-top: 1.25rem; }
.qr-section { text-align: center; }
.qr-section img { border: 1px solid var(--color-border); border-radius: var(--radius); padding: 6px; background: #fff; }
.pay-hint { color: var(--dlrg-red); font-weight: 600; }
.prose { white-space: normal; }

/* =========================================================================
   Admin-Bereich
   ========================================================================= */
.muted { color: var(--color-muted); }
.btn--small { padding: 0.35rem 0.6rem; font-size: 0.85rem; width: auto; }

/* --- Wartezustand langsamer Formulare (admin.js) ---------------------------
   Der Tagesexport braucht mehrere Sekunden: vier Anhaenge bauen, je Empfaenger
   eine SMTP-Sitzung. Ohne Anzeige steht die Seite in dieser Zeit unveraendert
   da, und der naechste Klick loest eine zweite Mailrunde aus.

   Gesperrt wird ueber [data-busy] am Formular, NICHT ueber button.disabled -
   der Grund steht in admin.js. Die Regeln hier sind reine Anzeige; ohne
   JavaScript greift keine davon. */
.btn.is-busy {
    cursor: progress;
    /* Die Farbe bleibt: ein ausgegrauter Knopf saehe nach "geht nicht" aus,
       nicht nach "laeuft gerade". */
    opacity: 0.85;
}
.btn.is-busy::before {
    content: '';
    display: inline-block;
    width: 0.85em;
    height: 0.85em;
    margin-right: 0.5em;
    vertical-align: -0.1em;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: btn-spin 0.7s linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }

/* Die uebrigen Absende-Knoepfe desselben Formulars treten zurueck. Sie sind
   weiterhin sichtbar - was sie tun wuerden, soll ablesbar bleiben -, aber sie
   nehmen keine Klicks mehr an, und das Formular weist einen zweiten Versuch
   ohnehin ab. */
form[data-busy] .btn:not(.is-busy) {
    opacity: 0.45;
    pointer-events: none;
}

/* Ohne Bewegung: der Ring steht still und wird stattdessen halbtransparent.
   Die Beschriftung ("Export wird gesendet…") traegt die Aussage dann allein -
   deshalb ist sie kein Schmuck, sondern der barrierefreie Teil. */
@media (prefers-reduced-motion: reduce) {
    .btn.is-busy::before {
        animation: none;
        border-top-color: currentColor;
        opacity: 0.5;
    }
}

/* Login */
.login-wrap {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--gap);
}
.login-card {
    background: var(--color-card);
    border: 1px solid var(--color-border);
    border-top: 4px solid var(--dlrg-red);
    border-radius: var(--radius);
    padding: 1.5rem;
    width: 100%;
    max-width: 360px;
}
.login-brand {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    margin-bottom: 1rem;
    text-align: center;
}
.login-brand .logo { max-height: 44px; max-width: 100%; height: auto; width: auto; }
.login-brand small { color: var(--color-muted); }
.back-public { text-align: center; margin-top: 1rem; }
.back-public a { color: var(--color-muted); }

/* Admin-Kopf */
.admin-header {
    background: #fff;
    border-bottom: 4px solid var(--dlrg-yellow);
}
.admin-header-inner {
    max-width: var(--maxw-admin);
    margin: 0 auto;
    padding: 0.6rem var(--gap);
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}
.admin-brand {
    display: inline-flex;
    align-items: baseline;
    gap: 0.35rem;
    text-decoration: none;
    color: var(--color-text);
    font-weight: bold;
    max-width: 300px;
    overflow: hidden;
}
.admin-brand .brand-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.admin-brand-tag { color: var(--dlrg-red); flex: none; }
/* Zweizeiliger Kopf: Marke + Benutzer in Zeile 1, die volle Navi in Zeile 2.
   So passt die Navi (mit Icons) immer und bricht nicht mehr unschön um. */
.admin-menu {
    display: flex;
    flex-basis: 100%;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.45rem;
    padding-top: 0.45rem;
    border-top: 1px solid var(--color-border);
}
.admin-nav { display: flex; gap: 0.2rem; margin-right: auto; flex-wrap: wrap; }
.admin-nav a {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    text-decoration: none;
    color: var(--color-text);
    padding: 0.35rem 0.6rem;
    border-radius: var(--radius);
    white-space: nowrap;
    font-size: 0.95rem;
}
.nav-ico { flex: none; color: var(--color-muted); }
.admin-nav a:hover { background: var(--color-bg); }
.admin-nav a:hover .nav-ico { color: var(--color-text); }
/* Aktiver Punkt: dezent hinterlegt + DLRG-Rot als „Du bist hier“. */
.admin-nav a.active { background: var(--color-bg); color: var(--dlrg-red); font-weight: 600; }
.admin-nav a.active .nav-ico { color: var(--dlrg-red); }
/* Zwischen Klappmenue (bis 900 px) und breitem Kopf: seit dem Eintrag
   "Backhaus" (1.27.0) hat der Admin neun Punkte. Etwas enger gesetzt passen
   sie ab rund 1000 px wieder in eine Zeile, wie vorher die acht. */
@media (min-width: 900.02px) and (max-width: 1099.98px) {
    .admin-nav { gap: 0; }
    .admin-nav a { padding: 0.35rem 0.45rem; gap: 0.3rem; }
}
.admin-user { display: flex; align-items: center; gap: 0.6rem; }
.admin-user--top { margin-left: auto; }   /* Zeile 1 rechtsbündig */
.admin-user--menu { display: none; }       /* nur im mobilen Klappmenü sichtbar */

/* Hamburger-Button (nur mobil sichtbar) */
.nav-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 40px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: #fff;
    cursor: pointer;
    margin-left: auto;
}
.nav-toggle-bar { position: relative; width: 22px; height: 2px; background: var(--color-text); }
.nav-toggle-bar::before,
.nav-toggle-bar::after {
    content: ''; position: absolute; left: 0; width: 22px; height: 2px; background: var(--color-text);
}
.nav-toggle-bar::before { top: -7px; }
.nav-toggle-bar::after { top: 7px; }

@media (max-width: 900px) {
    .nav-toggle { display: flex; }
    .admin-user--top { display: none; }     /* oben weg, wandert ins Klappmenü */
    .admin-menu {
        display: none;
        flex-basis: 100%;
        width: 100%;
        flex-direction: column;
        align-items: stretch;
        gap: 0.5rem;
        margin-top: 0.5rem;
        padding-top: 0;
        border-top: none;
    }
    .admin-menu.open { display: flex; }
    .admin-menu .admin-nav { flex-direction: column; gap: 0.25rem; margin: 0; }
    .admin-menu .admin-nav a { padding: 0.7rem 0.8rem; border: 1px solid var(--color-border); }
    .admin-user--menu {
        display: flex;
        justify-content: space-between;
        margin-top: 0.25rem;
        padding-top: 0.6rem;
        border-top: 1px solid var(--color-border);
    }
}
.logout-form { margin: 0; }
.role-badge {
    font-size: 0.8rem;
    padding: 0.2rem 0.5rem;
    border-radius: 999px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    white-space: nowrap;
}
.role-admin { border-color: var(--dlrg-red); }

.admin-main { max-width: var(--maxw-admin); margin: 0 auto; padding: var(--gap); width: 100%; }
/* Sticky-Footer: Footer klebt unten am Fensterrand statt im Leeren zu schweben. */
.admin-app { min-height: 100vh; display: flex; flex-direction: column; }
.admin-app .admin-header { flex: none; }
.admin-app .admin-main { flex: 1 0 auto; }
.admin-app .admin-footer { flex: none; }
.admin-footer {
    width: 100%;
    max-width: var(--maxw-admin);
    margin: 1.5rem auto 1rem;
    padding: 0.6rem var(--gap);
    border-top: 1px solid var(--color-border);
    display: flex;
    justify-content: space-between;
    gap: 0.6rem;
    flex-wrap: wrap;
    font-size: 0.85rem;
    color: var(--color-muted);
}
.page-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
/* Mehrere Ausgaenge im Seitenkopf bleiben eine Gruppe: bricht die Zeile um,
   wandern sie gemeinsam unter die Ueberschrift statt einzeln auseinander. */
.page-head-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; }

/* Statistik-Karten */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: var(--gap);
    margin: var(--gap) 0;
}
.stat-card {
    background: var(--color-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}
.stat-num { font-size: 1.8rem; font-weight: bold; color: var(--dlrg-red); }
.stat-label { color: var(--color-muted); font-size: 0.9rem; }
.stat-offen .stat-num { color: #b8860b; }
.stat-abgeholt .stat-num { color: #2e7d32; }
.stat-storniert .stat-num { color: #888; }
.stat-unbestaetigt .stat-num { color: #c2410c; }
.stat-verfallen .stat-num { color: #7a2620; }
/* Anklickbare Kacheln (verlinken auf die gefilterte Bestellliste). */
a.stat-card { text-decoration: none; color: inherit; transition: border-color 0.15s, box-shadow 0.15s, transform 0.05s; }
a.stat-card:hover { border-color: var(--color-muted); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); }
a.stat-card:active { transform: scale(0.99); }

/* Laibe je Abholort: EINE Kachel, darin je Ort eine Spalte. auto-fit statt
   auto-fill: leere Spuren fallen weg, die vorhandenen Orte teilen sich die
   ganze Breite. Mit auto-fill blieben bei vier Orten rechts eine leere
   fuenfte Spalte stehen und die Namen brachen unnoetig um (1.21.1).
   min(220px, 100%) haelt die Mindestbreite unter der Kachelbreite - bei
   320 px bliebe sonst waagerechtes Scrollen. */
.pickup-note { margin: 0; font-size: 0.85rem; }
.pickup-card { margin: var(--gap) 0; }
.pickup-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
    gap: var(--gap) 1.5rem;
}
.pickup-loc { min-width: 0; padding-left: 0.75rem; border-left: 3px solid var(--color-border); }
.pickup-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.6rem;
    margin: 0 0 0.3rem;
    font-size: 1rem;
}
/* Lange Namen brechen um, die Summe bleibt neben der ersten Zeile stehen. */
.pickup-name { min-width: 0; overflow-wrap: anywhere; }
.pickup-head .stat-num { flex: none; font-size: 1.5rem; line-height: 1.1; white-space: nowrap; }
.pickup-slots { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
.pickup-slots th,
.pickup-slots td { padding: 0.3rem 0; border-top: 1px solid var(--color-border); vertical-align: top; }
.pickup-slots th { text-align: left; font-weight: normal; overflow-wrap: anywhere; }
.pickup-slots td {
    padding-left: 0.75rem;
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* Tendenz zum Vorjahr (Dashboard) und Verlaufskurve (Statistik), 1.26.0.
   Nur vorhandene Farben: Gruen wie "abgeholt", Rot wie die endgueltigen
   Handlungen, Grau wie die Nebentexte. Die Kurve bekommt ihre Farben ueber
   Klassen - style-Attribute verbietet die CSP. */
.trend-note { margin: 0.2rem 0; font-size: 0.9rem; }
.trend { display: flex; flex-direction: column; gap: 0.1rem; font-size: 0.9rem; font-variant-numeric: tabular-nums; }
.trend-delta { font-weight: bold; }
.trend--auf .trend-delta { color: #2e7d32; }
.trend--ab .trend-delta { color: var(--color-danger); }
.trend--gleich .trend-delta { color: var(--color-muted); }
.trend-prev { color: var(--color-muted); }

.stats-table th[scope="row"] { white-space: nowrap; }
.archive-fields { margin-bottom: 0.8rem; }

.season-chart { margin: var(--gap) 0; overflow-x: auto; }
.season-chart svg {
    display: block;
    width: 100%;
    max-width: 56rem;   /* breiter nur groessere Schrift, nicht mehr Information */
    height: auto;
    background: var(--color-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}
.season-chart .gitter { stroke: var(--color-border); stroke-width: 1; }
.season-chart .achse { stroke: var(--color-muted); stroke-width: 1; }
.season-chart .achse-text { fill: var(--color-muted); font: 12px var(--font); }
.season-chart .linie { fill: none; stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.season-chart .linie--aktuell { stroke: var(--dlrg-red); }
.season-chart .linie--vorjahr { stroke: var(--color-muted); stroke-dasharray: 6 4; }
/* Die Kurve skaliert mit der Breite, Schrift und Linien in Einheiten der
   viewBox mit. Schmal waeren 12 Einheiten nur noch gut 5 px - deshalb dort
   groessere Werte, statt die Kurve seitlich scrollen zu lassen. */
@media (max-width: 600px) {
    .season-chart .achse-text { font-size: 22px; }
    .season-chart .linie { stroke-width: 5; }
    .season-chart .linie--vorjahr { stroke-dasharray: 12 8; }
}
.stats-zeit { white-space: nowrap; }
.chart-legend { display: flex; flex-wrap: wrap; gap: 0.4rem 1.2rem; align-items: center; margin-top: 0.5rem; font-size: 0.9rem; }
.chart-key { display: inline-flex; align-items: center; gap: 0.4rem; font-weight: bold; }
.chart-swatch { display: inline-block; width: 1.6rem; border-top: 3px solid var(--color-muted); }
.chart-swatch.linie--aktuell { border-top-color: var(--dlrg-red); }
.chart-swatch.linie--vorjahr { border-top-style: dashed; }

/* Filter-Tabs */
.filter-tabs { display: flex; gap: 0.4rem; flex-wrap: wrap; margin: var(--gap) 0; }
.filter-tabs a {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    text-decoration: none;
    color: var(--color-text);
    padding: 0.4rem 0.8rem;
    border: 1px solid var(--color-border);
    border-radius: 999px;
}
.tab-ico { flex: none; }
.tab-count {
    min-width: 1.25rem;
    padding: 0 0.35rem;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.08);
    font-size: 0.78rem;
    font-weight: 600;
    text-align: center;
    line-height: 1.35;
}
.filter-tabs a.active .tab-count { background: rgba(255, 255, 255, 0.28); color: #fff; }
.filter-tabs a.active { background: var(--dlrg-red); color: #fff; border-color: var(--dlrg-red); }

/* Die sichtbar bleibenden Chips (Einstellungen, Protokoll) sind ein Ziel fuer
   eine Fingerkuppe: die 0.4rem Polsterung ergeben nur rund 39 px. Der
   Breakpoint allein genuegt dafuer nicht - ein Touch-Tablet mit 1024 px
   bedient dieselben Chips mit demselben Finger. Deshalb zusaetzlich
   pointer: coarse; die Sichtbarkeitsumschaltung bleibt bei 899.98px. */
@media (max-width: 899.98px), (pointer: coarse) {
    .filter-tabs a { min-height: 44px; }
}

/* Tabelle */
.table-scroll { overflow-x: auto; }
.admin-table { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
.admin-table th, .admin-table td {
    padding: 0.6rem 0.7rem;
    border-bottom: 1px solid var(--color-border);
    text-align: left;
    vertical-align: top;
}
/* Zebra-Streifen: jede zweite Zeile dezent hinterlegt. */
.admin-table tbody tr:nth-child(even) { background: rgba(0, 0, 0, 0.035); }
.admin-table tbody tr:hover { background: rgba(226, 0, 26, 0.05); }
.admin-table .num { text-align: right; white-space: nowrap; }
.admin-table .contact { font-size: 0.85rem; }
.inline-form { display: inline; margin: 0 0.15rem 0.15rem 0; }
/* Bestaetigende Aktion (fruehere .paid). Der alte Name trug eine
   Zahlungsbedeutung, die es nicht mehr gibt: bezahlt wird beim Abholen. */
.btn--ok { background: #2e7d32; color: #fff; border-color: #2e7d32; }

/* Aktionszelle der Bestellliste: hoechstens eine direkte Schaltflaeche und
   das Drei-Punkte-Menue.
   Die direkte Aktion bekommt eine gemeinsame Mindestbreite und bricht nicht
   um, das Menue steht immer ganz rechts - auch dort, wo es keines gibt
   (row-menu-spacer). Ohne beides taenzelten "Bestaetigen",
   "Wiederherstellen" und "Als abgeholt markieren" von Zeile zu Zeile. */
.row-actions { display: flex; gap: 0.4rem; align-items: center; justify-content: flex-end; }
.row-actions .inline-form { display: flex; margin: 0; }
.row-actions .btn--small {
    min-width: 11.5rem;
    white-space: nowrap;
    text-align: center;
    justify-content: center;
}
.row-menu-spacer { flex: none; width: 44px; }
.btn--icon { font-size: 1rem; line-height: 1; padding: 0.4rem 0.55rem; text-decoration: none; }

/* ---------- Bestellliste: Werkzeugleiste, Zeilenmenue, Seitenzahlen -------
 *
 * Ein gemeinsames Tabellen-Markup. Ab 900 px eine kompakte Tabelle mit fuenf
 * Spalten, darunter dieselben Zeilen als Karten (siehe Media Query weiter
 * unten). Kein zweites DOM, keine doppelten Formulare.
 */

/* Sichtbarer Tastaturfokus im Verwaltungsbereich.
 *
 * Der Ring ist DUNKEL, nicht rot: auf dem aktiven roten Filter-Chip und auf
 * .btn--primary verschwaende ein roter Ring in der Flaeche. Der helle Hof
 * setzt ihn zusaetzlich von dunklen wie von roten Untergruenden ab.
 * Der oeffentliche Bereich hat eigene, feiner abgestimmte Regeln
 * (.qty-stepper, .pickup-option) und bleibt unberuehrt. */
.admin-body a:focus-visible,
.admin-body .btn:focus-visible,
.admin-body button:focus-visible,
.admin-body summary:focus-visible,
.admin-body select:focus-visible,
.admin-body input:focus-visible {
    outline: 3px solid var(--color-text);
    outline-offset: 2px;
    box-shadow: 0 0 0 2px #fff;
}

/*
 * Der Verwaltungsbereich reserviert immer Platz fuer den Scrollbalken. Sonst
 * springt die ganze Seite seitlich, sobald ein Filter von 132 auf 4
 * Bestellungen wechselt und der Balken verschwindet.
 */
html:has(body.admin-body) { overflow-y: scroll; }
@supports (scrollbar-gutter: stable) {
    html:has(body.admin-body) { overflow-y: auto; scrollbar-gutter: stable; }
}

/* Mit JavaScript suchen Feld und Auswahlliste selbst - die zugehoerigen
   Knoepfe waeren dann nur noch Attrappen. Ohne JavaScript bleiben sie der
   einzige Weg, beides abzuschicken, und sind deshalb im Markup. */
.js .orders-search-go,
.js .pager-apply { display: none; }

.orders-search {
    display: flex;
    gap: 0.6rem;
    align-items: flex-end;
    flex-wrap: wrap;
    margin: var(--gap) 0 0.6rem;
}
.orders-search label { margin: 0 0 0.25rem; font-size: 0.9rem; }
.orders-search-field { flex: 1 1 22rem; min-width: 12rem; }
.orders-search-actions { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
.orders-filter-select select { width: auto; min-width: 12rem; }
/* Abholort und Zeitfenster (1.34.0) - auf allen Breiten sichtbar, anders als
   .orders-filter-select. Feste, gleiche Breite (1.34.1): mit width: auto war
   ein Feld so breit wie seine laengste Option, und ein langer Ortsname zog es
   samt aufgeklappter Liste in die Breite. Lange Beschriftungen kuerzt das
   Template (orders.php, $kurz) so, dass sie hineinpassen; was trotzdem
   uebersteht, endet in einer Ellipse statt abgeschnitten. */
.orders-pickup-filter select {
    width: 16rem;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ---------- Sammelaktion der Bestellliste (1.34.0) ----------
 *
 * Auswahlspalte, "Alle auf dieser Seite" und die Leiste unter der Tabelle.
 * Die Checkboxen muessen den globalen Regeln fuer input und label entkommen
 * (volle Breite, Polster, Rahmen, fette Blockbeschriftung) - wie
 * .consent-label input[type="checkbox"].
 */
.sammel-check,
.sammel-hit {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    margin: 0;
    font-weight: normal;
    cursor: pointer;
}
.sammel-check input[type="checkbox"],
.sammel-hit input[type="checkbox"] {
    width: 1.3rem;
    height: 1.3rem;
    min-width: 1.3rem;
    margin: 0;
    padding: 0;
    accent-color: var(--dlrg-red);
    cursor: pointer;
}
/* Trefferflaeche um die Checkbox: 44 px fuer den Finger, ohne dass die Zeile
   hoeher wird - der negative Rand nimmt das Polster wieder heraus. */
.sammel-hit {
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    margin: -0.6rem -0.4rem;
}
.orders-table .col-wahl { width: 1%; padding-right: 0; text-align: center; }

/* "Alle auswaehlen" hakte ohne JavaScript nichts an - erst mit Skript sichtbar. */
.sammel-alle { display: none; margin: 0 0 0.5rem; }
.js .sammel-alle { display: flex; }
.sammel-alle .sammel-check { min-height: 44px; }

/* Die Leiste: ohne JavaScript eine schlichte Zeile unter der Tabelle. Mit
   JavaScript erst sichtbar, sobald etwas angehakt ist (orders.js setzt
   .is-aktiv), dann am unteren Rand klebend. Die Vorgabe "zu" steht im CSS,
   nicht im Skript: die Live-Suche tauscht die Leiste aus, und die neue soll
   ohne Zutun wieder zu sein. */
.sammel-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem 1rem;
    margin: 0.7rem 0;
    padding: 0.7rem 0.9rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-card);
}
.js .sammel-bar:not(.is-aktiv) { display: none; }
.js .sammel-bar.is-aktiv {
    position: sticky;
    bottom: 0.5rem;
    z-index: 10;               /* unter den Zeilenmenues (20) */
    box-shadow: 0 6px 22px rgba(0, 0, 0, 0.16);
}
.sammel-bar__anzahl { margin: 0; font-weight: 600; }
.sammel-bar__knoepfe { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.sammel-bar .btn { white-space: nowrap; }
.sammel-dialog__filter { margin: 0.5rem 0 0; font-weight: 600; }
.sammel-dialog__filter:empty,
.sammel-dialog .set-frage__text:empty { display: none; }

.more-filters { margin: 0 0 0.4rem; }
.more-filters > summary {
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    color: var(--color-muted);
    font-size: 0.92rem;
}
.more-filters .filter-tabs { margin-top: 0.3rem; }

.list-count { margin: 0.2rem 0 0.7rem; color: var(--color-muted); }

/* Zwei Zeilen je Zelle: oben der Hauptwert, darunter der Zusatz. */
.cell-sub { display: block; font-size: 0.85rem; color: var(--color-muted); overflow-wrap: anywhere; }
.order-code { text-decoration: none; font-weight: 600; }
/* Stiller Hinweis auf eine Bemerkung. Klein genug, dass die Zeile nicht
   waechst, und deutlich genug, dass man ihn beim Ueberfliegen findet. */
.note-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Groesse in em statt px: der Hinweis bleibt damit innerhalb der
       Zeilenbox der Bestellnummer und die Zeile waechst um keinen Pixel. */
    width: 1.35em;
    height: 1.35em;
    margin-left: 0.4rem;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-bg);
    color: #8a5a00;
    vertical-align: middle;
}
.note-badge svg { width: 0.85em; height: 0.85em; }
/* Die Bemerkung in der Detailansicht: ruhig hervorgehoben, nicht als Warnung. */
.detail-note {
    background: #fff8e6;
    border-left: 4px solid var(--dlrg-yellow);
    border-radius: var(--radius);
    padding: 0.7rem 0.9rem;
    margin: 0.3rem 0 0;
    white-space: normal;
    overflow-wrap: anywhere;
}
.order-code code { overflow-wrap: anywhere; }
.orders-table td { vertical-align: middle; }
.orders-table .col-posten { white-space: nowrap; }
.col-actions { position: relative; text-align: right; width: 1%; white-space: nowrap; }

/* Stornierte und abgelaufene Zeilen: erkennbar, aber voll lesbar. Eine
   reduzierte Deckkraft machte frueher genau die Zeilen unleserlich, die man
   im Zweifel am genauesten liest. */
.orders-table tr.is-storniert,
.orders-table tr.is-verfallen { box-shadow: inset 3px 0 0 0 var(--color-muted); }
.orders-table tr.is-unbestaetigt { box-shadow: inset 3px 0 0 0 #e2a31a; }

/* Drei-Punkte-Menue: natives <details>. Ohne JavaScript oeffnet und schliesst
   es der Browser allein; admin.js ergaenzt Escape, Klick daneben und
   "hoechstens eines offen". */
.row-menu > summary { list-style: none; }
.row-menu > summary::-webkit-details-marker { display: none; }
/* Der Ausloeser tritt im Ruhezustand zurueck: er steht neben der grossen
   gruenen Hauptaktion und ist das Zweitrangige. Flaeche und Rahmen kommen
   beim Zeigen - und bleiben, solange das Menue offen ist. Sonst sieht man
   bei zwanzig Zeilen nicht, wessen Menue aufgeklappt ist. */
.row-menu-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;              /* Fingerkuppe, WCAG 2.5.8 */
    border: 1px solid transparent;
    border-radius: var(--radius);
    background: none;
    color: var(--color-muted);
    cursor: pointer;
    transition: background-color 0.12s, border-color 0.12s, color 0.12s;
}
.row-menu-btn:hover { background: var(--color-bg); color: var(--color-text); }
.row-menu[open] > .row-menu-btn {
    background: var(--color-bg);
    border-color: var(--color-border);
    color: var(--color-text);
}
.row-menu-list {
    position: absolute;
    right: 0;
    top: calc(100% + 6px);         /* das Menue klebt nicht am Knopf */
    z-index: 20;
    min-width: 12rem;
    padding: 0.35rem;
    background: var(--color-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    /* Zwei Lagen statt einer harten: der enge Schatten setzt die Kante ab,
       der weite hebt die Flaeche. Dieselbe Idee wie --shadow-card im Shop. */
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), 0 12px 28px rgba(0, 0, 0, 0.13);
    text-align: left;
    transform-origin: top right;
}
.row-menu-list .inline-form { display: block; margin: 0; }
.row-menu-item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    min-height: 44px;
    text-align: left;
    padding: 0.55rem 0.7rem;
    border: 0;
    border-radius: 8px;
    background: none;
    font: inherit;
    color: var(--color-text);
    text-decoration: none;         /* „Bearbeiten" ist ein <a>, „Stornieren"
                                      ein <button> - gleich aussehen muessen
                                      sie trotzdem */
    cursor: pointer;
    transition: background-color 0.12s, color 0.12s;
}
/* Tastatur und Maus bekommen dieselbe Flaeche: eine leichte Abdunklung, die
   auf jedem Grund zu sehen ist. --color-bg taugte dafuer nicht - bis 1.33.0
   war es #fafafa und auf der weissen Karte nicht zu unterscheiden. */
.row-menu-item:hover,
.row-menu-item:focus-visible { background: rgba(28, 28, 28, 0.06); }
/* Der Fokusring der Verwaltung ist 3px breit und liegt 2px aussen; sein
   weisser Saum noch 2px weiter. Das reicht ueber die Polsterung des Panels
   hinaus, also zeichnet er hier nach innen. Der Selektor braucht .admin-body:
   die allgemeine Regel oben nennt `button` und `a` mit und waere sonst
   spezifischer. */
.admin-body .row-menu-item:focus-visible { outline-offset: -2px; }
.row-menu-item svg {
    width: 17px;
    height: 17px;
    flex: none;
    color: var(--color-muted);
}
.row-menu-item:hover svg,
.row-menu-item:focus-visible svg { color: inherit; }
/* Endgueltig, aber nicht im Ruhezustand: ein dauerhaft rotes Menue in jeder
   Zeile schreit, wo es nur warnen soll. */
.row-menu-item--danger:hover,
.row-menu-item--danger:focus-visible {
    background: var(--color-danger-soft);
    color: var(--color-danger);
}
.row-menu-sep { height: 1px; margin: 0.3rem 0.4rem; background: var(--color-border); }

/* Nur beim Oeffnen. Natives <details> schliesst ohne JavaScript sofort, und
   dafuer eigene Zustandslogik zu bauen waere der Wirkung nicht angemessen.
   Die Richtung steckt allein im transform-origin: nach unten aufklappend
   waechst das Menue aus seiner oberen, nach oben aufklappend aus seiner
   unteren Ecke - beide Male also aus dem Knopf heraus. Ein verschobener
   Anfang (translateY) braeuchte dafuer zwei Keyframes und liefe in der einen
   Richtung auf den Knopf zu statt von ihm weg. */
@keyframes row-menu-in {
    from { opacity: 0; transform: scale(0.96); }
    to   { opacity: 1; transform: none; }
}
.row-menu[open] > .row-menu-list { animation: row-menu-in 120ms ease-out; }
@media (prefers-reduced-motion: reduce) {
    .row-menu[open] > .row-menu-list { animation: none; }
    .row-menu-btn, .row-menu-item { transition: none; }
}

/* Die letzten Zeilen klappen nach oben auf, sonst haengt das Menue unter der
   Seite. Es gibt hoechstens zwei Eintraege - das reicht ohne Nachmessen. */
.orders-table tbody tr:nth-last-child(-n+2) .row-menu-list {
    top: auto;
    bottom: calc(100% + 6px);
    transform-origin: bottom right;
}

/* Aktionen der Benutzerliste in zwei Darstellungen.
 *
 * Ab 900 px die Symbolknoepfe wie bisher, darunter EIN Drei-Punkte-Menue mit
 * ausgeschriebenen Schaltflaechen: drei Symbole von je 0.4rem Polsterung
 * stehen auf einem Telefon zu eng fuer eine Fingerkuppe, und untereinander
 * gestapelt machen sie die Zeile unnoetig hoch.
 *
 * Die Zelle braucht `position: relative` (ueber .col-actions), sonst haengt
 * sich das absolut positionierte Menue an einen Vorfahren weiter oben. Und
 * die Tabelle darf NICHT in einem .table-scroll stehen - ein
 * overflow-Container schnitte das aufgeklappte Menue ab. */
.users-table .row-actions-wide { display: flex; gap: 0.4rem; align-items: center; justify-content: flex-end; }
.users-table .row-actions-wide .inline-form { display: flex; margin: 0; }
.users-table .row-actions-narrow { display: none; }

/* Letzte Anmeldung (1.25.0) ebenfalls in zwei Darstellungen: ab 900 px als
 * eigene Spalte, darunter als Zeile unter dem Namen. Eine sechste Spalte liess
 * bei 320 px von den uebrigen Zellen nur Silbenstuecke uebrig. Datum und
 * Uhrzeit brechen je fuer sich nicht um - das word-break unten zerlegte sonst
 * die Jahreszahl. Umgebrochen wird nur nach dem Komma. */
.users-table .last-login-part { white-space: nowrap; }
.users-table .last-login-narrow { display: none; }

/* Die letzten beiden Zeilen klappen nach oben auf, sonst haengt das Menue
   unter der Seite. */
.users-table tbody tr:nth-last-child(-n+2) .row-menu-list {
    top: auto;
    bottom: calc(100% + 6px);
    transform-origin: bottom right;
}

@media (max-width: 899.98px) {
    .users-table .row-actions-wide { display: none; }
    .users-table .row-actions-narrow { display: block; }
    .users-table .last-login-wide { display: none; }
    .users-table .last-login-narrow { display: block; }
    /* Auf schmalen Anzeigen duerfen Name und Rolle umbrechen - so bleibt die
       Tabelle ohne overflow-Container innerhalb der Seite. */
    .users-table td, .users-table th { word-break: break-word; }
}

/* Seit 1.33.0 steht die Benutzerliste neben der Seitenleiste. Zwischen 900 und
   gut 1000 px ist die Inhaltsspalte dann schmaler als die breite Tabelle -
   ueber die Darstellung entscheidet deshalb die Breite des Listenbereichs,
   nicht die des Fensters. Bewusst ein eigener Container um die Liste und
   nicht .settings-main: ein Abfrage-Container wird Bezugsrahmen fuer fixierte
   Elemente, und die Hinweis-Toasts stehen in .settings-main. */
.users-bereich { container-type: inline-size; container-name: users-bereich; }
@container users-bereich (max-width: 47.99rem) {
    .users-table .row-actions-wide { display: none; }
    .users-table .row-actions-narrow { display: block; }
    .users-table .last-login-wide { display: none; }
    .users-table .last-login-narrow { display: block; }
    /* Nur die Namensspalte darf mitten im Wort trennen (lange Benutzernamen);
       Rolle, Status und 2FA brechen nur an Leerzeichen um. */
    .users-table td:first-child { overflow-wrap: anywhere; }
}

/* Seitenzahlen */
.pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem 1rem;
    margin: var(--gap) 0;
    padding-top: 0.8rem;
    border-top: 1px solid var(--color-border);
}
.pager-size { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; margin: 0; }
.pager-size label { margin: 0; font-weight: 400; }
.pager-size select { width: auto; padding: 0.35rem 0.5rem; }
.pager-apply { font-size: 0.8rem; }
.pager-state { margin: 0; margin-right: auto; color: var(--color-muted); }
.pager-pages { display: flex; gap: 0.2rem; list-style: none; margin: 0; padding: 0; }
.pager-num, .pager-gap {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.4rem;
    min-height: 2.4rem;
    border-radius: 8px;
    text-decoration: none;
    color: var(--color-text);
}
.pager-num:hover { background: var(--color-bg); }
.pager-num.is-current { background: var(--dlrg-red); color: #fff; font-weight: 700; }
.pager-steps { display: flex; gap: 0.4rem; }
.pager-step { min-height: 44px; display: inline-flex; align-items: center; }
.pager-step.is-disabled { opacity: 0.5; cursor: default; }

/*
 * Unter 900 px wird aus jeder Tabellenzeile eine Karte. 899.98px statt 900px:
 * bei glatt 900 griffen sonst diese Regel UND eine min-width: 900px-Regel
 * gleichzeitig (die bestehende Kopfzeilen-Regel weiter oben liegt ebenfalls
 * bei max-width: 900px).
 *
 * Die Reihenfolge auf der Karte kommt aus grid-template-areas, das DOM behaelt
 * die Spaltenfolge des Desktops. Bewusst KEINE role="table"/"row"/"cell"
 * nachruesten: hier ist es eine Kartenliste, und "Zeile 3, Spalte 2" waere
 * dafuer die falsche Ansage. Die Feldnamen liefert data-label ueber ::before.
 */
@media (max-width: 899.98px) {
    .orders-table,
    .orders-table tbody,
    .orders-table tr,
    .orders-table td { display: block; }
    .orders-table thead {          /* wie .sr-only: vorlesbar, unsichtbar */
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        overflow: hidden;
        clip-path: inset(50%);
    }
    .orders-table tr {
        display: grid;
        /* minmax(9rem, ...) gibt der Bestellnummer einen Boden, minmax(0, auto)
           deckelt die Statusspalte: Pille und Anpassungs-Badge stapeln sich
           dann untereinander, statt die Bestellnummer in eine
           Buchstabensaeule zu zerlegen. */
        grid-template-columns: minmax(9rem, 1fr) minmax(0, auto);
        grid-template-areas:
            "kunde    status"
            "abholung abholung"
            "posten   posten"
            "aktion   aktion";
        gap: 0.35rem 0.75rem;
        border: 1px solid var(--color-border);
        border-radius: var(--radius);
        padding: 0.85rem;
        margin-bottom: 0.7rem;
        background: var(--color-card);
    }
    .orders-table tbody tr:nth-child(even) { background: var(--color-card); }  /* kein Zebra */
    .orders-table tbody tr:hover { background: var(--color-card); }
    .orders-table td { border-bottom: 0; padding: 0; }
    /* Karten mit Auswahl (1.34.0): die Checkbox links neben Bestellnummer
       und Status, alles Weitere ueber die volle Breite. Karten ohne
       anhakbare Bestellung behalten ihr Raster; ihre leere Auswahlzelle
       faellt weg, sonst stuende sie als eigene Zeile in der Karte. */
    .orders-table tr.has-wahl {
        grid-template-columns: auto minmax(9rem, 1fr) minmax(0, auto);
        grid-template-areas:
            "wahl     kunde    status"
            "abholung abholung abholung"
            "posten   posten   posten"
            "aktion   aktion   aktion";
    }
    .orders-table .col-wahl { grid-area: wahl; width: auto; padding: 0; align-self: center; }
    .orders-table tr:not(.has-wahl) .col-wahl { display: none; }
    .orders-table .sammel-hit { margin: -0.4rem 0 -0.4rem -0.4rem; }
    .orders-table .col-kunde { grid-area: kunde; }
    .orders-table .col-status { grid-area: status; justify-self: end; text-align: right; }
    .orders-table .col-abholung { grid-area: abholung; }
    .orders-table .col-posten { grid-area: posten; white-space: normal; }
    .orders-table .col-actions {
        grid-area: aktion;
        text-align: left;
        /* width: 1% ist der Shrink-to-fit-Kniff der TABELLE. Auf der Karte
           ist die Zelle ein Grid-Element, dort meint 1% woertlich ein
           Prozent - die Zelle waere ~3px breit, und das mit right:0 daran
           haengende Menue laege links neben dem Bildschirm. */
        width: auto;
        white-space: normal;
    }
    .orders-table td[data-label]::before {
        content: attr(data-label) ": ";
        color: var(--color-muted);
        font-size: 0.8rem;
    }
    /* Auf dem Telefon wird getippt, nicht geklickt: die Bestellnummer und das
       Anpassungs-Badge sind Links mitten im Text und waeren mit ihrer
       Zeilenhoehe von rund 20 px eine Zumutung fuer eine Fingerkuppe. Der
       negative Rand haelt die Karte trotzdem kompakt. */
    .orders-table .order-code {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
        margin-block: -0.6rem;   /* allein in seiner Zelle - der Rand haelt die Karte kompakt */
    }
    /* Die Statuszelle traegt zwei Dinge untereinander: Pille und
       Anpassungs-Badge. Hier waere ein negativer Rand falsch - er zoege das
       Badge in die Pille hinein. Stattdessen eine Spalte mit Abstand. */
    .orders-table .col-status {
        display: flex;
        flex-direction: column;
        align-items: flex-end;
        gap: 0.25rem;
    }
    .orders-table .chg-badge {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
        margin: 0;
    }
    .pager-size select { min-height: 44px; }

    .orders-table .row-actions { justify-content: flex-start; flex-wrap: wrap; }
    .orders-table .row-actions .btn--small { min-width: 0; flex: 1 1 auto; }
    .row-menu-spacer { display: none; }   /* auf der Karte braucht es keinen Platzhalter */
    .orders-page .btn--small { min-height: 44px; padding: 0.6rem 0.9rem; }

    /* Mobil: Auswahlfeld statt Chips - aber NUR auf der Bestellliste. Ungescopt
       traf die Regel jede .filter-tabs, also auch die Einstellungs-
       Unternavigation (.filter-tabs.settings-subnav) und den Protokollfilter;
       beide waren unter 900 px schlicht unerreichbar.
       Inzwischen bringt jede der drei Navigationen ihren eigenen Ersatz mit
       (.settings-nav-select, .log-filter-select) - und jede blendet ihre
       Chips ueber eine EIGENE, gescopte Regel aus. Diese hier bleibt deshalb
       an .orders-page gebunden. */
    .orders-page .filter-tabs,
    .orders-page .more-filters { display: none; }
    .orders-search { align-items: stretch; }
    .orders-search-field, .orders-filter-select { flex: 1 1 100%; }
    .orders-filter-select select { width: 100%; }
    /* min-width: 0 und max-width: 100%: ein Auswahlfeld waechst sonst auf
       die Breite seiner laengsten Option und schiebt die Seite seitlich. */
    .orders-pickup-filter { flex: 1 1 100%; min-width: 0; }
    .orders-pickup-filter select { width: 100%; min-width: 0; max-width: 100%; }
    .sammel-bar__knoepfe { flex: 1 1 100%; }
    .sammel-bar__knoepfe .btn { flex: 1 1 auto; }

    .pager { flex-direction: column; align-items: stretch; }
    .pager-pages { display: none; }                  /* mobil: Zurueck - Seite X von Y - Weiter */
    .pager-state { text-align: center; margin-right: 0; }
    .pager-steps { justify-content: space-between; }
    .pager-size { order: 2; justify-content: center; }
}

/* Ab 900 px uebernehmen die Chips den Filter. */
@media (min-width: 900px) {
    .orders-filter-select { display: none; }
}

/* Protokollfilter: dasselbe Muster wie die Bestellliste - ab 900 px die
   Chips, darunter ein Auswahlfeld. Sieben Chips brauchen auf einem Telefon
   vier Zeilen.

   Die Regel, die die Chips ausblendet, ist ueber `.log-filter-tabs` gescopt.
   Das ist Pflicht, kein Stil: ungescopt traefe sie jede `.filter-tabs`, also
   auch die Einstellungs-Unternavigation - genau das war der Fehler, der
   1.10.1 ausgeloest hat. */
.log-filter-select { margin: var(--gap) 0; }
.log-filter-select label { display: block; margin-bottom: 0.25rem; font-size: 0.9rem; }
.log-filter-select select { width: 100%; min-height: 44px; }   /* Fingerkuppe, WCAG 2.5.8 */
.log-filter-apply { margin-top: 0.5rem; }
/* Mit JavaScript schickt die Auswahl sich selbst ab (forms.js, data-autosubmit);
   ohne JavaScript ist der Knopf der einzige Weg und bleibt deshalb stehen. */
.js .log-filter-apply { display: none; }

@media (min-width: 900px) {
    .log-filter-select { display: none; }
}
@media (max-width: 899.98px) {
    .log-filter-tabs { display: none; }
}

/* Datenbank-Wartung: Gefahrenbereich + roter Button */
.danger-zone { border: 1px solid #e6b0aa; background: #fdf3f2; }
.danger-zone h2 { color: #a32d2d; }
.btn--danger { background: #c0392b; color: #fff; border-color: #c0392b; }
.btn--danger:hover { background: #a93226; border-color: #a93226; }

/* Changelog */
.changelog { max-width: 720px; }
.changelog-entry { margin-bottom: 1.4rem; }
.changelog-entry h2 { font-size: 1.05rem; margin: 0 0 0.4rem; color: var(--dlrg-red); }
.changelog-entry ul { margin: 0; padding-left: 1.3rem; }
.changelog-entry li { margin: 0.25rem 0; }
.admin-footer a { color: var(--color-muted); }

/* Inline-Warnung in Formularen (z. B. widersprüchliche Einstellungen) */
.form-warn {
    color: #8a4b00;
    background: #ffe9c7;
    border: 1px solid #f0c36d;
    border-radius: var(--radius);
    padding: 0.6rem 0.8rem;
    margin: 0.6rem 0;
    font-size: 0.92rem;
}

/* Export-Seite */
.export-form { max-width: 520px; }
.export-form select { max-width: 340px; }
.export-count { margin-top: 0.9rem; }
.export-actions { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-top: var(--gap); }
.export-hint { margin-top: 0.9rem; font-size: 0.9rem; }
.export-form .switch { margin-top: 0.9rem; }
.export-reset { margin: 0.6rem 0 0; font-size: 0.92rem; }
/* Die Voreinstellung steht ueber dem Formular: sie setzt alle Felder auf
   einmal und ist deshalb kein Teil eines Fieldsets. */
.export-preset { max-width: 520px; margin-top: var(--gap); }
.export-preset p { margin: 0.5rem 0 0; font-size: 0.9rem; }

/* Ab 900px: Filter links, Reihenfolge und Darstellung rechts - dasselbe
   Muster wie .order-grid. Einspaltig stand rechts nur leere Flaeche.
   Knoepfe und Hinweis laufen darunter ueber beide Spalten, die
   Voreinstellung wird zur Zeile aus Knopf und Erklaerung. Die Hinweistexte
   behalten eine lesbare Zeilenlaenge. */
@media (min-width: 900px) {
    .export-form {
        max-width: none;
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        column-gap: 1.5rem;
        align-items: stretch;
    }
    .export-form > fieldset { margin-bottom: 0; }
    .export-form > .export-actions,
    .export-form > .export-hint { grid-column: 1 / -1; }
    .export-form select { max-width: none; }
    .export-hint { max-width: 75ch; }
    .export-preset { max-width: none; display: flex; align-items: center; gap: 1.2rem; }
    .export-preset .btn { flex-shrink: 0; }
    .export-preset p { margin: 0; max-width: 75ch; }
}

/* Listen-Werkzeugleiste (Filter + Aktion) */
.list-toolbar {
    display: flex;
    gap: 0.6rem;
    align-items: center;
    flex-wrap: wrap;
    margin: var(--gap) 0;
}
.list-toolbar input[type="search"] { flex: 1; min-width: 200px; }
.filter-empty { margin-top: 0.5rem; }

/* Status traegt Icon UND Wort, nicht nur Farbe. */
.status-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    font-size: 0.8rem;
    font-weight: bold;
}
.status-pill .tab-ico { width: 13px; height: 13px; }
.status-offen { background: #fff3cd; color: #7a5c00; }
.status-abgeholt { background: #d7f0d8; color: #1e5e22; }
.status-storniert { background: #eee; color: #666; }
.status-unbestaetigt { background: #ffe0b2; color: #8a4b00; }
.status-verfallen { background: #e2c4c0; color: #7a2620; }

/* 2FA-Status der Benutzerliste. Eigene Klassen statt der Bestellstatus-Pillen:
   dieselben Farben, aber die Benutzerliste haengt fachlich nicht an den
   Bestellzustaenden - wer die spaeter umfaerbt, faerbt sonst hier mit.
   Orange, nicht rot: "Einrichtung erforderlich" ist ein normaler
   Zwischenstand, kein Fehler. */
.mfa-aktiv { background: #d7f0d8; color: #1e5e22; }
.mfa-offen { background: #ffe0b2; color: #8a4b00; }
.mfa-entfaellt { background: #eee; color: #666; }

/* Bestätigungs-Hinweis auf der Bestätigungsseite (Double-Opt-in offen) */
.confirm-pending {
    background: #fff8e6;
    border: 1px solid #f0c36d;
    border-left: 5px solid #e2a31a;
    border-radius: var(--radius);
    padding: 1rem 1.2rem;
    margin-bottom: var(--gap);
}
.confirm-pending h1 { margin: 0 0 0.4rem; color: #8a5a00; font-size: 1.15rem; }
.confirm-pending p { margin: 0.3rem 0; }
.confirm-pending-hint { font-size: 0.9rem; color: var(--color-muted); }

/* Anpassungs-Badge + Bestelldetail/Verlauf */
.chg-badge {
    display: inline-block;
    background: var(--dlrg-yellow);
    color: #5a4500;
    border-radius: 999px;
    padding: 0.1rem 0.5rem;
    font-size: 0.8rem;
    font-weight: bold;
    text-decoration: none;
    white-space: nowrap;
}
.detail-grid { display: grid; gap: var(--gap); margin-top: var(--gap); }
@media (min-width: 760px) { .detail-grid { grid-template-columns: 1.2fr 1fr; align-items: start; } }
.detail-grid h2 { font-size: 1.05rem; margin: 1rem 0 0.3rem; }
.detail-grid h2:first-child { margin-top: 0; }
.history { list-style: none; margin: 0; padding: 0; }
.history li {
    padding: 0.5rem 0 0.5rem 0.9rem;
    border-left: 2px solid var(--dlrg-yellow);
    margin-bottom: 0.3rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.1rem 0.5rem;
    align-items: baseline;
}
.history .hist-time { font-size: 0.8rem; flex-basis: 100%; }
.history .hist-act { font-weight: bold; }
/* Der zusammengefasste Verlaufseintrag von /admin/orders/edit ist deutlich
   laenger als bisherige Details ("Menge 3 → 5; Telefon … → …; Abholort …").
   .history li ist display:flex - ohne min-width:0 schrumpft das Feld nicht
   unter seinen laengsten Inhalt und schiebt die Zeile aus der Karte. */
.history .hist-det { min-width: 0; overflow-wrap: anywhere; }
/* Der zusammengefasste Eintrag von /admin/orders/edit nennt bis zu sieben
   Felder auf einmal. Je Feld eine Zeile, Beschriftung und Wert in zwei
   Spalten - dt/dd sind direkte Kinder des Rasters, es braucht also kein
   display:contents und die Liste behaelt ihre Semantik.

   flex-basis:100%, weil .history li ein Flex-Container ist: ohne das saesse
   die Liste neben der Aktion statt darunter. */
.history .hist-fields {
    flex-basis: 100%;
    margin: 0.15rem 0 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: 0 0.75rem;
    font-size: 0.95rem;
}
.history .hist-fields dt {
    font-weight: 600;
    color: var(--color-muted);
}
/* anywhere und nicht break-word: eine lange Adresse oder ein Zeitfenster
   muss auch dann in die Karte passen, wenn kein Leerzeichen darin steht. */
.history .hist-fields dd {
    margin: 0 0 0.25rem;
    min-width: 0;
    overflow-wrap: anywhere;
}
/* Erst wenn wirklich Platz ist, wandert der Wert neben die Beschriftung.
   Darunter stuende die Spalte so schmal, dass jeder Wert umbraeche. */
@media (min-width: 560px) {
    .history .hist-fields { grid-template-columns: max-content 1fr; }
    .history .hist-fields dd { margin-bottom: 0.1rem; }
}

/* Einstellungen */
/* Die Unternavigation der Einstellungen. Seit 1.33.0 hat sie ihr eigenes
   Aussehen und borgt nicht mehr bei .filter-tabs: auf der Einstellungsseite
   ist sie ab 900 px eine Seitenleiste (siehe "Einstellungsseite" weiter
   unten), ueberall sonst - Benutzerseiten, ohne JavaScript unter 900 px -
   eine Reihe von Chips wie bisher. Sie fuehrt als einzige in die uebrigen
   Einstellungsbereiche; deshalb steht display hier ausdruecklich.

   Unter 900 px treten die Chips an das Auswahlfeld darunter ab (siehe dort).
   OHNE JavaScript bleiben sie auf jeder Breite stehen - dann sind sie wieder
   der einzige Weg. */
.settings-subnav { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: var(--gap) 0; }
.settings-subnav a {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.8rem;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-card);
    color: var(--color-text);
    text-decoration: none;
}
.settings-subnav a.active { background: var(--dlrg-red); border-color: var(--dlrg-red); color: #fff; }
.settings-subnav .nav-ico { flex: none; color: var(--color-muted); }
.settings-subnav a.active .nav-ico { color: currentColor; }
/* Der Punkt ist nur Grafik - was er meint, steht im Text, den
   aria-describedby dem Link zuordnet (helpers.php, admin_settings_nav). */
.settings-subnav__dot { flex: none; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: #c2410c; }
.settings-subnav a.active .settings-subnav__dot { background: #fff; }
@media (max-width: 899.98px), (pointer: coarse) {
    .settings-subnav a { min-height: 44px; }
}

/* Mobiler Ersatz fuer die Chips: sechs Chips brauchen auf einem Telefon
   mehrere Zeilen, ein Auswahlfeld eine.

   Der Tausch haengt an `.js`, und zwar zwingend: ein Auswahlfeld navigiert
   nicht von selbst. Ohne JavaScript waere ein sichtbares Feld eine Sackgasse -
   dann bleibt es bei den Chips. (Das Auswahlfeld der Bestellliste darf das
   anders halten: es steckt in einem echten GET-Formular.)

   Ab 900 px greift der Media-Query nicht: Chips sichtbar, Auswahlfeld weg. */
.settings-nav-select { display: none; margin-bottom: var(--gap); }
.settings-nav-select label { display: block; margin-bottom: 0.25rem; font-size: 0.9rem; }
.settings-nav-select select { width: 100%; min-height: 44px; }   /* Fingerkuppe, WCAG 2.5.8 */

@media (max-width: 899.98px) {
    .js .settings-nav-select { display: block; }
    .js .settings-subnav { display: none; }
}

/* Sprungmarken innerhalb eines Panels. Bewusst KEINE Chips: sie muessen sich
   den Hauptreitern unterordnen, sonst stuenden zwei gleich aussehende
   Navigationen uebereinander und es saehe nach zwei Ebenen Tabs aus. */
.section-jump {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.2rem 0.9rem;
    margin: 0 0 var(--gap);
    font-size: 0.92rem;
}
.section-jump-label { color: var(--color-muted); }
.section-jump a {
    display: inline-flex;
    align-items: center;
    color: var(--color-text);
    text-decoration: underline;
    text-underline-offset: 3px;
}
.section-jump a:hover { color: var(--dlrg-red); }
/* Kein outline: none - der Fokusrahmen des Browsers bleibt die Anzeige. */
@media (max-width: 899.98px), (pointer: coarse) {
    .section-jump a { min-height: 44px; }
}

/* Tab-Panels: ohne JS alle sichtbar; mit JS (.tabs-on) nur das aktive. */
.settings-tabs.tabs-on .tab-panel { display: none; }
.settings-tabs.tabs-on .tab-panel.is-active { display: block; }
/* Klebende Speicherleiste (seit 1.33.0 als eigene Leiste). Solange nichts
   geaendert ist, ruhig und hell; mit ungespeicherten Aenderungen dunkel, mit
   Zustandstext und "Verwerfen" (settings.js). Der leere Zustandstext
   verschwindet ganz - dann stehen die Knoepfe rechts. */
.settings-save {
    position: sticky;
    bottom: 0;
    z-index: 30;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 0.6rem;
    margin: 1.25rem 0 0;
    padding: 0.7rem 1rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius) var(--radius) 0 0;
    background: var(--color-card);
    box-shadow: 0 -6px 18px rgba(0, 0, 0, 0.07);
}
.settings-save__status { margin: 0 auto 0 0; font-weight: 600; }
.settings-save__status:empty { display: none; }
.settings-save__status::before {
    content: '';
    display: inline-block;
    width: 0.6rem;
    height: 0.6rem;
    margin-right: 0.5rem;
    border-radius: 50%;
    background: var(--dlrg-yellow);
    vertical-align: 0.05em;
}
.settings-save.is-dirty { background: var(--color-text); border-color: var(--color-text); color: #fff; }
.settings-save.is-dirty .btn:not(.btn--primary) {
    background: transparent;
    border-color: rgba(255, 255, 255, 0.55);
    color: #fff;
}
/* Auf der dunklen Leiste waere der dunkle Admin-Fokusring unsichtbar. */
.admin-body .settings-save.is-dirty .btn:focus-visible { outline-color: #fff; box-shadow: 0 0 0 2px var(--color-text); }
/* Ein fokussiertes Feld soll nicht unter der klebenden Leiste landen. */
html:has(.settings-save) { scroll-padding-bottom: 5.5rem; }
/* Handy: Zustand und "Verwerfen" teilen sich eine Zeile, "Speichern" steht
   in voller Breite darunter - zwei Zeilen statt drei. */
@media (max-width: 599.98px) {
    .settings-save { padding: 0.6rem 0.75rem; }
    .settings-save__status { flex: 1 1 0; min-width: 0; margin: 0; font-size: 0.9rem; }
    .settings-save [data-dirty-discard] { flex: 0 0 auto; min-height: 44px; padding: 0.45rem 0.75rem; font-size: 0.92rem; }
    .settings-save .btn--primary { flex: 1 1 100%; }
}
.settings-form fieldset { background: var(--color-card); }
.settings-form hr { border: none; border-top: 1px solid var(--color-border); margin: 1rem 0; }
.switch {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    font-weight: 600;
    margin: 0.8rem 0 0.2rem;
    cursor: pointer;
}
.switch input[type="checkbox"] {
    width: 1.3rem;
    height: 1.3rem;
    min-width: 1.3rem;
    margin-top: 0.1rem;
    accent-color: var(--dlrg-red);
}

/* =========================================================================
   Einstellungsseite (seit 1.33.0): Seitenleiste, Karten, Zeilen
   Alle Klassen beginnen mit settings- oder set- und gelten nur hier. Die
   uebrigen Formulare mit .settings-form (Abholorte, Bestellung bearbeiten,
   Brot, Benutzer) behalten ihr Aussehen.
   ========================================================================= */

/* Geruest: mobil untereinander, ab 900 px Seitenleiste | Inhalt. Die
   Seitenleiste klebt beim Scrollen - sticky, nicht fixed: fixed naehme ihr
   den offsetParent, und der Navigationstest hielte sie fuer unsichtbar. */
.settings-main { min-width: 0; }
@media (min-width: 900px) {
    .settings-shell {
        display: grid;
        grid-template-columns: 13.5rem minmax(0, 1fr);
        gap: 0 1.75rem;
        align-items: start;
    }
    .settings-aside { position: sticky; top: 1rem; }
    .settings-main { max-width: 60rem; }

    .settings-shell .settings-subnav {
        flex-direction: column;
        flex-wrap: nowrap;
        gap: 2px;
        margin: 0;
    }
    .settings-shell .settings-subnav a {
        position: relative;
        display: flex;
        gap: 0.65rem;
        padding: 0.6rem 0.75rem;
        border-color: transparent;
        border-radius: var(--radius);
        background: transparent;
    }
    .settings-shell .settings-subnav a:hover { background: rgba(0, 0, 0, 0.045); }
    .settings-shell .settings-subnav a.active {
        background: var(--color-card);
        border-color: var(--color-border);
        color: var(--dlrg-red);
        font-weight: 600;
    }
    .settings-shell .settings-subnav a.active::after {
        content: '';
        position: absolute;
        left: -1px;
        top: 0.45rem;
        bottom: 0.45rem;
        width: 3px;
        border-radius: 0 3px 3px 0;
        background: var(--dlrg-red);
    }
    .settings-shell .settings-subnav .nav-ico { width: 18px; height: 18px; }
    .settings-shell .settings-subnav a.active .nav-ico { color: var(--dlrg-red); }
    .settings-shell .settings-subnav__dot { margin-left: auto; }
    .settings-shell .settings-subnav a.active .settings-subnav__dot { background: #c2410c; }
    /* "Benutzerverwaltung" ist eine eigene Seite, kein Bereich dieser Seite:
       eine Trennlinie darueber. */
    .settings-shell .settings-subnav a:not([data-tab]) { margin-top: 0.9rem; }
    .settings-shell .settings-subnav a:not([data-tab])::before {
        content: '';
        position: absolute;
        left: 0.75rem;
        right: 0.75rem;
        top: calc(-0.45rem - 1px);
        border-top: 1px solid var(--color-border);
    }
}

/* Kopf eines Bereichs */
.set-panel__head { margin: 0 0 1rem; }
.set-panel__title { margin: 0; font-size: 1.35rem; line-height: 1.25; }
.set-panel__lead { margin: 0.25rem 0 0; color: var(--color-muted); }

/* Karte = <fieldset>. Die Legende wird per float zur Kopfzeile: eine
   schwebende Legende ist keine "gerenderte Legende", der Rahmen bekommt keine
   Luecke, und sie laesst sich wie ein gewoehnlicher Block gestalten (dieselbe
   Technik nutzt Bootstrap). `~ *` statt `+ *`, damit auch ein erstes
   Geschwister mit hidden die Nachfolger nicht neben die Legende rutschen
   laesst. min-inline-size: 0 hebt die Mindestbreite auf, mit der ein
   Fieldset sonst jede breite Tabelle mitwachsen liesse. */
.set-card {
    min-inline-size: 0;
    margin: 0 0 1.25rem;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-card);
}
.set-card > legend {
    float: left;
    width: 100%;
    margin: 0;
    padding: 1rem 1.15rem 0.2rem;
    font-size: 1.1rem;
    font-weight: 700;
    line-height: 1.3;
}
.set-card > legend ~ * { clear: both; }
.set-card__intro { padding: 0 1.15rem 0.9rem; color: var(--color-muted); font-size: 0.95rem; }
.set-card__intro p { margin: 0; }
.set-card__intro .help-fallback { margin: 0.5rem 0 0; }
.set-card__intro .help-fallback p { margin: 0.5rem 0 0; color: var(--color-text); }
.set-card__warnungen { padding: 0.35rem 1.15rem 0.1rem; }
.set-card__warnungen .form-warn { margin: 0 0 0.75rem; }

/* Knopf, der wie ein Link aussieht (oeffnet einen Hilfedialog). */
.set-link {
    display: inline-block;
    margin: 0.25rem 0 0;
    padding: 0.35rem 0;
    border: 0;
    background: none;
    color: var(--color-text);
    font: inherit;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
}
.set-link:hover { color: var(--dlrg-red); }
@media (max-width: 899.98px), (pointer: coarse) {
    .set-link { min-height: 44px; }
}

/* Eine Einstellung = eine Zeile: Bezeichnung und kurze Erklaerung links, das
   Feld rechts. Unter 900 px untereinander; Schalter bleiben auch dort rechts
   neben ihrer Bezeichnung. --stack fuer alles, was Breite braucht
   (Textfelder, Editoren, Uploads, Tabellen). */
.set-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 0.5rem 1.5rem;
    padding: 0.85rem 1.15rem;
    border-top: 1px solid var(--color-border);
}
.set-row--switch { grid-template-columns: minmax(0, 1fr) auto; align-items: center; }
@media (min-width: 900px) {
    .set-row { grid-template-columns: minmax(0, 1fr) minmax(15rem, 42%); align-items: center; }
    .set-row--stack { grid-template-columns: minmax(0, 1fr); }
    .set-row--switch { grid-template-columns: minmax(0, 1fr) auto; }
}
/* Die Textspalte ist ein gewoehnlicher Block, kein Flex-Container: so bleibt
   das "?" beim Umbruch am letzten Wort der Bezeichnung haengen, statt allein
   in eine eigene Zeile zu rutschen. */
.set-row__text { position: relative; min-width: 0; }
.set-row__label { display: inline; margin: 0; font-weight: 600; }
.set-row__desc { margin: 0.15rem 0 0; color: var(--color-muted); font-size: 0.9rem; }
.set-row__control { min-width: 0; }
.set-input--zahl { max-width: 9rem; }

/* Abhaengige Unterfelder haengen eingerueckt unter ihrem Schalter. Kein
   display hier - das steuert allein [hidden] (settings_cond_fields_test.js). */
.set-card .cond-fields {
    margin: 0 1.15rem 0.85rem 1.6rem;
    padding-left: 0;
    border-left: 2px solid var(--color-border);
}
.set-card .cond-fields .set-row { padding-right: 0; padding-left: 1rem; }
.set-card .cond-fields > .set-row:first-child { border-top: 0; }

/* Kippschalter: ein gewoehnliches Kontrollkaestchen, nur anders gezeichnet.
   Der Knopf ist ein Verlauf auf dem Feld selbst (keine Pseudo-Elemente an
   einem <input>). Grau = aus, gruen = an. Im Kontrastmodus des Systems
   zeichnet der Browser wieder sein eigenes Kaestchen. */
.set-switch {
    -webkit-appearance: none;
    appearance: none;
    flex: none;
    width: 2.9rem;
    height: 1.7rem;
    margin: 0;
    padding: 0;
    border: 1px solid #8a8a8a;
    border-radius: 999px;
    background: #d6d6d6 radial-gradient(circle at 0.82rem 50%, #fff 0.58rem, transparent 0.62rem) no-repeat;
    cursor: pointer;
    vertical-align: middle;
}
.set-switch:checked {
    border-color: #2e7d32;
    background-color: #2e7d32;
    background-position: 1.14rem 0;
}
.set-switch:focus:not(:focus-visible) { outline: none; }
@media (prefers-reduced-motion: no-preference) {
    .set-switch { transition: background-color 0.15s, background-position 0.15s; }
}
@media (forced-colors: active) {
    .set-switch { -webkit-appearance: auto; appearance: auto; width: 1.3rem; height: 1.3rem; }
}

/* "?"-Hilfe. Ohne JavaScript steht der Text unter der Bezeichnung; mit
   JavaScript (settings.js) wird er zur Sprechblase: ab 900 px schwebend
   unter der Bezeichnung, darunter aufgeklappt in der Zeile. */
.help-btn--tip { margin: -12px -12px -12px -6px; }
.set-hint { margin: 0.35rem 0 0; font-size: 0.9rem; }
.set-hint p { margin: 0; }
.set-hint p + p { margin-top: 0.4rem; }
.set-hint--tip {
    padding: 0.7rem 0.85rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-bg);
    color: var(--color-text);
    line-height: 1.45;
}
@media (min-width: 900px) {
    .set-hint--tip {
        position: absolute;
        z-index: 20;
        top: calc(100% + 0.4rem);
        left: 0;
        width: min(28rem, 100%);
        margin: 0;
        background: var(--color-card);
        box-shadow: 0 10px 28px rgba(0, 0, 0, 0.14);
    }
}
/* Fokusring um den sichtbaren Kreis, nicht um die 44-px-Flaeche. */
.admin-body .help-btn:focus-visible { outline: none; box-shadow: none; }
.admin-body .help-btn:focus-visible .help-btn__icon { outline: 3px solid var(--color-text); outline-offset: 2px; }

/* Stand und Kennzahlen innerhalb einer Karte */
.set-status {
    padding: 0.85rem 0 0.2rem 1rem;
    border-top: 1px solid var(--color-border);
    font-size: 0.95rem;
}
.set-status__zeile { margin: 0 0 0.6rem; }
.set-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0 0 0.6rem; padding: 0; list-style: none; }
.set-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.2rem 0.65rem;
    border-radius: 999px;
    background: #efefef;
    color: var(--color-text);
    font-size: 0.85rem;
    font-weight: 600;
    white-space: nowrap;
}
.set-chip--ok { background: #d7f0d8; color: #1e5e22; }
.set-chip--warn { background: #ffe9c7; color: #8a4b00; }
.set-details { margin: 0 0 0.6rem; }
.set-details summary { padding: 0.35rem 0; font-weight: 600; cursor: pointer; }
.set-details[open] summary { margin-bottom: 0.4rem; }
@media (max-width: 899.98px), (pointer: coarse) {
    .set-details summary { padding: 0.65rem 0; }
}
.set-faelle { margin: 0 0 0.6rem; padding-left: 1.2rem; }
.set-status .admin-table { font-size: 0.85rem; }
.set-status .admin-table th, .set-status .admin-table td { padding: 0.5rem 0.55rem; }
.set-status .admin-table th { white-space: nowrap; }

/* Fuss einer Karte: die Zusatzaktionen (Testmail, Muster, Export). Abgesetzt
   vom Speichern ganz unten - sie speichern zwar mit, tun aber mehr. */
.set-card__footer {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem 1rem;
    padding: 0.9rem 1.15rem;
    border-top: 1px solid var(--color-border);
    border-radius: 0 0 var(--radius) var(--radius);
    background: var(--color-bg);
}
.set-card__footer-field { flex: 1 1 16rem; min-width: 0; }
.set-card__footer-field label { margin: 0 0 0.3rem; }
.set-card__footer-note { flex-basis: 100%; margin: 0; color: var(--color-muted); font-size: 0.9rem; }
@media (max-width: 599.98px) {
    .set-card__footer .btn { width: 100%; }
}

/* Unsichtbarer Standard-Speichernknopf (erster Absendeknopf, fuer Enter).
   Nicht display: none - er muss "gerendert" bleiben, damit der Browser ihn
   als Standardknopf benutzt. */
.settings-default-submit {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Startklar-Check ueber dem Formular. Gelbe Kante wie .notice--warn, gruen
   ohne Befund, grau bei nur ergaenzenden Hinweisen. Die Ueberschrift eines
   Punktes ist sein Sprunglink; die Erklaerung steht darunter, eingerueckt
   unter der Ueberschrift. */
.set-check {
    margin: 0 0 1.25rem;
    padding: 0.9rem 1.15rem;
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--dlrg-yellow);
    border-radius: var(--radius);
    background: var(--color-card);
}
.set-check--ok { border-left-color: #2e7d32; }
.set-check--ruhig { border-left-color: #9e9e9e; }
.set-check__kopf { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.6rem; }
.set-check__titel { margin: 0 0.2rem 0 0; font-size: 1.05rem; }
.set-check__ok { margin: 0.45rem 0 0; }
.set-check__liste { display: grid; gap: 0.35rem; margin: 0.65rem 0 0; padding: 0; list-style: none; }
.set-check__punkt { border-radius: 8px; background: var(--color-bg); }
.set-check__link {
    display: grid;
    grid-template-columns: 4.6rem minmax(0, 1fr) auto;
    align-items: baseline;
    gap: 0.2rem 0.65rem;
    padding: 0.5rem 0.65rem;
    border-radius: 8px;
    color: var(--color-text);
    text-decoration: none;
}
.set-check__link:hover { background: rgba(28, 28, 28, 0.05); }
.set-check__link:hover .set-check__was { text-decoration: underline; text-underline-offset: 3px; }
.set-check__marke {
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 700;
    text-align: center;
    white-space: nowrap;
}
.set-check__punkt--problem .set-check__marke { background: var(--color-danger-soft); color: var(--color-danger); }
.set-check__punkt--hinweis .set-check__marke { background: #e6e6e6; color: var(--color-muted); }
.set-check__wo { color: var(--color-muted); font-size: 0.85rem; white-space: nowrap; }
.set-check__warum {
    margin: -0.15rem 0 0;
    padding: 0 0.65rem 0.55rem 5.9rem;
    color: var(--color-muted);
    font-size: 0.9rem;
}
.set-check__hinweise { margin: 0.5rem 0 0; }
.set-check__hinweise > summary { padding: 0.4rem 0; font-weight: 600; cursor: pointer; }
.set-check__hinweise > .set-check__liste { margin-top: 0.2rem; }
.set-check__stand { margin: 0.6rem 0 0; color: var(--color-muted); font-size: 0.85rem; }
/* Mobil zugeklappte Erklaerungen: nur mit JavaScript gibt es den Knopf. */
.set-check__erklaeren {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    margin: 0.2rem 0 0;
    padding: 0.35rem 0;
    border: 0;
    background: none;
    color: var(--color-text);
    font: inherit;
    font-size: 0.92rem;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
}
@media (min-width: 600px) {
    .set-check__erklaeren { display: none; }
}
/* Handy: das Etikett schrumpft zum farbigen Punkt (der Text bleibt fuer
   Screenreader im Link), damit die Ueberschrift die Zeile bekommt. */
@media (max-width: 599.98px) {
    .set-check { padding: 0.8rem 0.85rem; }
    .set-check__titel { font-size: 1rem; }
    .set-check__kopf { gap: 0.35rem 0.45rem; }
    .set-check__kopf .set-chip { padding: 0.15rem 0.5rem; font-size: 0.8rem; }
    .set-check__link { grid-template-columns: 0.6rem minmax(0, 1fr); align-items: center; gap: 0 0.6rem; }
    .set-check__marke { width: 0.6rem; height: 0.6rem; padding: 0; overflow: hidden; font-size: 0; }
    .set-check__punkt--problem .set-check__marke { background: var(--color-danger); }
    .set-check__punkt--hinweis .set-check__marke { background: #9e9e9e; }
    .set-check__wo { grid-column: 2; font-size: 0.8rem; }
    .set-check__warum { padding-left: 1.85rem; }
    .set-check.is-knapp .set-check__warum { display: none; }
}
@media (max-width: 899.98px), (pointer: coarse) {
    .set-check__link { min-height: 44px; }
    .set-check__hinweise > summary { padding: 0.65rem 0; }
}
.set-chip--problem { background: var(--color-danger-soft); color: var(--color-danger); }

/* Zustandszeile oben in einer Karte (z. B. "Versand laeuft.") */
.set-card__status { margin: 0; padding: 0 1.15rem 0.85rem; font-size: 0.95rem; }
/* Hilfen im Kartenkopf haengen an diesem Block. */
.set-card__intro { position: relative; }
.set-input--zeit { max-width: 12rem; }

/* Aufgedeckt: ein Ziel lag in einem Unterbereich, dessen Schalter aus ist.
   settings.js macht ihn sichtbar und sagt, warum. */
.set-card .cond-fields.is-aufgedeckt,
.is-aufgedeckt { border-left-color: #e3b800; border-left-style: dashed; }
.set-aufgedeckt {
    margin: 0.6rem 0 0 1rem;
    padding: 0.45rem 0.7rem;
    border-radius: 8px;
    background: #fff4d6;
    color: #6b4d00;
    font-size: 0.9rem;
}

/* Kurze Markierung eines Sprungziels. Ohne Bewegungswunsch steht sie ruhig
   da, bis settings.js sie nach gut zwei Sekunden wieder abnimmt. */
.is-target { box-shadow: 0 0 0 3px var(--dlrg-yellow); }
@media (prefers-reduced-motion: no-preference) {
    .is-target { animation: set-ziel 2.4s ease-out 1 both; }
}
@keyframes set-ziel {
    0%, 55% { box-shadow: 0 0 0 3px var(--dlrg-yellow); }
    100% { box-shadow: 0 0 0 3px rgba(255, 236, 0, 0); }
}

/* Bild-Regel der Zusatzaktionen (settings.js): nicht abgeschickt. */
.set-card__alarm {
    flex-basis: 100%;
    margin: 0;
    padding: 0.6rem 0.8rem;
    border: 1px solid #f3b4b7;
    border-radius: var(--radius);
    background: var(--color-danger-soft);
    color: var(--color-danger);
    font-size: 0.92rem;
    font-weight: 600;
}

/* Dokumentzeilen (Datenschutz, Impressum) */
.set-doc { padding: 0.95rem 1.15rem; border-top: 1px solid var(--color-border); }
.set-doc__kopf { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.6rem; }
.set-doc__titel { margin: 0; font-size: 1rem; }
.set-doc__vorschau {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    margin: 0.45rem 0 0.75rem;
    color: var(--color-muted);
    font-size: 0.92rem;
}
.set-doc__aktionen { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.set-doc__aktionen .btn { min-height: 44px; padding: 0.55rem 1.1rem; font-size: 0.95rem; }
.set-doc__editor { margin-top: 0.85rem; }

/* Editoren auf dieser Seite: feste Hoehe, darin scrollen, Hoehe ziehbar.
   Die Produktseite behaelt ihr mitwachsendes Feld. */
.settings-shell .richtext-area {
    max-height: min(22rem, 55vh);
    overflow-y: auto;
    resize: vertical;
}
.richtext-btn--gross { margin-left: auto; }

/* Rueckfrage im Stil der Seite (settings.js, seit 1.33.1) statt des
   Browser-Popups. Form des Hilfedialogs; die Knoepfe stehen rechts, die
   ungefaehrliche Antwort zuerst. Mobil teilen sie sich die Zeile. */
.set-frage { width: min(420px, calc(100vw - 32px)); }
.set-frage__titel { margin: 0.2rem 0 0; font-size: 1.15rem; line-height: 1.3; }
.set-frage__text { margin: 0.5rem 0 0; color: var(--color-muted); }
.set-frage__knoepfe {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.6rem;
    margin-top: 1.25rem;
}
@media (max-width: 599.98px) {
    .set-frage__knoepfe .btn { flex: 1 1 0; padding-left: 0.75rem; padding-right: 0.75rem; }
}

/* Grosser Editor-Dialog. display nur im offenen Zustand setzen - eine
   Autorenregel mit display ueberstimmte sonst das Verstecken durch den
   Browser. */
.set-editor {
    width: min(60rem, calc(100vw - 32px));
    max-width: none;
    height: min(52rem, calc(100vh - 32px));
    height: min(52rem, calc(100dvh - 32px));
    max-height: none;
    margin: auto;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-card);
    color: var(--color-text);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18);
}
.set-editor[open] { display: flex; flex-direction: column; }
.set-editor::backdrop { background: rgba(28, 28, 28, 0.45); }
.set-editor__innen { display: flex; flex: 1; flex-direction: column; min-height: 0; padding: 1rem 1.25rem 1.1rem; }
.set-editor__kopf { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }
.set-editor__titel { margin: 0.35rem 0 0.75rem; font-size: 1.15rem; }
.set-editor__koerper { display: flex; flex: 1; flex-direction: column; min-height: 0; }
.set-editor__koerper .richtext { display: flex; flex: 1; flex-direction: column; min-height: 0; margin: 0; }
/* min-height: 0 - sonst hielte das Textfeld seine 8rem und liefe bei wenig
   Hoehe in den Fuss hinein. */
.set-editor__koerper .richtext-area { flex: 1; min-height: 0; max-height: none; overflow-y: auto; resize: none; }
.set-editor__koerper .richtext-btn--gross { display: none; }
.set-editor__fuss { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 0.6rem; margin-top: 0.9rem; }
.set-editor__hinweis { margin: 0 auto 0 0; color: var(--color-muted); font-size: 0.9rem; }
@media (max-width: 599.98px) {
    .set-editor__innen { padding: 0.75rem 0.8rem 0.8rem; }
    .set-editor__fuss .btn { flex: 1 1 100%; }
}

/* Bildschirmtastatur (settings.js): ist die sichtbare Flaeche deutlich
   kleiner als das Fenster, folgt der Editor-Dialog ihr - Text, Einfuegemarke
   und "Schliessen" bleiben ueber der Tastatur. Die Masse setzt settings.js
   aus window.visualViewport als Variablen; der Fuss wird dabei einzeilig. */
.set-editor.is-knapp {
    top: calc(var(--editor-oben, 0px) + 8px);
    bottom: auto;
    height: calc(var(--editor-hoehe, 100dvh) - 16px);
    margin-top: 0;
    margin-bottom: 0;
}
/* Knapper Platz - Tastatur eingeblendet (is-knapp) oder ein niedriges
   Fenster: Kopf und Fuss ruecken zusammen, die Werkzeugleiste bleibt
   einzeilig und rollt seitlich, der Platz gehoert dem Text. */
.set-editor.is-knapp .set-editor__innen { padding: 0.55rem 0.75rem 0.6rem; }
.set-editor.is-knapp .set-editor__titel { margin: 0.2rem 0 0.4rem; font-size: 1rem; }
.set-editor.is-knapp .set-editor__hinweis { display: none; }
.set-editor.is-knapp .set-editor__fuss { flex-wrap: nowrap; margin-top: 0.5rem; }
.set-editor.is-knapp .set-editor__fuss .btn { flex: 1 1 0; min-height: 44px; padding: 0.4rem 0.5rem; font-size: 0.9rem; }
.set-editor.is-knapp .richtext-toolbar { flex-wrap: nowrap; overflow-x: auto; }
.set-editor.is-knapp .richtext-toolbar > * { flex: none; }
.set-editor.is-knapp .set-editor__fuss [data-editor-verwerfen] { flex-grow: 1.7; }
@media (max-height: 33.75rem) {
    .set-editor .richtext-toolbar > * { flex: none; }
    .set-editor .set-editor__fuss [data-editor-verwerfen] { flex-grow: 1.7; }
    .set-editor .set-editor__innen { padding: 0.55rem 0.75rem 0.6rem; }
    .set-editor .set-editor__titel { margin: 0.2rem 0 0.4rem; font-size: 1rem; }
    .set-editor .set-editor__hinweis { display: none; }
    .set-editor .set-editor__fuss { flex-wrap: nowrap; margin-top: 0.5rem; }
    .set-editor .set-editor__fuss .btn { flex: 1 1 0; min-height: 44px; padding: 0.4rem 0.5rem; font-size: 0.9rem; }
    .set-editor .richtext-toolbar { flex-wrap: nowrap; overflow-x: auto; }
}

/* Bereiche Allgemein, Darstellung und Bestellung */

/* Ruhige Notiz in einer Karte ("Der Shop ist manuell gesperrt ..."). */
.set-card__notiz {
    margin: 0 1.15rem 0.85rem;
    padding: 0.55rem 0.75rem;
    border-radius: 8px;
    background: var(--color-bg);
    color: var(--color-muted);
    font-size: 0.92rem;
}
/* Warnung in einem eingerueckten Unterbereich: buendig mit dessen Zeilen. */
.set-card .cond-fields .set-card__warnungen { padding: 0.75rem 0 0.1rem 1rem; }
.set-input--zeitpunkt { max-width: 16rem; }
.set-input--kurz { max-width: 15rem; }

/* Bildzeilen: Vorschau des gespeicherten Bildes, daneben Dateiauswahl und
   Entfernen-Haken. */
.set-bild { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem 1rem; }
.set-bild__vorschau {
    display: flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: 8rem;
    height: 5rem;
    padding: 0.35rem;
    overflow: hidden;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: #fff;
}
.set-bild__vorschau--breit { width: 9.5rem; }
/* Das Bild fuellt die Innenflaeche des Rahmens und wird darin unverzerrt
   eingepasst - hohe wie breite Logos. Bis 1.33.1 stand hier max-height: 100%
   in einem Raster: die Prozentangabe bezog sich auf die Rasterzeile, die
   sich nach dem Bild selbst richtet, und ein hohes Logo lief unten hinaus. */
.set-bild__vorschau img { display: block; width: 100%; height: 100%; object-fit: contain; }
.set-bild__fehlt { margin: 0; color: var(--color-danger); font-size: 0.85rem; text-align: center; }
.set-bild__felder { display: grid; flex: 1 1 15rem; gap: 0.5rem; min-width: 0; }
.set-bild__felder input[type="file"] { padding: 0.5rem; background: var(--color-bg); }
.set-bild__entfernen {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    margin: 0;
    font-weight: 400;
    cursor: pointer;
}
.set-bild__entfernen input[type="checkbox"] {
    flex: none;
    width: 1.2rem;
    height: 1.2rem;
    margin: 0;
    padding: 0;
    accent-color: var(--dlrg-red);
}
@media (max-width: 899.98px), (pointer: coarse) {
    .set-bild__entfernen { min-height: 44px; }
}

/* Suche in der Seitenleiste (settings.js). Waehrend der Suche stehen alle
   Bereiche untereinander; was nicht passt, traegt .is-suche-aus - eine
   Klasse, nie hidden: das Attribut gehoert den bedingten Feldern. */
.settings-suche { margin: 0 0 0.9rem; }
.settings-suche__feld { position: relative; }
.settings-suche__ico {
    position: absolute;
    top: 50%;
    left: 0.75rem;
    color: var(--color-muted);
    transform: translateY(-50%);
    pointer-events: none;
}
.settings-suche__feld input { min-height: 44px; padding: 0.55rem 0.75rem 0.55rem 2.35rem; }
/* Platz fuer das Kreuz nur, solange es zu sehen ist - sonst waere der
   Platzhalter in der schmalen Seitenleiste abgeschnitten. */
.settings-suche__feld:has(.settings-suche__leeren:not([hidden])) input { padding-right: 2.75rem; }
.settings-suche__feld input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.settings-suche__leeren {
    position: absolute;
    top: 0;
    right: 0;
    width: 44px;
    height: 100%;
    padding: 0;
    border: 0;
    border-radius: 0 var(--radius) var(--radius) 0;
    background: none;
    color: var(--color-muted);
    font-size: 1.35rem;
    line-height: 1;
    cursor: pointer;
}
.settings-suche__leeren:hover { color: var(--color-text); }
.settings-suche__status { margin: 0.35rem 0 0; color: var(--color-muted); font-size: 0.85rem; }
.settings-suche__status:empty { display: none; }

.is-suche-aus { display: none !important; }
.settings-tabs.tabs-on.is-suche .tab-panel { display: block; }
.settings-tabs.is-suche .tab-panel { margin-bottom: 1.75rem; }
.settings-shell.is-suche .set-check,
.settings-tabs.is-suche .section-jump,
.settings-tabs.is-suche .set-panel__lead { display: none; }
/* Verweis an einer Schalterzeile: ein Treffer liegt darunter, im
   ausgeschalteten Unterbereich. */
.set-suche-verweis {
    grid-column: 1 / -1;
    margin: 0;
    padding: 0.45rem 0.7rem;
    border-radius: 8px;
    background: #fff4d6;
    color: #6b4d00;
    font-size: 0.88rem;
}
.set-suche-leer {
    margin: 0 0 1.25rem;
    padding: 1rem 1.15rem;
    border: 1px dashed #bdbdbd;
    border-radius: var(--radius);
    background: var(--color-card);
    color: var(--color-muted);
}

/* Scan-Ansicht */
.scan-main { max-width: 560px; }
.scanner {
    position: relative;
    background: #000;
    border-radius: var(--radius);
    overflow: hidden;
    margin: var(--gap) 0;
    aspect-ratio: 4 / 3;
}
.scanner video { width: 100%; height: 100%; object-fit: cover; display: block; }
.scan-hint {
    position: absolute; left: 0; right: 0; bottom: 0;
    margin: 0; padding: 0.5rem;
    background: rgba(0,0,0,0.55); color: #fff; text-align: center; font-size: 0.9rem;
}
/* Kein Kamerazugriff (z. B. http): heller Hinweiskasten statt schwarzem Bild. */
.scanner--off { background: var(--color-card); border: 1px solid var(--color-border); aspect-ratio: auto; }
.scanner--off video { display: none; }
.scanner--off .scan-hint {
    position: static; background: none; color: var(--color-muted);
    padding: 1rem; font-size: 1rem;
}
.scan-form input { font-size: 1.3rem; text-align: center; letter-spacing: 0.08em; }
.scan-result {
    border-radius: var(--radius);
    border: 2px solid var(--color-border);
    padding: 1rem;
    margin: var(--gap) 0;
    background: var(--color-card);
}
.scan-result.scan-ok { border-color: #2e7d32; background: #eef8ee; }
.scan-result.scan-warn { border-color: #b8860b; background: #fff8e6; }
.scan-result.scan-err { border-color: var(--dlrg-red); background: #fff5f5; }
.scan-msg { font-size: 1.2rem; font-weight: bold; margin: 0 0 0.5rem; }
.scan-amount { font-size: 2.4rem; font-weight: bold; color: var(--dlrg-red); }
.scan-amount span { font-size: 1rem; color: var(--color-muted); font-weight: normal; }
.scan-order dl { display: grid; grid-template-columns: auto 1fr; gap: 0.2rem 0.8rem; margin: 0.6rem 0 0; }
.scan-order dt { color: var(--color-muted); }
.scan-order dd { margin: 0; }
/* "Abgeholt am ... von ..." direkt unter der Meldung - die zweite Frage am
   Stand nach "abgeholt oder nicht?". */
.scan-when { font-size: 1.1rem; font-weight: bold; margin: 0 0 0.5rem; }
/* Datum und Uhrzeit nicht auseinanderreissen: umbrochen wird hoechstens
   vor dem Datum, sonst stand "Uhr" allein in der naechsten Zeile. */
.scan-when .scan-zeit { white-space: nowrap; }
/* Wer abgehakt hat: eigene, leisere Zeile direkt darunter. In derselben
   Zeile ("... von Anna") las es sich, als habe Anna das Brot geholt. */
.scan-when + .scan-by { margin: -0.3rem 0 0.5rem; color: var(--color-muted); }
/* Die Bemerkung hat sonst dieselbe Flaeche wie der gelbe Kasten
   (.scan-warn) und verschwaende darin. */
.scan-result .detail-note { background: #fff; margin-top: 0.6rem; }
/* Der Knopf zum Abhaken: volle Breite und gross genug fuer den Finger.
   "Abbrechen" steht mit dem Abstand von .actions ausserhalb des Kastens. */
.scan-collect { margin: 1rem 0 0; }
.scan-collect .btn { width: 100%; font-size: 1.2rem; padding: 1rem 1.4rem; }

/* Bild-Vorschau (Upload) */
.img-preview {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    margin: 0.4rem 0 0.6rem;
}
.img-preview img {
    max-width: 160px;
    max-height: 120px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 4px;
    background: #fff;
}

/* Verwaltungs-Karten (Orte/Zeiten) */
.card-form {
    background: var(--color-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1rem;
    margin: 0.8rem 0;
}
.card-form label { font-weight: 600; }
.row-head {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-bottom: 0.5rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--color-border);
}
.row-head strong { margin-right: auto; }

/* Zeitfenster-Bereich im Abholort */
.slots-section { margin-top: 0.6rem; }
.slot-row { margin: 0.6rem 0; }
.slot-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 0.4rem 1rem;
}
.slot-grid label { font-weight: 600; }
/* Hinweis „(leer = unbegrenzt)“ dezent und als Ganzes umbrechen statt mittendrin. */
.slot-grid label .muted { font-weight: normal; font-size: 0.8rem; white-space: nowrap; }
.del-check { font-weight: normal; color: var(--dlrg-red); display: inline-flex; align-items: center; gap: 0.3rem; }
[data-add-slot] { margin-top: 0.4rem; }

/* Honeypot-Feld der Bestellseite.
   Das `hidden`-Attribut im HTML macht es unsichtbar, auch ohne dieses
   Stylesheet – ein Formular, das „Bitte dieses Feld leer lassen“ anzeigt,
   weil eine CSS-Datei fehlt oder veraltet im Cache liegt, wäre peinlicher
   als der Nutzen der Falle.
   Hier wird `hidden` bewusst überstimmt und das Feld stattdessen aus dem
   sichtbaren Bereich geschoben: display:none überspringen manche
   Massenversender gezielt, ein positioniertes Feld füllen sie aus.
   Für Screenreader bleibt es über aria-hidden und tabindex="-1" außen vor
   (siehe templates/order.php). */
.hp-field[hidden] {
    display: block !important;
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* ---------- Abholorte: Reihenfolge ----------
 *
 * Der Griff traegt touch-action: none. Ohne das scrollt der Browser beim
 * Wischen ueber den Griff die Seite, statt die Zeile zu bewegen. Das
 * Nachscrollen am Bildschirmrand uebernimmt admin.js selbst.
 *
 * Griff, Ziehen-Hinweis und Rueckmeldebereich sind VON HAUS AUS aus und
 * werden erst durch .is-pointer-sort-enabled sichtbar - gesetzt von
 * admin.js am Ende seines Sortierblocks, also nur bei vorhandenem fetch,
 * PointerEvent, request-/cancelAnimationFrame und setPointerCapture UND
 * nach erfolgreichem Aufsetzen.
 *
 * Die Pfeile bleiben in JEDEM Fall - sie sind der Weg mit der Tastatur.
 */
.col-griff { width: 1%; white-space: nowrap; box-sizing: border-box; }
.sort-controls { display: flex; align-items: center; gap: 0.2rem; }
.sort-buttons { display: flex; gap: 0.15rem; margin: 0; }

.drag-handle {
    display: none;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    cursor: grab;
    touch-action: none;
    user-select: none;
    color: var(--color-muted);
    font-size: 1.1rem;
    line-height: 1;
}
.is-pointer-sort-enabled .drag-handle { display: inline-flex; }
.drag-handle:active { cursor: grabbing; }

.hinweis-ziehen { display: none; }
.is-pointer-sort-enabled .hinweis-ziehen { display: inline; }
.is-pointer-sort-enabled .hinweis-pfeile { display: none; }

.sort-feedback { display: none; gap: 0.6rem; align-items: center; flex-wrap: wrap; margin-top: 0.5rem; }
.is-pointer-sort-enabled .sort-feedback { display: flex; }
.sort-status { margin: 0; font-size: 0.9rem; min-height: 1.3em; }
.sort-status:focus-visible { outline: 2px solid var(--dlrg-red); outline-offset: 2px; }
.sort-status.is-error { color: var(--dlrg-red); font-weight: bold; }

/* aria-disabled statt disabled: der Knopf behaelt den Fokus, sieht aber
   inaktiv aus. Der Click-Guard in admin.js macht ihn wirkungslos. */
.btn[aria-disabled="true"] { opacity: 0.6; cursor: default; }

.move-btn { min-width: 44px; min-height: 44px; }
.move-btn[disabled] { opacity: 0.35; cursor: default; }
[data-row-anchor]:focus-visible { outline: 2px solid var(--dlrg-red); outline-offset: 2px; }

/* Lange Ortsnamen brechen um, statt die Spalte aufzublaehen. Das setzt
   zugleich die inhaltsbedingte Mindestbreite der Zelle auf ein einzelnes
   Zeichen herunter - erst dadurch wirkt die min-width unten als echte
   Untergrenze. */
.admin-table .ort-name { overflow-wrap: anywhere; word-break: break-word; }
.admin-table tr.is-dragging { background: var(--dlrg-yellow); box-shadow: 0 2px 6px rgba(0,0,0,0.25); }
.admin-table tr.is-dragging:hover { background: var(--dlrg-yellow); }

/* Gesperrt wird beim Filtern UND in den Endzustaenden der Warteschlange.
   Das Abschalten selbst passiert in admin.js ueber button.disabled. */
.sortier-gesperrt .drag-handle { opacity: 0.35; cursor: not-allowed; }

.reorder-hint { margin: 0 0 0.6rem; font-size: 0.9rem; }
.sort-locked-hint { margin: 0 0 0.6rem; font-size: 0.9rem; }

/* Das Filterfeld DIESER Seite arbeitet ausschliesslich in admin.js. Ohne
   JavaScript ist es ein Bedienelement, das nichts tut - und es gehoert zu
   einer Sperre, die es ohne JavaScript gar nicht gibt. Bewusst nur die
   Abholortseite: dasselbe Feld auf /admin/log und /admin/users ist ein
   eigenes Thema. */
html:not(.js) .locations-toolbar { display: none; }

/* Schmale Anzeigen (Akzeptanztest A16: 320 CSS-px nutzbare Breite).
 *
 * 1) Das Filterfeld. Die Basisregel .list-toolbar input[type="search"]
 *    setzt min-width: 200px - bei 320 CSS-px sprengt das zusammen mit dem
 *    Innenabstand die Seite waagerecht.
 *
 * 2) Griff UND Pfeile vollstaendig untereinander. Ein blosses width:44px
 *    an der Zelle waere KEINE Zusage - Innenabstand, Rahmen und Inhalt
 *    weiten sie jederzeit auf. Deshalb wird alles drei festgenagelt:
 *    box-sizing: border-box, 4px Innenabstand je Seite, 44px Inhalt. Die
 *    zugesagte AUSSENBREITE ist damit 52px - und genau dagegen prueft
 *    A16, nicht gegen 44px.
 *
 * 3) Die Namensspalte bekommt den Rest des sichtbaren Scrollports, mit
 *    einer Untergrenze von 9rem. 52px + 9rem bleiben unter 320px.
 *
 * Die Zeilenhoehe steigt dadurch auf rund 136px. Das ist gewollt und der
 * Grund fuer das Rand-Autoscroll in admin.js, §7.4.
 */
@media (max-width: 460px) {
    .locations-toolbar input[type="search"] { min-width: 0; width: 100%; flex-basis: 100%; }

    .admin-table .col-griff {
        box-sizing: border-box;
        width: 52px;
        min-width: 52px;
        max-width: 52px;
        padding-left: 4px;
        padding-right: 4px;
        white-space: normal;
    }
    .sort-controls { flex-direction: column; align-items: center; gap: 0.2rem; width: 44px; }
    .sort-buttons  { flex-direction: column; width: 44px; }
    .move-btn { width: 44px; }

    .admin-table .ort-name { min-width: 9rem; }
    .admin-table th, .admin-table td { padding: 0.5rem 0.4rem; }
}

/* Zwei-Faktor-Anmeldung: Schluessel zum Abtippen, Abbruch-Formular */
.mfa-secret { text-align: center; margin: 0.4rem 0 1.2rem; }
.mfa-secret code { font-size: 1.05rem; letter-spacing: 0.08em; word-break: break-all; }
.mfa-cancel { text-align: center; margin-top: 1rem; }

/* --- Interne Bestellerfassung (Herkunft + Formular) --- */

/* Herkunftsmarke einer intern erfassten Bestellung. Grau statt bunt und
   klein genug, dass die Zeile der Bestellliste dadurch nicht waechst: das
   ist eine Auskunft, keine Warnung. Groesse in em, damit sie innerhalb der
   Zeilenbox der Bestellnummer bleibt - dieselbe Ueberlegung wie bei
   .note-badge. */
.src-badge {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.05em 0.5em;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-bg);
    color: var(--color-muted);
    font-size: 0.75em;
    font-weight: 600;
    line-height: 1.6;
    white-space: nowrap;
    vertical-align: middle;
}
/* In der Detailansicht steht die Marke am Zeilenanfang - dort braucht sie
   keinen linken Abstand. */
.src-note { color: var(--color-muted); margin: 0.2rem 0 0; }
.src-note .src-badge { margin-left: 0; margin-right: 0.4rem; }

/* Brot und Preis ueber dem Mengenfeld: eine Zeile am PC, zwei am Telefon.
   Kein Kartenrahmen - das Fieldset drumherum ist bereits einer. */
.order-new-product { display: flex; flex-wrap: wrap; gap: 0.2rem 0.6rem; align-items: baseline; margin: 0; }

/* === Backhaus-Seite (1.27.0) =============================================
   Fuer den Touch-PC im Backhaus, bewusst nur fuer breite Bildschirme
   gestaltet: grosse Kacheln, Tasten ab 72 px, keine Handy-Umbrueche.
   Eigene Klassen statt .stat-card/.stat-num: Tests lesen das Dashboard ueber
   genau diese Klassen, sie sollen hier nichts finden.
   Farben aus dem Bestand (gruen #2e7d32, gelb #b8860b, --color-danger). Das
   Gelb traegt auf Weiss nur etwa 3,3:1 - es bleibt deshalb Rahmen, Flaeche
   und grosse Ziffer; die Saetze stehen in der Textfarbe. */
.backhaus { display: flex; flex-direction: column; gap: 1.25rem; }
.bh-kopf { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.bh-kopf h1 { margin: 0; }
.bh-stand { margin: 0; color: var(--color-muted); font-variant-numeric: tabular-nums; }
.bh-verbindung {
    margin: 0;
    padding: 0.75rem 1rem;
    border: 2px solid #b8860b;
    border-radius: var(--radius);
    background: #fff8db;
    color: var(--color-text);
    font-weight: 600;
}
/* Veralteter Stand: die Zahlen treten sichtbar zurueck, bis wieder eine
   frische Antwort da ist. */
.backhaus.bh-veraltet .bh-kacheln { opacity: 0.55; }

.bh-kacheln {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr)) minmax(0, 1.6fr);
    gap: var(--gap);
}
.bh-kachel {
    background: var(--color-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1rem 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
.bh-zahl { font-size: 3rem; font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.bh-label { font-size: 1.05rem; font-weight: 600; color: var(--color-muted); }
.bh-unter { font-size: 0.95rem; color: var(--color-muted); }
.bh-frei { border-width: 3px; }
.bh-frei .bh-zahl { font-size: 3.6rem; }
.bh-satz { font-size: 1.15rem; font-weight: 600; color: var(--color-text); }
.bh-frei--plus { border-color: #2e7d32; background: #edf7ee; }
.bh-frei--plus .bh-zahl { color: #2e7d32; }
.bh-frei--null { border-color: #b8860b; background: #fff8db; }
.bh-frei--null .bh-zahl { color: #b8860b; }
.bh-frei--minus { border-color: var(--color-danger); background: var(--color-danger-soft); }
.bh-frei--minus .bh-zahl { color: var(--color-danger); }

.bh-rueckfrage {
    border: 3px solid var(--color-danger);
    border-radius: var(--radius);
    background: var(--color-danger-soft);
    padding: 1.25rem 1.5rem;
}
.bh-rueckfrage h2 { margin-top: 0; color: var(--color-danger); }
.bh-rueckfrage p { font-size: 1.15rem; }
.bh-rueckfrage-knoepfe { display: flex; gap: 1rem; flex-wrap: wrap; align-items: center; }
.bh-gross { min-height: 4rem; font-size: 1.25rem; padding: 0.9rem 1.6rem; display: inline-flex; align-items: center; }

.bh-eingaben { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; }
.bh-eingabe {
    background: var(--color-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1rem 1.25rem 1.25rem;
}
.bh-eingabe h2 { margin: 0 0 0.25rem; }
/* Erklaerung und Warnhinweis haben dieselben Masse: so stehen die beiden
   Zahlenbloecke auf gleicher Hoehe, egal welcher von beiden gerade da ist. */
.bh-erklaerung, .bh-hinweis {
    margin: 0 0 0.75rem;
    padding: 0.6rem 0.8rem;
    border-left: 4px solid var(--color-border);
    background: var(--color-bg);
    color: var(--color-muted);
}
.bh-hinweis { border-left-color: var(--color-danger); background: var(--color-danger-soft); color: var(--color-text); font-weight: 600; }
.bh-form { display: flex; flex-direction: column; gap: 0.75rem; }
.bh-anzeige-zeile { display: grid; grid-template-columns: 5.5rem minmax(0, 1fr) 5.5rem; gap: 0.6rem; }
.bh-anzeige {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 5rem;
    border: 2px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-bg);
    font-size: 2.6rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.bh-form--minus .bh-anzeige { color: var(--color-danger); border-color: var(--color-danger); }
.bh-block { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.6rem; margin-top: 0.6rem; }
/* manipulation: kein Warten auf einen moeglichen Doppeltipp-Zoom; ohne
   user-select markiert ein schnelles Tippen sonst die Ziffern. */
.bh-taste {
    min-height: 4.5rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: #fff;
    color: var(--color-text);
    font: inherit;
    font-size: 2rem;
    font-weight: 700;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-user-select: none;
    user-select: none;
}
.bh-taste:active { background: var(--dlrg-yellow); }
.bh-taste--schritt { min-height: 5rem; font-size: 2.6rem; background: var(--color-bg); }
.bh-taste--neben { font-size: 1.6rem; background: var(--color-bg); }
.bh-buchen { width: 100%; min-height: 4.5rem; font-size: 1.35rem; touch-action: manipulation; }
.bh-buchen[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }

.bh-verlauf h2 { margin-bottom: 0.5rem; }
.bh-buchungen td { vertical-align: middle; }
/* Zurueckgenommen: die Zeile tritt grau zurueck, durchgestrichen ist nur die
   Menge - sie ist das, was nicht mehr zaehlt. Eine ganz durchgestrichene
   Zeile war muehsam zu lesen. */
.bh-buchungen .bh-storniert td { color: var(--color-muted); }
.bh-buchungen .bh-storniert .bh-menge { text-decoration: line-through; font-weight: 400; }
/* Marke in der Spalte Aktion, so hoch wie der Knopf "Rueckgaengig". Eigene
   Klasse neben .status-pill: dieselben Farben wie "storniert" in der
   Bestellliste, aber nicht an deren Klasse gekoppelt. */
.bh-zurueck { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 0.2rem 0.6rem; min-height: 48px; }
.bh-zurueck-marke { background: #eee; color: #666; }
.bh-zurueck-wann { font-size: 0.85rem; white-space: nowrap; }
.bh-buchungen .bh-menge { font-weight: 700; font-variant-numeric: tabular-nums; }
.bh-buchungen .bh-zeit { white-space: nowrap; font-variant-numeric: tabular-nums; }
.bh-rueckgaengig { min-height: 48px; padding: 0.5rem 1rem; font-size: 0.95rem; touch-action: manipulation; }

/* Rueckfrage vor "Rueckgaengig" (1.27.1), Aufbau wie .help-dialog der
   Bestellseite: padding 0 am <dialog>, der Inhalt steckt vollstaendig in
   __inner - ein Klick auf den Hintergrund trifft so das <dialog> selbst.
   Grosse Knoepfe nebeneinander, fuer den Finger am Touch-PC. */
.bh-dialog {
    width: min(560px, calc(100vw - 32px));
    max-width: none;
    margin: auto;
    padding: 0;
    border: 0;
    border-radius: var(--radius);
    background: var(--color-card);
    color: var(--color-text);
    box-shadow: 0 16px 40px rgba(0, 0, 0, 0.25);
}
.bh-dialog::backdrop { background: rgba(28, 28, 28, 0.55); }
.bh-dialog__inner { padding: 1.5rem 1.75rem 1.75rem; }
.bh-dialog h2 { margin: 0 0 1rem; font-size: 1.4rem; }
.bh-dialog__buchung { margin: 0; font-size: 2.2rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.bh-dialog__meta { margin: 0.2rem 0 1rem; color: var(--color-muted); font-size: 1.05rem; }
.bh-dialog__folge { margin: 0 0 0.4rem; font-size: 1.15rem; }
.bh-dialog__hinweis { margin: 0 0 1.5rem; color: var(--color-muted); }
.bh-dialog__knoepfe { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
.bh-dialog__knoepfe .bh-gross { width: 100%; justify-content: center; touch-action: manipulation; }
.bh-pager { margin-top: var(--gap); }

/* Niedrige Bildschirme (1366 x 768): flacher, damit Kacheln, Zahlenblock und
   Buchungsknopf ohne Scrollen zusammen zu sehen sind. Die Erklaerzeile
   entfaellt dort; der Warnhinweis bleibt. Die Tasten bleiben ueber 48 px. */
@media (max-height: 820px) {
    .backhaus { gap: 0.75rem; }
    .bh-kachel { padding: 0.6rem 1rem; }
    .bh-zahl { font-size: 2.2rem; }
    .bh-frei .bh-zahl { font-size: 2.6rem; }
    .bh-eingabe { padding: 0.75rem 1rem 1rem; }
    .bh-erklaerung { display: none; }
    .bh-form { gap: 0.5rem; }
    .bh-anzeige, .bh-taste--schritt { min-height: 3.4rem; }
    .bh-anzeige { font-size: 2.2rem; }
    .bh-block { gap: 0.5rem; margin-top: 0.5rem; }
    .bh-taste { min-height: 3.1rem; font-size: 1.7rem; }
    .bh-taste--schritt { font-size: 2.2rem; }
    .bh-buchen { min-height: 3.4rem; }
}
