:root {
    /* Support-Ticket Auftrag 120 (2026-08-29): sitweite Standard-Schriftart
       jetzt Arial (vorher fest Inter/Fraunces) - überschreibbar über
       Stammdaten > Konfiguration (siehe includes/header.php, dort wird
       dieselbe Variable ggf. mit einem anderen Wert neu gesetzt). Gilt für
       body UND Überschriften/Sonderstellen (siehe alle var(--app-font, ...)
       weiter unten), wie vom Nutzer verlangt ("Alle Schrift auf der ganzen
       Seite"). */
    --app-font: Arial, Helvetica, sans-serif;
    --color-bg: #fbf7f1;
    --color-surface: #ffffff;
    --color-border: #e8ddd0;
    --color-text: #3a2f28;
    /* Schritt 5 (Layout): von #8a7b6c auf #776653 abgedunkelt - die
       vorige Farbe erreichte auf --color-bg nur einen Kontrast von 3.84:1
       (WCAG AA verlangt 4.5:1 für normalen Fliesstext, diese Farbe wird
       aber sehr breit für Untertitel/Meta-Texte in normaler Schriftgrösse
       verwendet). Neue Farbe: 5.16:1 auf --color-bg, 5.51:1 auf
       --color-surface - besteht AA deutlich, wirkt optisch fast identisch. */
    --color-text-muted: #776653;
    --color-primary: #c1502e;
    --color-primary-dark: #a13f22;
    --color-secondary: #5c7a52;
    --color-danger: #b3413a;
    --radius: 12px;
    --shadow: 0 2px 8px rgba(58, 47, 40, 0.08);
    --shadow-hover: 0 8px 24px rgba(58, 47, 40, 0.14);
    /* Design-Review (2026-08-31, "ändere alle Icons auf diesen ähnlichen
       Stil, mit einem Rot Ton"): zwei Töne für die neuen flachen,
       zweifarbigen nav_icon()-Icons (siehe includes/functions.php) - aus
       der bestehenden Rot-/Terrakotta-Familie abgeleitet (dunkler als
       --color-primary-dark für genug Eigenkontrast zwischen den beiden
       Icon-Tönen). Via CSS-Variable statt fest verdrahtet, damit sich der
       Ton bei Bedarf an einer Stelle anpassen lässt und sich pro Kontext
       überschreiben lässt (siehe .btn-primary .nav-icon weiter unten). */
    --icon-dark: #8a2f1c;
    --icon-light: #e8916c;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--app-font, Arial, sans-serif);
    background: var(--color-bg);
    color: var(--color-text);
    line-height: 1.6;
}

h1, h2, h3 {
    font-family: var(--app-font, Arial, sans-serif);
    font-weight: 600;
    line-height: 1.2;
    margin: 0 0 0.5em;
}

a { color: inherit; text-decoration: none; }

/* Schritt 5 (Layout): sitweiter sichtbarer Fokus-Ring für Tastatur-
   Bedienung (a11y-Grundanforderung, bisher fehlte er komplett - Browser-
   Standard-Fokusring wurde durch die eigenen Button-/Link-Stile faktisch
   unsichtbar). :focus-visible statt :focus, damit der Ring nur bei
   Tastatur-/Tastatur-artiger Bedienung erscheint, nicht bei jedem Klick. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
    outline: 3px solid var(--color-secondary);
    outline-offset: 2px;
    border-radius: 4px;
}

/* Schritt 5 (Layout): "Zum Inhalt springen"-Link - für Tastatur-/
   Screenreader-Nutzer, damit nicht bei jeder Seite erst die komplette
   Navigation durchlaufen werden muss. Ausserhalb des sichtbaren Bereichs,
   bis er per Tab-Taste fokussiert wird. */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    background: var(--color-primary-dark);
    color: #fff;
    padding: 12px 20px;
    border-radius: 0 0 8px 0;
    font-weight: 600;
}

.skip-link:focus {
    left: 0;
}

.container {
    max-width: 1100px;
    margin: 0 auto;
    padding: 0 24px;
}

.site-header {
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    position: sticky;
    top: 0;
    z-index: 10;
}

.header-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 24px;
}

.brand {
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: var(--app-font, Arial, sans-serif);
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--color-primary-dark);
}

/* Support-Ticket Auftrag 34 (2026-08-28): optionales Logo im Kopfbereich,
   ersetzt das Emoji-Platzhaltersymbol, sobald eines hochgeladen wurde
   (siehe stammdaten_konfiguration.php).
   Support-Ticket 64 (2026-08-29): auf Nutzerwunsch um 50% vergrössert
   (32px -> 48px Höhe, max-width proportional 120px -> 180px).
   Support-Ticket 80 (2026-08-29): auf Nutzerwunsch nochmals um 100%
   vergrössert, ausgehend vom damaligen Stand (48px -> 96px Höhe,
   max-width proportional 180px -> 360px). Der Kopfbereich hat keine feste
   Höhe (.header-inner ist flex mit align-items:center), wächst also
   automatisch mit - Layout bleibt dadurch intakt, wird durch die grössere
   Kopfzeile lediglich insgesamt höher. */
.brand-logo {
    height: 96px;
    width: auto;
    max-width: 360px;
    object-fit: contain;
}

.site-header nav {
    display: flex;
    align-items: center;
    gap: 20px;
}

.site-header nav > a:not(.btn) {
    display: inline-flex;
    align-items: center;
    color: var(--color-text-muted);
    font-weight: 500;
    padding: 4px 2px;
    border-bottom: 2px solid transparent;
}

/* Nutzer-Auftrag (2026-08-29, "einheitliches schönes Layout... Icons wo es
   Sinn macht, aber versehe die Icons mit Alttexten"): die von nav_icon()
   (includes/functions.php) erzeugten Liniensymbole stehen überall NEBEN
   dem weiterhin sichtbaren Textlabel - rein dekorativ (aria-hidden), daher
   hier nur einheitliche Grösse/Abstand/Farbe, keine eigene Beschriftung
   nötig (das sichtbare Label ist der zugängliche Name). flex-shrink:0
   verhindert ein Stauchen des Icons in schmalen Menüzeilen. */
/* Support-Tickets Auftrag 121/125 (2026-08-30, "mach einen Leerschlag
   zwischen icon und Text"): der Flexbox-`gap` auf den umgebenden Elementen
   (siehe unten) reichte auf dem Live-System offenbar nicht aus/wurde nicht
   zuverlässig gerendert - margin-right DIREKT am Icon ist die robustere,
   layout-unabhängige Lösung und wirkt garantiert, unabhängig vom
   Flex-gap-Support des Browsers. */
.nav-icon { flex-shrink: 0; opacity: 0.85; margin-right: 8px; }
/* Design-Review (2026-08-31): Füllfarben der neuen zweifarbigen Icons,
   siehe --icon-dark/--icon-light weiter oben. */
.ic-dark { fill: var(--icon-dark); }
.ic-light { fill: var(--icon-light); }
/* .btn-primary hat einen farbigen (roten) Hintergrund mit weisser Schrift -
   die roten Icon-Töne wären darauf kaum lesbar/würden mit dem Hintergrund
   verschmelzen. Icons in diesem Kontext daher wie der Button-Text auf
   Weiss/halbtransparentes Weiss umgestellt, statt die roten Icon-Variablen
   global anzupassen. */
.btn-primary .nav-icon { --icon-dark: #ffffff; --icon-light: rgba(255, 255, 255, 0.6); }
/* Gleicher Grund wie .btn-primary oben: .btn-danger bekommt beim Hover
   einen roten Hintergrund (siehe .btn-danger:hover weiter unten) - Icon
   dann ebenfalls auf Weiss umstellen. Im Ruhezustand ist .btn-danger
   transparent, dort bleibt der rote Icon-Ton unverändert lesbar. */
.btn-danger:hover .nav-icon { --icon-dark: #ffffff; --icon-light: rgba(255, 255, 255, 0.6); }

.site-header nav > a:not(.btn):hover {
    color: var(--color-primary);
}

/* Schritt 5 (Layout): aktive Seite in der Hauptnavigation sichtbar
   hervorheben - die Klasse "active" wurde von includes/header.php schon
   seit Schritt 1 gesetzt, hatte aber bisher keine zugehörige CSS-Regel
   und blieb dadurch optisch wirkungslos. */
.site-header nav > a.active:not(.btn) {
    color: var(--color-primary-dark);
    border-bottom-color: var(--color-primary);
}

/* "Entwürfe retten" (2026-08-28, 1:1 aus der Referenz-App "Küchenplaner"
   übernommen): Warnzeichen im Header neben dem Benutzernamen, sichtbar
   sobald mindestens ein nicht gespeicherter Formular-Entwurf existiert
   (siehe entwuerfe.php). */
.draft-warning-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: #fef2f2;
    border: 1px solid #fca5a5;
    color: #b91c1c;
    border-radius: 20px;
    padding: 3px 10px;
    font-size: 0.85rem;
    font-weight: 600;
    text-decoration: none;
}
.draft-warning-badge:hover { background: #fee2e2; text-decoration: none; }
.draft-warning-count { font-weight: 700; }
/* Ticket #107 (2026-08-29): ersetzt das frühere ⚠️-Emoji, siehe includes/header.php. */
.draft-warning-icon { flex-shrink: 0; }

/* Ticket #52-Folgeauftrag (2026-08-29): Hinweisbox auf Rezept-/Menü-
   Detailseite, wenn die live berechneten Warenkosten nicht alle Zeilen
   abdecken (fehlender Warenpreis, fehlende Einheiten-Umrechnung oder -
   bei Rezepten - fehlende Verknüpfung) - macht sichtbar, dass die
   Summe dadurch zu niedrig ist, statt es nur in einer kleinen grauen
   Klammer zu erwähnen. Gleiche Amber-Farbgebung wie das frühere
   "Baustelle"-Hinweispanel (Stammdaten-Umrechnung), hier aber als
   wiederverwendbare eigene Klasse statt Inline-Styles. */
.kosten-warnhinweis {
    background: #fffbeb;
    border: 1px solid #d4a017;
    border-radius: var(--radius);
    padding: 8px 12px;
    margin: 8px 0 0;
    font-size: 0.85rem;
    color: #92620a;
}
.kosten-warnhinweis a { color: inherit; text-decoration: underline; font-weight: 600; }

/* Support-Ticket Auftrag 82 (Warenkosten ein-/ausblendbar) - per Auftrag
   117 (2026-08-29) wieder entfernt: Warenkosten sind jetzt immer sichtbar,
   .warenkosten-toggle-row/.warenkosten-block/.ist-ausgeblendet werden im
   Markup nicht mehr erzeugt, die zugehörigen Regeln sind daher entfallen. */

/* Schritt 5 (Layout): Basis-Styling für das Nutzermenü (<details
   class="user-menu"> in includes/header.php) - fehlte bisher komplett,
   wurde seit Schritt 1 nur mit dem unstyled Browser-Standard für
   <details>/<summary> dargestellt (klappte einfach den Inhalt block-weise
   auf, keine schwebende Dropdown-Optik). */
.user-menu { position: relative; list-style: none; }
.user-menu summary {
    display: inline-flex;
    align-items: center;
    cursor: pointer;
    color: var(--color-text-muted);
    font-weight: 500;
    list-style: none;
    padding: 4px 2px;
    border-bottom: 2px solid transparent;
}
.user-menu summary::-webkit-details-marker { display: none; }
.user-menu summary:hover { color: var(--color-primary); }
.user-menu.active summary { color: var(--color-primary-dark); border-bottom-color: var(--color-primary); }
.user-menu-panel {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-hover);
    padding: 6px;
    min-width: 160px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    z-index: 20;
}
.user-menu-link {
    display: flex;
    align-items: center;
    padding: 8px 10px;
    border-radius: 8px;
    color: var(--color-text);
    font-weight: 500;
    font-size: 0.9rem;
}
.user-menu-link:hover { background: var(--color-bg); color: var(--color-primary); }
.user-menu-link.active { color: var(--color-primary-dark); background: var(--color-bg); }

/* Verschachteltes Stammdaten-Untermenü im Nutzermenü (2026-08-27,
   Referenz-Angleichung) - gleiches <details>/<summary>-Grundmuster wie
   .user-menu, aber flach im Panel eingebettet statt absolut positioniert
   (klappt den restlichen Panel-Inhalt nach unten weg statt zu überlappen -
   bei nur 6 kurzen Links unproblematisch). */
/* Support-Ticket Auftrag 35 (2026-08-28): "Support", "Stammdaten" und
   "Import/Export" sollen exakt untereinander stehen - explizite
   margin:0/padding, damit das verschachtelte <details>-Element (Browser-
   Vorgaben können hier leicht abweichen) garantiert dieselbe Breite/
   Ausrichtung wie die einfachen .user-menu-link-Zeilen erhält. */
/* Support-Ticket #224 (2026-09-05): auf-/zuklappbare Bereichs-Gruppen auf
   abostufen_verwaltung.php ("Merkmale & Sichtbarkeit") - eigene, schlichtere
   Klasse statt .stammdaten-submenu, da diese für die schmale Nav-Dropdown-
   Optik gedacht ist (Einzug/Flex-Wrap), hier aber ein ganzer Tabellen-
   Abschnitt im Hauptinhalt gruppiert wird. */
/* Support-Ticket #230 (2026-09-06, PO wörtlich: "Externe Preisquellen/
   Allergene/Nährwerte ... aufklappbar Standardmässig eingeklappt"):
   ".formular-abschnitt-klapp" ist derselbe visuelle Baustein wie
   ".abo-merkmal-gruppe" (Rahmen/Abstand identisch, daher weiterhin
   zusammengefasst), nur unter einem Namen, der auch ausserhalb der
   Abostufen-Verwaltung Sinn ergibt - für einklappbare Formular-Abschnitte
   auf artikel_form.php/rezept_form.php/menue_form.php/rezept.php.
   Schriftgrösse/Dreieck-Position der summary-Zeile sind seit Ticket #257
   NICHT mehr gemeinsam geregelt (siehe zwei getrennte Blöcke weiter
   unten), da beide Klassen inzwischen unterschiedliche Ziel-Optik haben. */
.abo-merkmal-gruppe,
.formular-abschnitt-klapp {
    border: 1px solid var(--color-border);
    border-radius: 8px;
    margin: 0 0 14px;
    padding: 0 14px;
}
.abo-merkmal-gruppe summary,
.formular-abschnitt-klapp summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 -14px;
    padding: 10px 14px;
}
.abo-merkmal-gruppe .data-table { margin: 0 0 12px; }
.formular-abschnitt-klapp > summary + * { margin-top: 10px; }
.formular-abschnitt-klapp[open] { padding-bottom: 14px; }

/* .abo-merkmal-gruppe ("Merkmale & Sichtbarkeit" auf abostufen_
   verwaltung.php) - Ticket #241 (2026-09-06, "Schriftgrösse wie 'Merkmale &
   Sichtbarkeit'", h2-Grösse 1.5rem) bleibt hier unverändert bestehen, dafür
   wurde in Ticket #257 keine Änderung verlangt - bewusst NICHT mit
   .formular-abschnitt-klapp zusammengefasst, siehe Ticket-#257-Kommentar
   unten. */
.abo-merkmal-gruppe summary {
    font-size: 1.5rem;
    line-height: 1.2;
    font-weight: 600;
}
.abo-merkmal-gruppe summary::marker,
.abo-merkmal-gruppe summary::-webkit-details-marker { display: none; content: ''; }
.abo-merkmal-gruppe summary::after {
    content: '▸';
    font-size: 0.85rem;
    color: var(--color-text-muted);
    transition: transform 0.15s ease;
    margin-left: auto;
}
.abo-merkmal-gruppe[open] summary::after { transform: rotate(90deg); }

/* Support-Ticket #257 (2026-09-07, PO wörtlich: "alles was auf dieser
   Seite und auf allen anderen Seiten aufklappbar ist entsprechend mit
   Dreieck kennzeichnen [...] Überschriftgrösse von Externe Preisquellen/
   Allergene/Nährwerte/Diese Ware kann nicht... anpassen wie die
   Schriftgrösse von Weitere Einheiten"): löst/korrigiert die frühere,
   ebenfalls bewusste Ticket-#241-Entscheidung (1.5rem/Pfeil rechts) für
   ALLE Verwender von .formular-abschnitt-klapp (artikel_form.php:
   Externe Preisquellen/Allergene/Nährwerte/"Diese Ware kann nicht
   gelöscht werden..." x2; rezept.php: Löschschutz-Hinweis) - der PO will
   diese Abschnitte jetzt nicht mehr wie ein <h2>, sondern wie ein
   normales Formular-Label wirken lassen. "Weitere Einheiten" ist auf
   artikel_form.php ein simples <label> ohne eigene Klasse, erbt also
   .form-group label (0.9rem/600, siehe weiter unten in dieser Datei) -
   exakt diese Werte hier übernommen. Dreieck jetzt VORNE (::before) statt
   rechts aussen (::after), gleiches Prinzip wie die bisherige Modifier-
   Klasse .formular-abschnitt-klapp-klein aus Ticket #254/#255 (h3-Grösse,
   siehe eigener Block weiter unten) - deren rezept.php-Löschschutz-Hinweis
   ist von #257 NICHT namentlich erfasst und bleibt daher bewusst bei
   seiner eigenen, etwas grösseren h3-Optik (die Basisklasse hier greift
   für ihn nur noch bei der Pfeil-Richtung, nicht bei der Schriftgrösse -
   die Modifier-Klasse überschreibt Letztere weiterhin per höherer
   Spezifität). .abo-merkmal-gruppe (siehe oben) ist von alldem bewusst
   NICHT betroffen - dafür wurde keine Änderung verlangt. */
.formular-abschnitt-klapp summary {
    font-size: 0.9rem;
    font-weight: 600;
}
.formular-abschnitt-klapp summary::marker,
.formular-abschnitt-klapp summary::-webkit-details-marker { display: none; content: ''; }
.formular-abschnitt-klapp summary::before {
    content: '▸';
    font-size: 0.75rem;
    color: var(--color-text-muted);
    transition: transform 0.15s ease;
}
.formular-abschnitt-klapp[open] summary::before { transform: rotate(90deg); }

/* Support-Ticket #254/#255 (2026-09-06) - Modifier-Klasse für den
   rezept.php-Löschschutz-Hinweis. Ticket #257 (Basisklasse s.o.) nennt
   für die Schriftgrösse ausdrücklich nur die artikel_form.php-Abschnitte
   (Externe Preisquellen/Allergene/Nährwerte/"Diese Ware kann nicht..."),
   NICHT den rezept.php-Löschschutz-Hinweis - diese Modifier-Klasse bleibt
   daher unverändert bei der h3-Grösse (1.17em) aus #254/#255 bestehen und
   überschreibt die neue, kleinere Basisgrösse hier bewusst weiter (höhere
   Spezifität durch die zusammengesetzte Klasse). Die Pfeil-Position VORNE
   (::before) ist ohnehin identisch zur neuen Basisklasse - hier redundant,
   aber harmlos, da beide denselben Wert liefern. */
.formular-abschnitt-klapp.formular-abschnitt-klapp-klein summary {
    font-size: 1.17em;
}
.formular-abschnitt-klapp.formular-abschnitt-klapp-klein summary::after {
    content: none;
}
.formular-abschnitt-klapp.formular-abschnitt-klapp-klein summary::before {
    content: '▸';
    font-size: 0.85rem;
    color: var(--color-text-muted);
    transition: transform 0.15s ease;
}
.formular-abschnitt-klapp.formular-abschnitt-klapp-klein[open] summary::before {
    transform: rotate(90deg);
}

/* Support-Ticket #228 (2026-09-05): Live-Markierung "welche Stufe ich sehen
   will" - enthalten (grüner Rand, wie die bestehende Aktionspreis-Farbe
   #5c7a52) vs. nicht enthalten (abgeblendet, analog zum bestehenden
   Transparent-Modus-Look), rein über CSS-Klassen aus dem Vorschau-Skript. */
.abo-merkmal-enthalten { box-shadow: inset 3px 0 0 #5c7a52; }
.abo-merkmal-nicht-enthalten { opacity: 0.45; }

.stammdaten-submenu { border-radius: 8px; margin: 0; }
.stammdaten-submenu summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    margin: 0;
    padding: 8px 10px;
}
.stammdaten-submenu summary::marker { display: none; content: ''; }
.stammdaten-submenu summary::-webkit-details-marker { display: none; }
.stammdaten-submenu summary::after {
    content: '▸';
    font-size: 0.75rem;
    color: var(--color-text-muted);
    transition: transform 0.15s ease;
    margin-left: auto;
    padding-left: 8px;
}
.stammdaten-submenu[open] summary::after { transform: rotate(90deg); }
.stammdaten-submenu-panel {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 2px 0 2px 14px;
}
.user-menu-sublink {
    display: flex;
    align-items: center;
    padding: 7px 10px;
    border-radius: 8px;
    color: var(--color-text-muted);
    font-weight: 500;
    font-size: 0.85rem;
}
.user-menu-sublink .nav-icon { width: 15px; height: 15px; }
.user-menu-sublink:hover { background: var(--color-bg); color: var(--color-primary); }

/* Schritt 5 (Layout): Hamburger-Knopf für die mobile Navigation - nur
   unterhalb des Breakpoints sichtbar (siehe @media-Regel weiter unten). */
.nav-toggle {
    display: none;
    background: none;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 8px 10px;
    cursor: pointer;
    color: var(--color-text);
}

.nav-toggle svg { display: block; }

main.container {
    padding-top: 32px;
    padding-bottom: 64px;
    min-height: 60vh;
}

.page-head {
    margin-bottom: 24px;
}

.subtitle {
    color: var(--color-text-muted);
    margin: 0;
}

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 10px 18px;
    border-radius: 999px;
    border: 1px solid transparent;
    font-weight: 600;
    font-size: 0.92rem;
    cursor: pointer;
    transition: transform 0.1s ease, box-shadow 0.15s ease, background 0.15s ease;
}

.btn:hover { transform: translateY(-1px); }

.btn-primary {
    background: var(--color-primary);
    color: #fff;
}
.btn-primary:hover { background: var(--color-primary-dark); }

.btn-secondary {
    background: var(--color-surface);
    color: var(--color-text);
    border-color: var(--color-border);
}
.btn-secondary:hover { border-color: var(--color-primary); color: var(--color-primary); }

.btn-ghost {
    background: transparent;
    color: var(--color-text-muted);
    border-color: transparent;
}
.btn-ghost:hover { color: var(--color-primary); }

.btn-danger {
    background: transparent;
    color: var(--color-danger);
    border-color: var(--color-danger);
}
.btn-danger:hover { background: var(--color-danger); color: #fff; }

/* Support-Ticket #258 (2026-09-07): Schnellwahl-Knopfgruppe für die
   Volumen-Einheiten (l/dl/ml/TL/EL/Tasse) beim Feld "Einheit *" in
   artikel_form.php, siehe VOLUMEN_EINHEITEN_ML in includes/functions.php.
   Kompakte, umbrechende Knopfreihe unter dem bestehenden Textfeld - bewusst
   kleiner/dezenter als die normalen .btn-Elemente, da es sich um eine
   Zusatzfunktion neben dem weiterhin massgeblichen Textfeld handelt. */
.einheit-schnellwahl {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
}
.einheit-schnellwahl-btn {
    padding: 4px 10px;
    border-radius: 999px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-text-muted);
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.einheit-schnellwahl-btn:hover { border-color: var(--color-primary); color: var(--color-primary); }
.einheit-schnellwahl-btn.active {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

/* Flash messages */
.flash {
    padding: 12px 18px;
    border-radius: var(--radius);
    margin-bottom: 20px;
    font-weight: 500;
}
.flash-success { background: #e7f0e2; color: #3f5c34; }
.flash-error { background: #f6e2df; color: #8a352b; }
/* Support-Ticket #162 (2026-08-30): neutraler Hinweiskasten (weder Erfolg
   noch Fehler) - z.B. für den FotoRezept-Import-Hinweis auf entwuerfe.php. */
.flash-info { background: #e6edf3; color: #33475b; }

/* Filter bar */
/* Support-Ticket #253 (2026-09-06, "alle drei eingabefelder nach unten
   ausgerichtet"): das Suchfeld sitzt in .filter-field (Label ÜBER dem
   Feld, siehe weiter unten in dieser Datei), die einfachen <select>-
   Filter (Quelle/Kategorie/Waren-Verknüpfung) haben dagegen kein eigenes
   Label und sind dadurch niedriger als .filter-field insgesamt. Ohne
   eigenes align-items nutzt Flexbox standardmässig "stretch" - die
   Kind-Elemente werden oben ausgerichtet, wodurch das eigentliche
   Eingabefeld innerhalb von .filter-field (unterhalb seines Labels)
   sichtbar tiefer sitzt als die daneben stehenden <select>-Felder.
   align-items: flex-end richtet alle Zeilen-Elemente an ihrer Unterkante
   aus - Label und Select "schweben" dann zwar unterschiedlich hoch, aber
   die eigentlichen Eingabe-/Auswahlfelder selbst liegen auf einer Linie. */
.filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 10px;
    margin-bottom: 32px;
}

.search-input, .category-select {
    padding: 10px 14px;
    border-radius: var(--radius);
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    font-size: 0.95rem;
    font-family: inherit;
}

.search-input { flex: 1; min-width: 220px; }

/* Support-Ticket #222 (2026-09-04, "Alle Eingabefelder gleiche Höhe",
   artikel_liste.php, Waren-Werkzeugleisten): trotz identischer vertikaler
   padding rendern <input>/<select>/<button> browserintern leicht
   unterschiedlich hoch (native Select-Pfeile, abweichende Zeilenhöhen je
   Element), UND .btn-sm (padding 6px 12px, siehe oben) ist gegenüber
   .search-input/.category-select (padding 10px 14px) spürbar niedriger,
   wenn beide in derselben Zeile stehen (z.B. "Waren verschieben"-Leiste:
   Kategorie/Lieferant-Auswahl neben den Icon-Knöpfen). Feste, gemeinsame
   Höhe für Such-/Auswahlfelder und die Knöpfe in denselben Werkzeugleisten
   löst beides auf einmal - .btn nutzt bereits display:inline-flex;
   align-items:center (siehe oben), zentriert den Inhalt bei fester Höhe
   also automatisch sauber. */
/* Support-Tickets #293/#296/#297 (2026-09-08): "Alle Eingabefelder gleich hoch
   machen und zeilenAbstand gleich machen" (Rezepte-Liste), "Eingabefelder
   Zeilenabstand geringer machen" und "Alle eingabefelder gleiche Hoehe"
   (Waren-Liste). Ticket #222 hatte 40 px nur fuer Elemente MIT den Klassen
   .search-input/.category-select/.btn gesetzt - ein Suchfeld ohne Klasse, ein
   blankes <select> oder der Aufklapp-Knopf "Ohne Allergene" blieben davon
   unberuehrt und standen deshalb unterschiedlich hoch in derselben Zeile.
   Jetzt strukturell statt nach Klasse: alles, was direkt in der Filterleiste
   (oder in einem .filter-field darin) sitzt, ist gleich hoch. Bewusst mit
   Kind-Selektoren - ein pauschales ".filter-bar input" wuerde auch die
   Allergen-Haekchen im Aufklapp-Panel auf 40 px aufblasen. */
.filter-bar > input,
.filter-bar > select,
.filter-bar > .btn,
.filter-bar > button,
.filter-bar > .filter-field > input,
.filter-bar > .filter-field > select,
.filter-bar > .filter-details > summary,
.bulk-actions-bar-body .search-input,
.bulk-actions-bar-body .category-select,
.bulk-actions-bar-body .btn {
    height: 40px;
    box-sizing: border-box;
}
/* Der Aufklapp-Knopf hat seine Hoehe bisher aus der Innenabstand-Angabe
   bezogen (padding: 10px 14px) - mit fester Hoehe muss der Text stattdessen
   mittig ausgerichtet werden, sonst klebt er oben. */
.filter-bar > .filter-details > summary {
    display: inline-flex;
    align-items: center;
    padding-top: 0;
    padding-bottom: 0;
}
/* Zeilenabstand: 10 px waren als gemeinsamer Abstand gesetzt - beim Umbruch
   auf mehrere Zeilen wirkte das zu luftig (#296). Waagrecht bleibt es bei
   10 px, senkrecht enger. */
.filter-bar {
    column-gap: 10px;
    row-gap: 6px;
}

/* Support-Ticket #294 (2026-09-08, "Alle 'Bearbeiten Icon' rechts
   ausrichten"): die Aktionsspalte hatte bisher gar keine eigene Regel, die
   Symbole standen also linksbuendig in einer meist breiten letzten Spalte.
   Zentral geloest, damit Waren-, Rezepte- und Menue-Uebersicht nicht
   auseinanderlaufen - die Aktionsspalte heisst auf allen drei Seiten gleich. */
.data-table td.col-actions,
.col-actions { text-align: right; }
.row-action-icons { justify-content: flex-end; }

/* "Ohne diese Allergene"-Filter (2026-08-27, Referenz-Angleichung) - ein
   <details>-Aufklapp-Kasten mit Allergen-Checkboxen (menue_liste.php,
   rezepte_liste.php), gleiches .checkbox-grid/.checkbox-chip wie im
   Allergene-Auswahlblock im Waren-Formular (Schritt 3). */
.filter-details {
    display: flex;
    align-items: flex-start;
    position: relative;
}
.filter-details summary {
    list-style: none;
    cursor: pointer;
    padding: 10px 14px;
    border-radius: var(--radius);
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    font-size: 0.9rem;
    color: var(--color-text-muted);
}
.filter-details summary::-webkit-details-marker { display: none; }
.filter-details[open] summary { border-color: var(--color-primary); color: var(--color-primary); }
.filter-details-panel {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 15;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-hover);
    padding: 14px;
    min-width: 280px;
    max-width: 360px;
}
/* Auftrag 16 (2026-08-27): Ware-per-Suche-zur-Auswahl-hinzufügen im
   "Waren verschieben"-Kasten (artikel_liste.php) - gleiches Dropdown-
   Muster wie .filter-details-panel. */
.bulk-artikel-suche-ergebnisse {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    z-index: 15;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-hover);
    min-width: 280px;
    max-width: 420px;
    max-height: 260px;
    overflow-y: auto;
}
.bulk-artikel-suche-treffer {
    display: block;
    width: 100%;
    text-align: left;
    padding: 8px 12px;
    border: none;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-text);
    font-size: 0.88rem;
    cursor: pointer;
}
.bulk-artikel-suche-treffer:last-child { border-bottom: none; }
.bulk-artikel-suche-treffer:hover:not(:disabled) { background: var(--color-bg); }
.bulk-artikel-suche-treffer:disabled {
    color: var(--color-text-muted);
    cursor: default;
}

.filter-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 10px;
}
.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border-radius: 999px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    font-size: 0.82rem;
}
.filter-chip-remove {
    color: var(--color-text-muted);
    font-size: 0.9rem;
    line-height: 1;
    text-decoration: none;
}
.filter-chip-remove:hover { color: var(--color-danger); }

/* Support-Ticket Auftrag 42 (2026-08-28): Layout-Wrapper für die beiden
   "Ware(n) im Rezept"/"Ohne Ware(n)"-Boxen auf rezepte_liste.php - 1:1
   Layout-Regel aus der Referenz-App übernommen (dort .ware-filter-row/
   .ware-filter-box), Chips/Checkbox-Auswahl selbst nutzen bewusst die
   bereits vorhandenen .filter-chip(-row/-remove)/.checkbox-grid/
   .checkbox-chip-Klassen (siehe rezepte_liste.php), keine Dopplung. */
.ware-filter-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; margin-bottom: 20px; }
.ware-filter-box { min-width: 0; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); padding: 12px 16px; }

/* Recipe grid */
.recipe-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 24px;
}

/* Schritt 5 (Layout): index.php (Dashboard, seit Schritt 1) verwendet
   diese vier Klassen für die Kennzahlen-Kacheln und die Übersichtskarten -
   es gab dafür bisher KEINE CSS-Regeln (echte Lücke seit Schritt 1,
   dadurch erschien die Startseite bisher unstyled/als reine Textliste). */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 16px;
    margin-bottom: 32px;
}

.stat-card {
    background: var(--color-surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 20px;
    text-align: center;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.stat-value {
    font-family: var(--app-font, Arial, sans-serif);
    font-size: 2rem;
    font-weight: 700;
    color: var(--color-primary-dark);
}

.stat-label {
    color: var(--color-text-muted);
    font-size: 0.85rem;
}

.dashboard-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 20px;
}

.dashboard-card {
    background: var(--color-surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 24px;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
    display: block;
}

.dashboard-card:hover,
.dashboard-card:focus-visible {
    transform: translateY(-3px);
    box-shadow: var(--shadow-hover);
}

.dashboard-card h3 {
    margin: 0 0 8px;
    font-size: 1.1rem;
}

.dashboard-card p {
    margin: 0;
    color: var(--color-text-muted);
    font-size: 0.9rem;
}

.recipe-card {
    background: var(--color-surface);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
    display: flex;
    flex-direction: column;
}

.recipe-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-hover);
}

.recipe-card-image {
    position: relative;
    aspect-ratio: 4 / 3;
    background: #f0e6d8;
}

.recipe-card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.recipe-card-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2.5rem;
}

.badge {
    position: absolute;
    top: 10px;
    left: 10px;
    background: rgba(255, 255, 255, 0.92);
    color: var(--color-primary-dark);
    font-size: 0.75rem;
    font-weight: 600;
    padding: 4px 10px;
    border-radius: 999px;
}

.recipe-hero .badge {
    position: static;
    display: inline-block;
    margin-bottom: 10px;
}

/* Auftrag 22, Kategorie A (2026-08-27): rezept.php zeigt die Kategorie-
   Badge jetzt direkt im page-head statt im (entfernten) recipe-hero-Bild -
   gleiche Freistellung wie oben bei .recipe-hero .badge. */
.page-head .badge {
    position: static;
    display: inline-block;
    margin-bottom: 8px;
}

.recipe-card-body {
    padding: 16px;
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.recipe-card-body h3 {
    font-size: 1.15rem;
}

.recipe-card-body p {
    color: var(--color-text-muted);
    font-size: 0.9rem;
    margin: 0;
    flex: 1;
}

.recipe-card-meta {
    display: flex;
    gap: 14px;
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

.empty-state {
    text-align: center;
    padding: 64px 24px;
    color: var(--color-text-muted);
}
.empty-state .btn { margin-top: 12px; }

/* Recipe detail */
.back-link {
    display: inline-block;
    margin-bottom: 20px;
    color: var(--color-text-muted);
    font-weight: 500;
}
.back-link:hover { color: var(--color-primary); }

/* Support-Ticket #158 (2026-08-30): Vorheriges/Nächstes-Navigation, einzige
   Erzeugungsstelle ist render_prev_next_nav() (includes/functions.php) -
   diese Klassen sind daher bewusst die EINZIGE Stelle, die das Aussehen
   bestimmt, damit rezept.php/menu_ansicht.php/artikel_form.php garantiert
   identisch aussehen. .back-link-row bettet die vorhandene .back-link
   zusammen mit der neuen Navigation in eine gemeinsame Kopfzeile ein, ohne
   deren bisherigen margin-bottom zu verlieren. */
.back-link-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 20px;
}
.back-link-row .back-link { margin-bottom: 0; }
.prev-next-nav {
    display: flex;
    gap: 6px;
    flex-shrink: 0;
}
.prev-next-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
}
.prev-next-btn-disabled {
    opacity: 0.35;
    cursor: default;
    pointer-events: none;
}

.recipe-hero {
    display: grid;
    grid-template-columns: 1fr;
    gap: 24px;
    background: var(--color-surface);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow);
    margin-bottom: 32px;
}

.recipe-hero-image {
    width: 100%;
    max-height: 420px;
    object-fit: cover;
    display: block;
}

.recipe-hero-content {
    padding: 24px 28px 28px;
}

.recipe-hero-content h1 {
    font-size: 2rem;
}

.recipe-description {
    color: var(--color-text-muted);
    margin: 0 0 16px;
}

.recipe-meta {
    display: flex;
    gap: 32px;
    margin: 16px 0;
}

.recipe-meta > div {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.recipe-meta span {
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.recipe-meta strong {
    font-size: 1.05rem;
}

.recipe-actions {
    display: flex;
    gap: 10px;
    margin-top: 16px;
}

.recipe-content {
    display: grid;
    grid-template-columns: 280px 1fr;
    gap: 32px;
}

.ingredients-section, .instructions-section {
    background: var(--color-surface);
    border-radius: var(--radius);
    padding: 24px;
    box-shadow: var(--shadow);
}

.ingredients-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.ingredients-list li {
    display: flex;
    gap: 10px;
    padding: 8px 0;
    border-bottom: 1px solid var(--color-border);
}
.ingredients-list li:last-child { border-bottom: none; }

.ingredient-amount {
    font-weight: 600;
    color: var(--color-secondary);
    min-width: 70px;
    flex-shrink: 0;
}

.instructions-text {
    white-space: pre-line;
}

.muted { color: var(--color-text-muted); }

/* Forms */
.recipe-form {
    background: var(--color-surface);
    border-radius: var(--radius);
    padding: 28px;
    box-shadow: var(--shadow);
    max-width: 820px;
}

.form-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
}

.form-group-wide {
    grid-column: 1 / -1;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.form-group label {
    font-weight: 600;
    font-size: 0.9rem;
}

/* Korrektur (2026-08-26, Layout-Prüfung nach Screenshot-Vergleich): ein
   einzelner <button>/<a class="btn"> als direktes Kind von .form-group
   (flex-direction:column, kein align-items gesetzt) wird sonst per
   Browser-Standard (align-items:stretch) auf die volle Breite gedehnt -
   der Button-Text (per .btn { justify-content:center }) erscheint dann
   mittig über die ganze Formularbreite statt als kompakter Link/Button
   an natürlicher Stelle. Betraf konkret "+ Einheit hinzufügen" im
   Artikel-Formular (artikel_form.php, #article-unit-add) - analog zum
   bereits vorhandenen Fix bei .supplier-add-form .btn (dort per Grid/
   justify-self:start gelöst). */
.form-group > .btn {
    align-self: flex-start;
}

.form-group input[type="text"],
.form-group input[type="number"],
.form-group input[type="file"],
.form-group select,
.form-group textarea {
    padding: 10px 12px;
    border-radius: 8px;
    border: 1px solid var(--color-border);
    font-family: inherit;
    font-size: 0.95rem;
    background: var(--color-bg);
}

.form-group textarea { resize: vertical; }

.current-image {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 6px;
}
/* Gleiche Aenderung wie bei .article-image-preview (Ticket #335): das ist
   derselbe Vorschaukasten, nur im Rezept-/Menueformular. Die PO-Direktive
   "wenn etwas geaendert wird, das eine andere Seite betrifft, muss das
   automatisch mitgeaendert werden" gilt hier wortwoertlich - sonst zeigt
   dieselbe Vorschau auf zwei Seiten zwei verschiedene Bildausschnitte.
   Listen-Miniaturen (.list-thumb, .recipe-card-image) bleiben bewusst bei
   cover: dort ist ein gleichmaessig gefuelltes Raster gewollt. */
.current-image img {
    width: 56px;
    height: 56px;
    object-fit: contain;
    background: var(--color-bg);
    border-radius: 8px;
}
.current-image span { font-size: 0.8rem; }

/* Support-Tickets #104/#105 (2026-08-29): vorher ein starres CSS-Grid mit
   fester Spaltenzahl (6 Spuren) - bei einer sortierbaren Zeile kommen aber
   bis zu 8 Elemente vor (Ziehgriff, ▲/▼, Menge, Einheit, Name, Ausrüstung,
   Textbaustein, Entfernen-Knopf), was zu unübersichtlichem Umbruch führte;
   dazu liess die mobile Grid-Regel (siehe frühere @media-Regel weiter
   unten) "Menge"/"Einheit" auf je 50% der Zeilenbreite anwachsen ("viel zu
   gross", Ticket #105). Jetzt Flexbox mit flexiblem Umbruch statt fester
   Spurenzahl - passt sich automatisch an unterschiedliche Element-Anzahlen
   an (Zutatenliste vs. Geschirr-Bereich) und hält Menge/Einheit auf allen
   Bildschirmgrössen kompakt (siehe .ing-amount/.ing-unit unten). */
.ingredient-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
}

/* Support-Ticket #247 (2026-09-06, "jede zweite Warenzeile muss hellgrau
   sein"): gleicher Grauton wie die bereits bestehende alternierende
   Zeilenfärbung an anderer Stelle im Projekt (siehe .zutaten-tabelle bzw.
   .einkaufsliste-table.zebra weiter oben) - hier auf die Zutaten-/
   Geschirr-Zeilen des Rezeptformulars angewendet. Textbaustein-Zeilen
   bewusst ausgenommen (:not(.is-text-baustein)), da diese als eigene
   Zwischenüberschrift/Abschnittstrenner optisch erkennbar bleiben sollen,
   nicht im normalen Streifenmuster untergehen. Kleiner Innenabstand +
   Rundung, damit der Grauton sichtbar als eigene Zeile wirkt statt direkt
   an den Feldrändern zu kleben. */
#ingredients-list .ingredient-row:nth-child(even):not(.is-text-baustein),
#equipment-list .ingredient-row:nth-child(even) {
    background: #ececec;
    border-radius: 6px;
    padding: 4px 6px;
    margin-left: -6px;
    margin-right: -6px;
}

.ingredient-row input[type="text"] {
    padding: 9px 10px;
    border-radius: 8px;
    border: 1px solid var(--color-border);
    font-family: inherit;
    background: var(--color-bg);
}

/* Ticket #111 (2026-08-29, Folgeauftrag zu Ticket #105): Menge/Einheit
   nochmals verschmälert, da dem Nutzer die vorherige Breite (64px/76px)
   weiterhin zu breit war - engerer Innenabstand bei diesen beiden Feldern,
   damit trotz der geringeren Breite noch genug Platz für 2-3 Ziffern bzw.
   Kürzel wie "kg"/"EL" bleibt. */
.ingredient-row .ing-amount,
.ingredient-row .ing-unit {
    padding-left: 6px;
    padding-right: 6px;
}

.ingredient-row .ing-amount {
    flex: 0 1 46px;
}

.ingredient-row .ing-unit {
    flex: 0 1 54px;
}

.ingredient-row .ing-name {
    flex: 1 1 140px;
}

/* Ticket #112 (2026-08-29): macht sichtbar, dass "Ausrüstung" einen
   erklärenden Tooltip hat (siehe title-Attribut auf .ing-ausruestung-label
   in rezept_form.php).
   Ticket #244 (2026-09-06): aus dem reinen aria-hidden-Hover-Symbol ist ein
   echter <button> geworden (title-Tooltips sind auf Touch-Geräten nicht
   erreichbar, siehe Docblock in rezept_form.php) - Button-Grundstil
   zurückgesetzt, damit er weiterhin wie ein kleines, unaufdringliches
   Symbol neben dem Wort "Ausrüstung" aussieht statt wie ein Formular-Knopf. */
.ing-info-btn {
    background: none;
    border: none;
    padding: 0 0 0 2px;
    margin: 0;
    color: var(--color-text-muted);
    font-size: 0.95em;
    line-height: 1;
    cursor: pointer;
    font-family: inherit;
}
.ing-info-btn:hover,
.ing-info-btn:focus-visible {
    color: var(--color-text);
}

/* Ticket #244: der per Klick/Tap ein-/ausgeblendete Erklärtext neben dem
   ⓘ-Knopf - flex-basis 100% lässt ihn im umbrechenden .ingredient-row-Flex
   (flex-wrap: wrap) sauber in eine eigene Zeile fallen, statt die anderen
   Felder zu verschieben. */
.ing-info-text {
    flex: 1 1 100%;
    font-size: 0.82rem;
    color: var(--color-text-muted);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 6px;
    padding: 6px 10px;
    margin-top: -2px;
}

/* Support-Ticket #262 (2026-09-07, "(generiere info icon)"): derselbe
   Klick/Tap-ⓘ-Baustein wie bei .ing-info-btn/.ing-info-text (Ticket #244),
   hier für den Warenkosten-Warnhinweis auf rezept.php
   (p.kosten-warnhinweis) - bewusst EIGENE, gleich aussehende Klassen statt
   Wiederverwendung von .ing-info-btn/.ing-info-text, da Letztere für den
   umbrechenden Flex-Kontext der Zutatenzeilen gedacht sind
   (flex: 1 1 100%), der Warnhinweis hier aber ein normaler Fliesstext-
   Absatz ohne Flex-Elternelement ist - display:block statt flex-basis
   erreicht denselben "eigene Zeile"-Effekt. */
.warnhinweis-info-btn {
    background: none;
    border: none;
    padding: 0 0 0 2px;
    margin: 0;
    color: var(--color-text-muted);
    font-size: 0.95em;
    line-height: 1;
    cursor: pointer;
    font-family: inherit;
}
.warnhinweis-info-btn:hover,
.warnhinweis-info-btn:focus-visible {
    color: var(--color-text);
}
.warnhinweis-info-text {
    display: block;
    font-size: 0.82rem;
    color: var(--color-text-muted);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 6px;
    padding: 6px 10px;
    margin: 4px 0;
}

/* Ticket #115 (2026-08-29, Nutzerwunsch "Dreiecke sind zuviel, wenn ich die
   Griffe vorne habe"): die ▲/▼-Knöpfe NICHT entfernt, da sie laut Docblock
   bei $renderIngredientRow() die verpflichtende Tastatur-Alternative zum
   nur mit der Maus bedienbaren Ziehgriff (.ing-drag-handle, aria-hidden)
   sind - ein Löschen würde Tastatur-/Screenreader-Nutzer:innen die einzige
   Möglichkeit zum Verschieben nehmen und dem Projektstandard "Drag&Drop per
   Maus MUSS eine tastaturbedienbare Alternative haben" widersprechen.
   Stattdessen (gleiches Muster wie .skip-link): visuell ausgeblendet, bis
   ein Knopf per Tab-Taste fokussiert wird - Maus-Nutzer:innen sehen die
   Dreiecke dadurch nicht mehr, Tastatur-Nutzer:innen weiterhin. */
.ing-move-buttons button {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
.ing-move-buttons button:focus {
    position: static;
    width: auto;
    height: auto;
    margin: 0 2px;
    overflow: visible;
    clip: auto;
    white-space: normal;
    padding: 2px 7px;
    border: 1px solid var(--color-border);
    border-radius: 4px;
    background: var(--color-surface);
    cursor: pointer;
}

/* Schritt 6 (Menü): Positionszeilen haben zusätzlich ein Typ-Auswahlfeld
   (Ware/Rezept/Frei) - eigene Spaltenaufteilung (6 statt 5 Spuren) und
   <select>-Styling, das die bisherige Zutatenzeile nicht brauchte. */
.ingredient-row select {
    padding: 9px 10px;
    border-radius: 8px;
    border: 1px solid var(--color-border);
    font-family: inherit;
    background: var(--color-bg);
    color: var(--color-text);
}

.position-row {
    grid-template-columns: 100px 1fr 90px 100px auto auto;
}

/* Schritt 4 (Rezept): Geschirr/Geräte/Nonfood-Kennzeichnung je Zutatenzeile
   (analog zu recipe_ingredients.ist_ausruestung in der Referenz-App) */
.ing-ausruestung-label {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 0.8rem;
    color: var(--color-text-muted);
    white-space: nowrap;
    cursor: pointer;
}

/* Auftrag 22, Kategorie C, Textbausteine (2026-08-28): gleiches Muster wie
   .ing-ausruestung-label, eigene Klasse statt Wiederverwendung, damit
   beide Häkchen unabhängig voneinander per JS ein-/ausblendbar bleiben.
   Support-Ticket #104 (2026-08-29, "Textbausteine machen die Sache sehr
   unübersichtlich, entferne diese, ausser man braucht die zwingend"): das
   Häkchen war bisher auf JEDER Zutatenzeile sichtbar, obwohl es nur bei
   einer bereits als Textbaustein markierten Zeile wirklich gebraucht wird
   (zum Zurückwandeln in eine normale Zutat) - Standardfall jetzt versteckt,
   nur noch sichtbar, wenn die Zeile schon .is-text-baustein trägt. Neue
   Textbaustein-Zeilen entstehen stattdessen bewusst über den Knopf "+ Neue
   Textzeile einfügen" bzw. das bestehende Textbaustein-Suchpanel (beide
   setzen das Häkchen direkt gesetzt an, siehe rezept_form.php) statt über
   dieses Häkchen auf einer gewöhnlichen Zeile. */
.ing-textbaustein-label {
    display: none;
    align-items: center;
    gap: 5px;
    font-size: 0.8rem;
    color: var(--color-text-muted);
    white-space: nowrap;
    cursor: pointer;
}

.ingredient-row.is-text-baustein .ing-textbaustein-label {
    display: flex;
}

/* Support-Ticket #50 (Referenz-Angleichung, 2026-08-28): Geschirr/Geräte-
   Bereich - eigener, separater Klapp-Bereich (siehe rezept_form.php) statt
   nur der bisherigen inline-Checkbox. Zeilen darin sind nie ein
   Textbaustein (analog zur Referenz-App, deren Geschirr-Tabelle gar keine
   Textbaustein-Spalte hat) - das Häkchen dafür bleibt technisch auf der
   gemeinsam genutzten Zeilen-Vorlage vorhanden, wird hier aber ausgeblendet.
   #equipment-list nutzt bewusst dieselbe .ingredient-row-Zeilenvorlage/CSS
   wie #ingredients-list (keine eigene Kopie). */
#equipment-list .ing-textbaustein-label {
    display: none;
}

/* Schritt 4: Status/Rezept-Nr.-Zeile auf der Rezeptkarte in rezepte_liste.php */
.recipe-card-sub {
    font-size: 0.8rem;
    margin: 2px 0 6px;
}

/* Support-Ticket #105: die vormalige Grid-basierte Mobile-Regel hier
   ("Menge"/"Einheit" auf je 50% der Zeilenbreite) ist mit dem Wechsel auf
   Flexbox oben entfallen - .ing-amount/.ing-unit bleiben durch ihre feste
   flex-basis jetzt auf allen Bildschirmgrössen kompakt, kein gesonderter
   Mobile-Sonderfall mehr nötig. */

.form-actions {
    display: flex;
    gap: 10px;
    margin-top: 24px;
    padding-top: 20px;
    border-top: 1px solid var(--color-border);
}

.site-footer {
    text-align: center;
    padding: 24px;
    color: var(--color-text-muted);
    font-size: 0.85rem;
    border-top: 1px solid var(--color-border);
}

@media (max-width: 720px) {
    .recipe-content { grid-template-columns: 1fr; }
    .form-grid { grid-template-columns: 1fr; }
}

/* Schritt 5 (Layout): echtes Hamburger-Menü statt der bisherigen
   Zeilenumbruch-Lösung (header-inner wurde vorher einfach auf
   flex-direction:column umgestellt, wodurch alle Nav-Links + Nutzermenü +
   Logout-Icon dauerhaft untereinander standen - unpraktisch bei 4+
   Hauptlinks). Ab hier wird die Nav standardmässig ausgeblendet und per
   Knopf (aria-expanded, siehe includes/header.php) ein-/ausgeklappt. */
@media (max-width: 720px) {
    .header-inner { flex-wrap: wrap; }
    .nav-toggle { display: inline-flex; align-items: center; justify-content: center; order: 2; }
    .site-header nav {
        display: none;
        order: 3;
        flex-basis: 100%;
        flex-direction: column;
        align-items: stretch;
        gap: 4px;
        padding: 12px 0 16px;
        border-top: 1px solid var(--color-border);
    }
    .site-header nav.nav-open { display: flex; }
    .site-header nav > a:not(.btn) {
        padding: 10px 4px;
        border-bottom: 1px solid var(--color-border);
    }
    .site-header nav > a.active:not(.btn) { border-bottom-color: var(--color-border); }
    .site-header .user-menu { width: 100%; }
    .site-header .user-menu-panel { position: static; box-shadow: none; border: none; padding-left: 12px; }
}

/* ===================================================================
   Ab hier: neue Blöcke für Kochbuch II (Login, Support-Tool) - das
   Original oberhalb bleibt unverändert. Verwendet dieselben CSS-
   Variablen wie oben, daher optisch konsistent.
   =================================================================== */

.btn-block { width: 100%; }
.btn-sm { padding: 6px 12px; font-size: 0.82rem; }

/* Login-Seite */
.login-body {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    margin: 0;
    background: var(--color-bg);
}
.login-box {
    background: var(--color-surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow-hover);
    padding: 36px;
    width: 100%;
    max-width: 380px;
}
.login-box h1 {
    font-family: var(--app-font, Arial, sans-serif);
    font-size: 1.5rem;
    margin-bottom: 4px;
}
.login-form { display: flex; flex-direction: column; gap: 14px; margin-top: 20px; }
.login-form .form-group { display: flex; flex-direction: column; gap: 6px; }
.login-form label { font-weight: 600; font-size: 0.88rem; }
.login-form input {
    padding: 10px 12px;
    border-radius: 8px;
    border: 1px solid var(--color-border);
    font-family: inherit;
    font-size: 0.95rem;
    background: var(--color-bg);
}

/* Support-Widget (Zahnrad-Feedback-Button, siehe includes/support_widget.php) */
#support-fab {
    position: fixed;
    right: 20px;
    bottom: 20px;
    z-index: 1000;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-text-muted);
    font-size: 1.3rem;
    line-height: 1;
    cursor: pointer;
    box-shadow: var(--shadow);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, color 0.15s, transform 0.15s;
}
#support-fab:hover {
    background: var(--color-bg);
    color: var(--color-primary);
    transform: rotate(25deg);
}
@media print {
    #support-fab, .support-modal-overlay { display: none !important; }
    /* Schritt 5 (Layout): Kopfzeile/Navigation/Skip-Link gehören nicht auf
       den Ausdruck (z.B. beim Drucken eines Rezepts). */
    .site-header, .skip-link { display: none !important; }
    /* Auftrag 7 (2026-08-27, Referenz-Angleichung): Bedienelemente, die nur
       auf dem Bildschirm Sinn ergeben (z.B. der "Drucken"-Knopf selbst),
       gleiches Klassen-Muster wie in der Referenz-App. */
    .screen-only { display: none !important; }
    /* Auftrag 22, Kategorie B (2026-08-28): Gegenstück zu .screen-only. */
    .print-only { display: inline !important; }
    /* Auftrag 13 (2026-08-27, Support-Rückmeldung): der Auf-/Zuklapp-
       Zustand von details.recipe-detail-toggle (z.B. Allergene) ist reine
       Bildschirm-Bequemlichkeit - beim Drucken soll der Inhalt immer
       vollständig erscheinen, unabhängig vom aktuellen Klappzustand. */
    .recipe-detail-toggle:not([open]) > *:not(summary) {
        display: block !important;
    }
}
.recipe-detail-toggle > summary {
    cursor: pointer;
}
/* Auftrag 22, Kategorie A (2026-08-27): rezept.php verwendet für seine
   Stammdaten-Panel-Überschriften jetzt h3 statt h2 (Referenz-Angleichung),
   die ursprüngliche h2-Regel bleibt für andere .recipe-detail-toggle-
   Verwendungen bestehen. */
.recipe-detail-toggle > summary > h2,
.recipe-detail-toggle > summary > h3 {
    display: inline-block;
    margin: 0;
}

/* Auftrag 22, Kategorie C (2026-08-28): live-aggregierte Allergene mit
   aufklappbarer Quellenanzeige (rezept.php) - 1:1 aus der Referenz-App. */
.allergen-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.allergen-details {
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 8px 12px;
}
.allergen-details summary {
    cursor: pointer;
    font-weight: 500;
    display: flex;
    align-items: center;
    gap: 8px;
}
.allergen-details p {
    margin: 6px 0 0;
}
.code-badge {
    display: inline-block;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    color: var(--color-text-muted);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    padding: 2px 8px;
    border-radius: 6px;
}

.support-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(58, 47, 40, 0.35);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1001;
    padding: 20px;
}
.support-modal-overlay[hidden] { display: none; }
.support-modal {
    background: var(--color-surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow-hover);
    width: 100%;
    max-width: 420px;
    padding: 20px;
    /* Support-Auftrag #454 (2026-09-15, PO woertlich: "ich muss die Support
       Rueckmeldungen scrollen koennen. sie ist zu lang, so dass ich senden
       nicht mehr sehe."): Das Fenster hatte bisher KEINE Hoehenbegrenzung -
       bei vielen Arten, langem Text oder mehreren Anhaengen wuchs es ueber
       den Bildschirmrand hinaus, der Senden-Knopf am Ende war dann nicht
       mehr erreichbar. Jetzt endet das Fenster am Bildschirmrand, der
       Inhalt scrollt darin, und die Knopfzeile klebt unten fest (siehe
       .support-modal-actions weiter unten) - Senden ist dadurch immer
       sichtbar, ohne scrollen zu muessen. Bewusst nur CSS: HTML und
       JavaScript des Widgets bleiben unangetastet (das Skript blendet
       #support-form-fields beim Dankeschoen aus; ein Umbau der Struktur
       haette das gestoert). */
    max-height: calc(100vh - 40px);
    display: flex;
    flex-direction: column;
}
/* Die Kopfzeile zum Verschieben bleibt stehen, nur der Inhalt scrollt. */
.support-modal > .support-modal-draghandle { flex: 0 0 auto; }
.support-modal > #support-form-fields,
.support-modal > #support-thankyou {
    overflow-y: auto;
    min-height: 0;
}
.support-modal-draghandle {
    text-align: center;
    color: var(--color-text-muted);
    font-size: 0.9rem;
    letter-spacing: 3px;
    line-height: 1;
    margin: -8px -8px 10px;
    padding: 6px 0;
    cursor: move;
    border-radius: 8px;
}
.support-modal-draghandle:hover { background: var(--color-bg); }
.support-modal.is-dragging { box-shadow: var(--shadow-hover), 0 0 0 2px var(--color-primary); }
.support-modal h2 { margin-top: 0; font-size: 1.15rem; }
.support-modal-field {
    margin-bottom: 10px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.support-modal-field label { font-size: 0.85rem; color: var(--color-text-muted); }
.support-modal-field textarea {
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 8px 10px;
    font-family: inherit;
    font-size: 0.95rem;
    resize: vertical;
}
.support-kat-list { display: flex; flex-direction: column; gap: 2px; }
.support-kat-option {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 8px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--color-text);
    cursor: pointer;
    font-family: inherit;
    font-size: 0.95rem;
    line-height: 1;
    text-align: left;
}
.support-kat-option:hover { background: var(--color-bg); }
.support-kat-box {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    border-radius: 4px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    position: relative;
}
.support-kat-option.is-active .support-kat-box {
    background: var(--color-primary);
    border-color: var(--color-primary);
}
.support-kat-option.is-active .support-kat-box::after {
    content: '';
    position: absolute;
    left: 5px;
    top: 1px;
    width: 5px;
    height: 10px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}
.support-kat-option.is-active .support-kat-text { font-weight: 600; }
/* Support-Auftrag #454: Die Knopfzeile klebt am unteren Rand des scrollenden
   Bereichs, damit "Senden" auch bei langem Inhalt immer sichtbar bleibt. Der
   eigene Hintergrund ist noetig, damit darunterliegender Text beim Scrollen
   nicht durchscheint; das negative margin-bottom gleicht das zusaetzliche
   Polster wieder aus, damit der Abstand unten gleich bleibt wie bisher. */
.support-modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 6px;
    position: sticky;
    bottom: 0;
    background: var(--color-surface);
    padding-block: 8px;
    margin-bottom: -8px;
}
.support-modal-msg { font-size: 0.9rem; margin: 0 0 10px; }
.support-modal-msg-ok { color: var(--color-primary); }
.support-modal-msg-error { color: var(--color-danger); }

/* Support-Ticket #227-Anschluss (2026-09-05): aus der EINEN Vorschau wird
   eine Liste (bis zu 5 Kacheln), jede mit eigenem Entfernen-Knopf. */
.support-screenshot-preview-list { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 10px; margin-top: 4px; }
.support-screenshot-preview-list:empty { display: none; }
.support-screenshot-item { position: relative; display: flex; align-items: center; }
.support-screenshot-item img {
    width: 70px;
    height: 70px;
    object-fit: cover;
    border-radius: 6px;
    border: 1px solid var(--color-border);
}
.support-screenshot-item-filename {
    max-width: 90px;
    font-size: 0.72rem;
    padding: 4px 6px;
    border-radius: 6px;
    border: 1px solid var(--color-border);
    background: var(--color-surface, #fff);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.support-screenshot-item-remove {
    position: absolute;
    top: -6px;
    right: -6px;
    width: 20px;
    height: 20px;
    line-height: 18px;
    padding: 0;
    border-radius: 50%;
    border: none;
    background: var(--color-danger);
    color: #fff;
    font-size: 0.75rem;
    cursor: pointer;
}

/* Support-Ticket #227-Anschluss (2026-09-05): Galerie mehrerer Screenshots/
   Dateien in der Support-Übersicht (support_uebersicht.php). */
.support-datei-liste { display: flex; flex-wrap: wrap; gap: 6px; }

/* Support-Ticket #236 (2026-09-06, PO wörtlich: "Wenn du ein Auftrag aus dem
   Support Rückmeldung mit diesen zwei Bildern bekommst, ist es kein 'Wunsch'
   sondern ein Eintrag in die Liste 'Merkmale & Sicherheit' ... reicht auch
   ein Screenshot. dieser muss aber in einem Minifenster geöffnet werden
   können und nicht in einem neuen Tab"): löst den früheren Hover-Ansatz
   (VORFALL 199, Klasse .abostufen-mini-bild*) ab - Minibild als echter
   Button, Klick/Enter öffnet die gemeinsame Lightbox weiter unten statt
   eines neuen Tabs. Wiederverwendbar überall, wo ein Merkmal einen
   Referenz-Screenshot hat (siehe abostufen_verwaltung.php). */
.merkmal-screenshot-mini-btn {
    display: inline-block;
    margin: 2px 4px 2px 0;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: 4px;
    background: #fff;
    cursor: pointer;
    line-height: 0;
}
.merkmal-screenshot-mini-btn img {
    display: block;
    max-height: 30px;
    max-width: 150px;
    width: auto;
    height: auto;
    object-fit: contain;
}
/* Support-Ticket #241 Punkt 2/3 (2026-09-06): echter, klickbarer Platzhalter
   statt "-" bei Merkmalen ohne Screenshot - Klick "armiert" ihn (Klasse
   .armiert) als Ziel für die nächste Zwischenablage-Einfügung (Strg+V),
   siehe Skript in abostufen_verwaltung.php. */
.merkmal-screenshot-platzhalter {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin: 2px 4px 2px 0;
    padding: 4px 8px;
    border: 1px dashed var(--color-border);
    border-radius: 4px;
    background: #fff;
    color: var(--color-text-muted);
    font-size: 0.82rem;
    line-height: 1.2;
    cursor: pointer;
    white-space: nowrap;
}
.merkmal-screenshot-platzhalter:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}
.merkmal-screenshot-platzhalter.armiert {
    border-style: solid;
    border-color: var(--color-primary);
    background: rgba(193, 80, 46, 0.08);
    color: var(--color-primary);
}
.merkmal-screenshot-platzhalter:disabled {
    opacity: 0.65;
    cursor: default;
}
.screenshot-lightbox {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
}
/* Selbst gefundener Bug (2026-09-06, PO-Meldung "etwas ganz komisches"):
   hier fehlte die EXPLIZITE [hidden]{display:none}-Regel, die für dieses
   Muster bereits weiter unten dokumentiert ist (Lehre aus Auftrag 36/145,
   siehe Kommentar bei .bulk-actions-bar/.cart-bar) - da .screenshot-lightbox
   `display:flex` setzt, gewann diese Autoren-Regel gegen die native
   [hidden]-Regel des Browsers, wodurch die Lightbox (leerer Dialog +
   Schliessen-Knopf) auf JEDER Seite mit Merkmale-Screenshots dauerhaft
   sichtbar war, obwohl das hidden-Attribut gesetzt ist. */
.screenshot-lightbox[hidden] { display: none; }
.screenshot-lightbox-backdrop { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.6); }
.screenshot-lightbox-dialog { position: relative; z-index: 1; max-width: 90vw; max-height: 90vh; }
.screenshot-lightbox-dialog img {
    display: block;
    max-width: 90vw;
    max-height: 90vh;
    border-radius: 6px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}
.screenshot-lightbox-close {
    position: absolute;
    top: -14px;
    right: -14px;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: none;
    background: #fff;
    color: #3a2f28;
    font-size: 1.2rem;
    line-height: 1;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

/* Support-Ticket #234/#235 (2026-09-06, "1. Zeile ... ein/ausblendbar" +
   "'Quelle' kann man aus der Liste entfernen"): Spalten Quelle/Bereich
   (manuell)/Transparent in "Merkmale & Sichtbarkeit" per Häkchen
   ein-/ausblendbar (siehe Skript in abostufen_verwaltung.php). */
#merkmale-liste.spalten-quelle-versteckt .col-quelle { display: none; }
#merkmale-liste.spalten-bereich-versteckt .col-bereich { display: none; }
#merkmale-liste.spalten-transparent-versteckt .col-transparent { display: none; }

.support-thankyou-title {
    font-family: var(--app-font, Arial, sans-serif);
    font-size: 1.3rem;
    font-weight: 600;
    color: var(--color-primary-dark);
    margin: 0 0 10px;
}
.support-thankyou-text { font-size: 0.98rem; margin: 0 0 10px; }

/* Positions-Marker im Support-Widget (2026-08-27) */
.support-position-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.support-position-status {
    margin: 4px 0 0;
    font-size: 0.85rem;
    color: var(--color-primary-dark, var(--color-primary));
    font-weight: 600;
}
.support-position-status[hidden] { display: none; }
.support-position-hintbar {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1002;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 10px 16px;
    background: var(--color-primary-dark, #7a2f18);
    color: #fff;
    font-size: 0.95rem;
    box-shadow: var(--shadow-hover);
}
.support-position-hintbar[hidden] { display: none; }
.support-position-hintbar button { cursor: pointer !important; }
body.support-position-crosshair,
body.support-position-crosshair * {
    cursor: crosshair !important;
}
.support-position-marker {
    position: absolute;
    width: 36px;
    height: 36px;
    margin-left: -18px;
    margin-top: -18px;
    z-index: 1000;
    cursor: grab;
    touch-action: none;
}
.support-position-marker.is-dragging { cursor: grabbing; }
.support-position-marker::before,
.support-position-marker::after {
    content: '';
    position: absolute;
    background: var(--color-primary, #a13f22);
}
.support-position-marker::before { left: 50%; top: 0; bottom: 0; width: 2px; margin-left: -1px; }
.support-position-marker::after { top: 50%; left: 0; right: 0; height: 2px; margin-top: -1px; }
.support-position-marker-dot {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 10px;
    height: 10px;
    margin-left: -5px;
    margin-top: -5px;
    border-radius: 50%;
    background: var(--color-primary, #a13f22);
    box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.9), 0 0 0 4px var(--color-primary, #a13f22);
}
.support-position-marker:focus-visible {
    outline: 2px solid var(--color-primary-dark, #7a2f18);
    outline-offset: 4px;
    border-radius: 50%;
}

/* Support-Übersicht (Admin, support_uebersicht.php) */
.support-tabs {
    display: flex;
    gap: 8px;
    margin-bottom: 24px;
    border-bottom: 1px solid var(--color-border);
}
.support-tabs a {
    padding: 10px 16px;
    color: var(--color-text-muted);
    font-weight: 600;
    font-size: 0.9rem;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
}
.support-tabs a:hover { color: var(--color-primary); }
.support-tabs a.active { color: var(--color-primary-dark); border-bottom-color: var(--color-primary); }

.support-list { display: flex; flex-direction: column; gap: 16px; }
.support-item {
    background: var(--color-surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 18px 20px;
}
.support-item-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
}
.support-kategorie-tag {
    background: var(--color-bg);
    color: var(--color-primary-dark);
    font-size: 0.78rem;
    font-weight: 600;
    padding: 3px 10px;
    border-radius: 999px;
}
.support-status { font-size: 0.85rem; font-weight: 600; }
.support-status-offen { color: var(--color-secondary); }
.support-status-erledigt { color: var(--color-primary); }
/* Support-Ticket #79 (2026-08-30): eigener Farbton für "Ideenpool" -
   bewusst ein ruhiges Blau, das sich von Offen (Rot/Grün-Töne unten),
   Gesendet (Gelb/Amber) und Erledigt (Terrakotta) klar unterscheidet. */
.support-status-ideenpool { color: #5b7fa6; }
.support-item-text { margin: 0 0 10px; white-space: pre-line; }
.support-item-screenshot {
    max-width: 220px;
    border-radius: 8px;
    border: 1px solid var(--color-border);
    display: block;
    margin-bottom: 10px;
}
.support-item-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    font-size: 0.82rem;
    color: var(--color-text-muted);
    margin-bottom: 10px;
}
.support-item-meta a { color: var(--color-primary); font-weight: 500; }
.support-item-actions { margin: 0; }

/* ---------------------------------------------------------------------
   Supporttool-Ausbau (Phase B, Schritt 2): grosse Tabellen-Übersicht mit
   Status-Tabs, Art-Filter, Bulk-Aktionen, KI-Briefing und Fragen-Zeilen -
   Vorbild ist das Support-Tool des separaten Küchenplaners, hier in der
   "Mein Kochbuch"-Terrakotta/Grün-Optik.
   --------------------------------------------------------------------- */

.page-head-actions {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.support-filter-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    border-bottom: 1px solid var(--color-border);
    margin-bottom: 14px;
}
.support-filter-tabs a {
    padding: 8px 14px;
    /* Support-Ticket Auftrag 133 (2026-08-30): "Schriftgrösse um 2
       vergrössern" - von 0.88rem (~14px) auf 1rem (~16px). */
    font-size: 1rem;
    font-weight: 600;
    color: var(--color-text-muted);
    border-bottom: 2px solid transparent;
}
.support-filter-tabs a:hover { color: var(--color-primary); }
.support-filter-tabs a.active { color: var(--color-primary-dark); border-bottom-color: var(--color-primary); }

.col-toggle-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 10px 14px;
    margin-bottom: 14px;
    font-size: 0.85rem;
}
.col-toggle-bar span { font-weight: 600; color: var(--color-text-muted); }
.col-toggle-bar label { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }

.support-bulk-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-bottom: 14px;
}
.support-bulk-bar form { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* Support-Ticket Auftrag 134 (2026-08-30): "Schriftgrösse wie 'Gesendete
   an Claude'" - der Knopf "für Claude markieren" (und, zur Konsistenz
   innerhalb derselben Zeile, seine Nachbar-Knöpfe) auf dieselbe Grösse wie
   die Filter-Reiter oben (.support-filter-tabs a, 1rem, siehe Auftrag 133). */
.support-bulk-bar .btn-sm { font-size: 1rem; }
/* 2026-09-15: Auswahlspalte und Übergabe-Knöpfe in der Massenaktionsleiste
   (PO: "ich kann zwei Aufträge anklicken und kann es nicht weiterleiten"). */
.support-bulk-trenner { color: var(--color-text-muted); opacity: 0.5; }
.support-auswahl-zelle { width: 32px; text-align: center; vertical-align: middle; }
.support-auswahl-zelle input[type="checkbox"] { width: 17px; height: 17px; cursor: pointer; accent-color: #8a2f1c; }
.support-danger-btn { color: var(--color-danger); }
.support-danger-btn:hover { background: var(--color-danger); color: #fff; }

/* Generische Tabellen-Optik, ab jetzt für alle Datenlisten (Support,
   künftig Waren/Rezepte/Menüs) nutzbar. */
.data-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
    font-size: 0.9rem;
}
.data-table th, .data-table td {
    padding: 10px 12px;
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--color-border);
}
.data-table th {
    background: var(--color-bg);
    font-weight: 600;
    font-size: 0.82rem;
    color: var(--color-text-muted);
    white-space: nowrap;
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover { background: rgba(193, 80, 46, 0.04); }

/* Support-Ticket Auftrag 116 (2026-08-29): jede 2. Zeile der Zutaten-
   Tabelle auf der Rezept-Detailseite (rezept.php) hellgrau hinterlegt -
   gleicher Grauton wie die bereits bestehende alternierende Zeilenfärbung
   im Sammeldruck (siehe .print-section-zutaten weiter unten). */
.zutaten-tabelle tbody tr:nth-child(even) {
    background: #ececec;
}

/* Support-Ticket #166 (2026-08-30): Zeilenabstand der Zutaten-Tabelle auf der
   Bildschirm-Ansicht der Rezept-Detailseite (rezept.php) verringert - reine
   Bildschirm-Optik, die Druck-Ansicht hat bereits eigene, kompaktere Werte
   (siehe .print-section-zutaten weiter unten) und bleibt unverändert. Gleiche
   Selektor-Spezifität wie .data-table th/td, gewinnt durch spätere
   Reihenfolge im Stylesheet - andere .data-table-Nutzungen (Support,
   Waren/Rezepte/Menü-Listen) sind davon nicht betroffen. */
.zutaten-tabelle th, .zutaten-tabelle td {
    padding: 5px 12px;
    line-height: 1.2;
}

.data-table th.sortable { cursor: pointer; user-select: none; }
.data-table th.sortable:hover { color: var(--color-primary); }
.sort-ind { font-size: 0.7em; }

/* Support-Ticket #174 (2026-08-30, Einkaufsliste "schöner formatiert,
   Zeilenabstand minimieren, jede zweite Zeile heller Hintergrund
   ein/ausblendbar"): kompaktere Zeilenhöhe als das normale .data-table
   (gleiches Prinzip wie .zutaten-tabelle), plus eine per Häkchen
   umschaltbare Zebra-Streifung (Klasse "zebra" wird per JS auf die
   Tabelle gesetzt/entfernt, siehe rezepte_/artikel_/menue_einkaufsliste.php). */
.einkaufsliste-table th, .einkaufsliste-table td {
    padding: 6px 12px;
    line-height: 1.3;
}
.einkaufsliste-table.zebra tbody tr:nth-child(even) {
    background: #ececec;
}

.support-table textarea {
    width: 100%;
    min-height: 54px;
    box-sizing: border-box;
    font-family: inherit;
    font-size: 0.88em;
    padding: 6px 8px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    resize: vertical;
    margin-bottom: 6px;
}
.support-edit-form { display: flex; flex-direction: column; align-items: flex-start; gap: 0; min-width: 220px; }
.support-status-select {
    font-family: inherit;
    font-size: 0.85rem;
    padding: 4px 8px;
    border-radius: 8px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
}
.support-status-gesendet { color: #a67c1e; }
.support-claude-check { display: inline-flex; align-items: center; gap: 5px; font-size: 0.82rem; cursor: pointer; }
.support-claude-kommentar { color: var(--color-text); }

.list-thumb {
    width: 46px;
    height: 46px;
    object-fit: cover;
    border-radius: 6px;
    border: 1px solid var(--color-border);
}

.support-dot {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    margin-right: 6px;
    vertical-align: 1px;
}
.support-dot-offen { background: var(--color-danger); }
.support-dot-gesendet { background: #d9a520; }
.support-dot-erledigt { background: var(--color-secondary); }
.support-dot-ideenpool { background: #5b7fa6; }

.url-warnung {
    margin-top: 4px;
    font-size: 0.76rem;
    color: var(--color-danger);
    max-width: 220px;
}

.support-frage-row td { background: #fbeeee; }
.support-frage-offen { padding: 10px 12px !important; }
.support-frage-item {
    padding: 8px 10px;
    border-radius: 8px;
    background: #fff;
    border: 1px solid #f0c9c9;
    margin-bottom: 8px;
}
.support-frage-item:last-child { margin-bottom: 0; }
.support-frage-item.support-frage-beantwortet {
    background: var(--color-bg);
    border-color: var(--color-border);
    opacity: 0.85;
}
.support-frage-text {
    color: var(--color-danger);
    font-weight: 600;
    font-size: 0.9rem;
    margin-bottom: 6px;
}
.support-frage-item.support-frage-beantwortet .support-frage-text { color: var(--color-text); font-weight: 500; }
.support-antwort-form { display: flex; flex-direction: column; gap: 4px; max-width: 480px; }
.support-antwort-label {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--color-text-muted);
}
.support-antwort-label textarea { font-weight: 400; color: var(--color-text); }
.support-antwort-buttons { display: flex; gap: 8px; }
.support-frage-delete-form { margin-top: 4px; }

/* ---------------------------------------------------------------------
   Waren-Verwaltung (Phase B, Schritt 3): Artikelliste (Spalten-Toggle,
   sortierbare .data-table, Bild-Miniaturen) + Artikel-Formular (Bild-
   Upload, Allergene-Chips, Nährwerte-Raster, weitere Einheiten).
   --------------------------------------------------------------------- */

.clickable-row { cursor: pointer; }
.clickable-row:hover { background: rgba(193, 80, 46, 0.04); }

.list-thumb-placeholder {
    display: inline-block;
    width: 46px;
    height: 46px;
    border-radius: 6px;
    border: 1px dashed var(--color-border);
    color: var(--color-text-muted);
    font-size: 0.62rem;
    line-height: 46px;
    text-align: center;
}

.lock-badge {
    display: inline-block;
    font-size: 0.78rem;
    color: var(--color-secondary);
    white-space: nowrap;
}

/* Allergene-Spalte der Rezepte-Liste (2026-08-27, Referenz-Angleichung) -
   kompakte Code-Badges (z.B. "GLU"), eine pro zugeordnetem Allergen. */
.allergen-tag {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    padding: 2px 7px;
    border-radius: 999px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    color: var(--color-text-muted);
    margin: 1px 2px 1px 0;
}

.delete-form { margin-top: 24px; }

/* Waren-Formular ist deutlich breiter als das Rezept-Formular (Nährwerte-
   Raster braucht Platz) - eigene Modifier-Klasse statt .recipe-form direkt
   zu verändern (würde das schmalere Rezept-Formular ebenfalls betreffen). */
.recipe-form.article-form { max-width: 980px; }

.article-image-field { display: flex; align-items: center; gap: 14px; }
/* Support-Ticket #335 (2026-09-11, PO woertlich: "Wenn das Bild nicht ins
   Vorschaufenster passt, muss es verkleinert werden"): die Vorschau stand auf
   object-fit: cover - das FUELLT den Kasten und schneidet dafuer ab, was nicht
   hineinpasst. Bei einem breiten oder hohen Bild war deshalb nur ein
   Ausschnitt zu sehen. Mit contain wird das Bild stattdessen so weit
   verkleinert, dass es vollstaendig hineinpasst; der freibleibende Rand
   bekommt den Seitenhintergrund, damit der Rand gewollt aussieht statt nach
   Fehler. */
.article-image-preview {
    width: 90px;
    height: 90px;
    object-fit: contain;
    background: var(--color-bg);
    border-radius: 10px;
    border: 1px solid var(--color-border);
    cursor: pointer;
    flex-shrink: 0;
}
.article-image-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-text-muted);
    font-size: 0.78rem;
    background: var(--color-bg);
    text-align: center;
}
.file-input-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
}

.allergen-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 8px;
}
.lock-toggle { display: inline-flex; align-items: center; gap: 6px; font-size: 0.85rem; font-weight: 500; cursor: pointer; }

.checkbox-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.checkbox-grid.is-locked { opacity: 0.55; }
.checkbox-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border-radius: 999px;
    border: 1px solid var(--color-border);
    background: var(--color-bg);
    font-size: 0.85rem;
    cursor: pointer;
}

.nutrient-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 14px;
}
.nutrient-field { display: flex; flex-direction: column; gap: 4px; }
.nutrient-field label { font-size: 0.82rem; font-weight: 600; color: var(--color-text-muted); }
.nutrient-input { display: flex; align-items: center; gap: 6px; }
.nutrient-input input {
    width: 100%;
    padding: 8px 10px;
    border-radius: 8px;
    border: 1px solid var(--color-border);
    font-family: inherit;
    background: var(--color-bg);
}
.nutrient-unit { font-size: 0.8rem; color: var(--color-text-muted); white-space: nowrap; }
.nutrient-nrv { font-size: 0.74rem; color: var(--color-text-muted); }
.nrv-footnote { margin-top: 8px; font-size: 0.76rem; }

.pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin: 14px 0;
}
.pager-size-form { margin: 0; }
.pager-size-label { font-size: 0.85rem; color: var(--color-text-muted); display: inline-flex; align-items: center; gap: 6px; }
.pager-size-label select {
    padding: 6px 8px;
    border-radius: 8px;
    border: 1px solid var(--color-border);
    font-family: inherit;
    background: var(--color-surface);
}
.pager-buttons { display: flex; flex-wrap: wrap; gap: 4px; }
.pageinfo { font-size: 0.82rem; color: var(--color-text-muted); margin-left: auto; }

/* Schritt 7 (Menüplaner): Kalender-Tabelle + Zell-Icons, portiert aus der
   Referenz-App (dortige Klassennamen unverändert übernommen). */
.row-action-icons {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
}
.icon-action-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 6px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    cursor: pointer;
    text-decoration: none;
    font-size: 0.95rem;
    color: var(--color-text);
}
.icon-action-btn:hover {
    background: rgba(193, 80, 46, 0.08);
}
.icon-action-btn:disabled {
    cursor: not-allowed;
}
.icon-action-btn:disabled:hover {
    background: var(--color-surface);
}
/* Support-Ticket #220 (2026-09-04): "Transparent-Modus" - Bausteine, die für
   die aktuelle Abostufe nicht sichtbar sind, aber admin-seitig als
   "transparent" markiert wurden (abo_merkmale.transparent_modus), werden für
   ECHTE Nutzer (nicht nur im Admin-Vorschau-Modus) trotzdem gerendert, aber
   sichtbar deaktiviert dargestellt - gleiche Opazität wie .abo-feature-hidden
   in der Admin-Vorschau (includes/header.php), damit der "durchsichtige"
   Look konsistent bleibt. Das eigentliche Deaktivieren übernimmt bei
   Buttons/Formularen das native disabled-Attribut (a11y: Tastatur/
   Screenreader erkennen den Zustand korrekt) - diese Klasse ist nur für die
   optische Wirkung zuständig. */
.abo-feature-locked {
    display: inline-flex;
    opacity: 0.35;
    cursor: not-allowed;
}

/* Support-Auftraege #421-#444 und #435 (2026-09-14/15, PO: "richte alle
   einheitlich aus" / "Einheitliches Layout nicht 1000 mal in den Code
   schreiben").

   abo_feature() legt um das gesteuerte Element ein <span class="abo-feature">
   mit display:inline-flex (includes/header.php). Fuer kurze Inline-Elemente
   (Knoepfe, Filter-Beschriftungen) passt das. Umschliesst derselbe Wrapper
   aber ein ganzes Formularfeld oder einen aufklappbaren Abschnitt, entstehen
   zwei Fehler: im .form-grid wird der Wrapper zum Grid-Element, das Feld
   verliert seine Spaltenbreite und "wide"-Felder rutschen in eine halbe
   Spalte; ausserdem zentriert align-items:center das Feld vertikal, wodurch
   das Vorschau-Haekchen auf halber Feldhoehe statt beim Label sitzt.

   Statt an jeder einzelnen Stelle Extra-Auszeichnung zu schreiben, richten
   das diese drei Regeln ueber den Kontext - sie gelten damit automatisch
   auch fuer jedes kuenftig umschlossene Feld. Sichtbar wird der Wrapper
   ohnehin fast nur in der Abo-Vorschau: fuer Admins und fuer Nutzer, die das
   Merkmal sehen duerfen, rendert abo_feature() den Inhalt ohne span. */
.abo-feature:has(> .form-group),
.abo-feature:has(> details),
.abo-feature:has(> .stammdaten-panel) {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    width: 100%;
    min-width: 0;
}
.abo-feature:has(> .form-group) > .form-group,
.abo-feature:has(> details) > details,
.abo-feature:has(> .stammdaten-panel) > .stammdaten-panel {
    flex: 1 1 auto;
    min-width: 0;
}
/* Ein umschlossenes Feld, das ueber beide Spalten geht (.form-group-wide),
   muss das als Wrapper ebenfalls tun - sonst steht es ploetzlich halb so
   breit neben dem Nachbarfeld. */
.form-grid > .abo-feature:has(> .form-group-wide) {
    grid-column: 1 / -1;
}

.menueplan-table td { vertical-align: top; }
.menueplan-tag-zelle { white-space: nowrap; }
.menueplan-zelle { min-width: 220px; }
.menueplan-eintrag {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: nowrap;
}
.menueplan-eintrag .list-thumb-placeholder {
    font-size: 1rem;
}
.menueplan-heute { background: #f0f7f2; }
.badge-heute {
    display: inline-block;
    background: var(--color-primary);
    color: #fff;
    font-size: 0.7rem;
    padding: 1px 6px;
    border-radius: 4px;
    margin-left: 6px;
}
@media (max-width: 720px) {
    .menueplan-table { display: block; overflow-x: auto; }
}

/* Support-Ticket Auftrag 53 (2026-08-28): Tab-Leiste für stammdaten.php,
   1:1 aus der Referenz-App übernommen (dort assets/style.css) - kp2 nutzt
   dieselben CSS-Variablen (--color-border/--color-text-muted/
   --color-primary/--color-primary-dark), daher fast unverändert portierbar.
   Bewusste, dokumentierte Abweichung: "flex-wrap: wrap" ergänzt (Referenz
   hat das nicht), weil kp2's Tab-Leiste mit neun Einträgen (inkl. Umrechnung/
   Texte/Konfiguration) auf Mobile-Breiten sonst abgeschnitten würde -
   Pflicht laut Projektstandard "Responsive Design (Mobile-First)". */
.tab-bar {
    display: flex;
    gap: 4px;
    border-bottom: 1px solid var(--color-border);
    margin-bottom: 24px;
    flex-wrap: wrap;
}
.tab {
    padding: 10px 16px;
    font-weight: 600;
    font-size: 0.92rem;
    color: var(--color-text-muted);
    border-bottom: 2px solid transparent;
}
.tab:hover { color: var(--color-primary); }
.tab.active { color: var(--color-primary-dark); border-bottom-color: var(--color-primary); }

/* Schritt 8 (Stammdaten): ein Karten-Panel je Stammdaten-Tabelle
   (Kategorien/Lieferanten/Allergene/Nährstoffe/Einheiten) + Inline-
   Bearbeitungsfelder in den Tabellenzeilen + das "Neu hinzufügen"-
   Formular am Ende jedes Panels. */
.stammdaten-panel {
    background: var(--color-surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 24px;
    margin-bottom: 24px;
}
.stammdaten-panel h3 { margin-top: 0; }
.stammdaten-panel .data-table { margin-bottom: 16px; }

/* Support-Ticket #213 (2026-09-03, "Layout anpassen", Preisquellen-Tabelle
   auf stammdaten.php): bei vielen Spalten scrollt die Tabelle horizontal
   (siehe .data-table @media 720px weiter unten) - ohne Fixierung verschwindet
   dabei aber die Spalte "Name" und man verliert die Zuordnung, welche Zeile
   man gerade bearbeitet. "Name" bekommt daher position:sticky (bleibt links
   stehen), die übrigen Text-Spalten sind stattdessen schmaler und nutzen
   <textarea> statt <input> (siehe stammdaten.php), damit lange Werte
   umbrechen statt die Spalte extra breit zu machen.
   PO-Rückmeldung (2026-09-04, Screenshot): "Name" blieb trotzdem nicht fixiert.
   Ursache gefunden: .data-table setzt global border-collapse:collapse (siehe
   oben) - in dieser Kombination ignorieren Browser position:sticky auf
   th/td zuverlässig (bekannte, dokumentierte CSS-Einschränkung, kein
   Sync-/Auslieferungsproblem - der Datei-Abgleich vom selben Tag bestätigt,
   dass Code und CSS bereits korrekt und identisch auf dem Server lagen).
   Fix: für diese Tabelle gezielt auf border-collapse:separate umstellen:
   border-spacing:0 verhindert dabei sichtbare Lücken zwischen den Zellen,
   da nur border-bottom (kein border-top) gesetzt ist (siehe .data-table
   th/td weiter oben) - keine doppelten Linien zwischen den Zeilen. */
.preisquellen-table {
    border-collapse: separate;
    border-spacing: 0;
    /* PO-Rückmeldung (2026-09-04): Umbruch der Kopfzeile wirkt bereits, die
       Fixierung der Name-Spalte trotz border-collapse:separate (siehe oben)
       aber immer noch nicht. Zweite Ursache: .data-table setzt zusätzlich
       overflow:hidden auf das <table>-Element selbst (siehe .data-table
       oben, wegen der abgerundeten Ecken) - jeder Vorfahre mit
       overflow ungleich "visible" zwischen der sticky-Zelle und dem
       tatsächlich scrollenden Element (dem umgebenden div mit
       overflow-x:auto, siehe stammdaten.php) bricht die Berechnung der
       sticky-Position. Für diese Tabelle daher overflow auf visible
       zurückgesetzt - die abgerundeten Ecken gehen für diese eine,
       ohnehin horizontal scrollende Tabelle verloren, das ist hier der
       richtige Kompromiss (Funktion vor Optik an dieser Stelle). */
    overflow: visible;
}
/* PO-Auftrag (2026-09-04): auch die Spaltenüberschriften ("CSS-Selektor
   (Aktionspreis)" etc.) sollen umbrechen statt die Spalte per
   .data-table th { white-space:nowrap } (siehe oben) breit zu ziehen -
   erst so wird die angestrebte "Minimum-Ansicht" (möglichst viele Spalten
   gleichzeitig sichtbar) tatsächlich erreicht. max-width hält die
   Kopfzelle in der Breite der schmalen <textarea>-Datenspalten (90px). */
.preisquellen-table th {
    white-space: normal;
    max-width: 110px;
}
.preisquellen-table th.sticky-col,
.preisquellen-table td.sticky-col {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--color-surface);
    box-shadow: 2px 0 4px -2px rgba(0, 0, 0, 0.12);
}
.preisquellen-table th.sticky-col { background: var(--color-bg); z-index: 2; }
.preisquellen-table textarea {
    width: 90px;
    min-height: 38px;
    padding: 6px 8px;
    border-radius: 6px;
    border: 1px solid var(--color-border);
    font-family: inherit;
    font-size: 0.85rem;
    resize: vertical;
    word-break: break-word;
}
.stammdaten-inline-input {
    width: 100%;
    padding: 6px 8px;
    border-radius: 6px;
    border: 1px solid var(--color-border);
    font-family: inherit;
    font-size: 0.9rem;
    background: var(--color-surface);
}
.stammdaten-add-form {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}
.stammdaten-add-form input[type="text"],
.stammdaten-add-form input[type="number"] {
    padding: 8px 10px;
    border-radius: 6px;
    border: 1px solid var(--color-border);
    font-family: inherit;
    background: var(--color-surface);
    flex: 1 1 160px;
}
.stammdaten-add-form-wide input[type="text"],
.stammdaten-add-form-wide input[type="number"] {
    flex: 1 1 140px;
}
/* Auftrag 54/57 (2026-08-29): Zeilen-Inline-Formulare (Kategorien-MwSt.,
   Umrechnungstabelle) - mehrere Eingabefelder + Speichern-Button in einer
   Zeile, ohne dabei die ganze Tabellenzeile zu einem <form> zu machen
   (siehe HTML-Regel-Lehre aus Schritt 8: <form> ist nur als Kind von <td>
   zulässig, nicht direkt von <tr>). */
.stammdaten-inline-form {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}
.stammdaten-inline-form select,
.stammdaten-inline-form input[type="text"],
.stammdaten-inline-form input[type="number"] {
    padding: 6px 8px;
    border-radius: 6px;
    border: 1px solid var(--color-border);
    font-family: inherit;
    font-size: 0.9rem;
    background: var(--color-surface);
}

/* ------------------------------------------------------------------
   Massenaktionen / Warenkorb (2026-08-27, Referenz-Angleichung):
   Checkbox-Spalte, obere Massenaktionen-Leiste (nur Waren: Kategorie/
   Lieferant ändern, Duplizieren) und untere "Warenkorb"-Leiste (Waren/
   Rezepte/Menüs: Drucken/Schlüsselworte zufügen/E-Mail-Versand/
   Cross-Link), 1:1 wie in der Referenz-App "Küchenplaner". Beide Leisten
   werden per [hidden]-Attribut ein-/ausgeblendet - da beide zusätzlich
   `display:flex` setzen, braucht es (Lehre aus der Referenz-App, Auftrag
   36/145) eine EXPLIZITE `[hidden]{display:none}`-Regel, sonst gewinnt
   die spätere Autoren-Regel gegen die native [hidden]-Regel des Browsers
   und die Leiste bliebe trotz gesetztem hidden-Attribut sichtbar.
   ------------------------------------------------------------------ */
.select-col { width: 40px; text-align: center; }
.select-col input[type="checkbox"] { width: 18px; height: 18px; cursor: pointer; }

.bulk-actions-bar {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 12px 16px;
    margin-bottom: 16px;
    box-shadow: var(--shadow);
}
.bulk-actions-bar[hidden] { display: none; }
/* Auftrag 40 (2026-08-28): Leiste ist jetzt ein <details>/<summary> statt
   eines schlichten <div> - gleiches Auf-/Einklapp-Muster (Pfeil-Indikator
   inkl. Dreh-Animation) wie bereits bei .stammdaten-submenu verwendet, aus
   Konsistenzgründen 1:1 übernommen statt eigens neu erfunden. */
.bulk-actions-bar summary {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    list-style: none;
    cursor: pointer;
}
.bulk-actions-bar summary::marker { display: none; content: ''; }
.bulk-actions-bar summary::-webkit-details-marker { display: none; }
.bulk-actions-bar summary::after {
    content: '▸';
    font-size: 0.75rem;
    color: var(--color-text-muted);
    transition: transform 0.15s ease;
    margin-left: auto;
}
.bulk-actions-bar[open] summary::after { transform: rotate(90deg); }
.bulk-actions-bar strong { color: var(--color-primary-dark); }
#bulk-count { color: var(--color-text-muted); font-size: 0.9rem; }
.bulk-actions-bar-body {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--color-border);
}

.cart-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    /* Ticket #110 (2026-08-29, Nutzerwunsch "Warenkorb muss rötlich
       eingefärbt sein"): gilt für alle vier Seiten, die diese Leiste über
       die gemeinsame Klasse .cart-bar einbinden (artikel_/rezepte_/
       menue_liste.php sowie menueplan.php) - eine Änderung hier reicht
       daher für alle vier aus. Farbton an das bestehende
       .draft-warning-badge angelehnt (gleiche rötliche Systemfarbe wie
       andere Warn-/Hinweis-Elemente dieser App). */
    background: #fef2f2;
    border: 1px solid #fca5a5;
    border-radius: var(--radius);
    padding: 12px 16px;
    margin: 20px 0;
    box-shadow: var(--shadow-hover);
    position: sticky;
    bottom: 12px;
    z-index: 20;
    /* 2026-08-27, Ticket 6 (Support-Rückmeldung): "Warenkorb muss von unten
       nach oben eingeschoben werden, sobald ein Artikel markiert wird" -
       1:1 wie die Referenz-App (dort Aufträge 163/166/167). Ausgangszustand
       ist nach unten aus dem sichtbaren Bereich verschoben/unsichtbar; die
       zugehörigen Listenseiten setzen kurz vor dem Einblenden
       "hidden = false" und ergänzen danach (nach einem erzwungenen Reflow)
       die Klasse "cart-bar-visible" - das ergibt den Schiebe-Effekt statt
       eines abrupten Erscheinens. Siehe setCartBarVisible() in den
       jeweiligen Scripts (artikel_/rezepte_/menue_liste.php/menueplan.php). */
    transform: translateY(120%);
    opacity: 0;
    transition: transform 0.25s ease, opacity 0.2s ease;
}
.cart-bar.cart-bar-visible {
    transform: translateY(0);
    opacity: 1;
}
.cart-bar[hidden] { display: none; }
.cart-bar strong { color: var(--color-danger); }
/* Support-Tickets #169/#170/#171 (2026-08-30): Warenkorb-Aktionen sind jetzt
   Icon-only-Buttons (Text weiterhin als title/aria-label vorhanden, siehe
   rezepte_/artikel_/menue_liste.php) - .nav-icon bringt sonst einen für
   Icon+Text-Links gedachten rechten Aussenabstand mit, der hier ohne
   folgenden Text nur unnötig Platz verschwenden würde. Feste quadratische
   Mindestbreite sorgt zusätzlich für eine ausreichend grosse, konsistente
   Klickfläche (a11y/Bedienbarkeit auch auf Touch-Geräten). */
.cart-bar .btn .nav-icon { margin-right: 0; }
.cart-bar .btn { min-width: 34px; display: inline-flex; align-items: center; justify-content: center; }

/* "Zuordnen"-Leiste im Menüplan (Cross-Link aus dem Menüs-Warenkorb) */
.zuordnen-bar {
    background: var(--color-surface);
    border: 1px solid var(--color-primary);
    border-radius: var(--radius);
    padding: 12px 16px;
    margin-bottom: 16px;
    box-shadow: var(--shadow);
}
.zuordnen-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 8px;
}
.zuordnen-chip {
    padding: 6px 14px;
    border-radius: 999px;
    border: 1px solid var(--color-border);
    background: var(--color-bg);
    font-size: 0.88rem;
    font-family: inherit;
    cursor: pointer;
}
.zuordnen-chip.is-armiert {
    background: var(--color-primary);
    border-color: var(--color-primary-dark);
    color: #fff;
    font-weight: 600;
}

/* Druckansichten (artikel_/rezepte_/menue_drucken.php) */
.print-actions {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
}

/* Auftrag 22, Kategorie A (2026-08-27): Einheiten-Umschaltung
   (Original/Gramm/Kilogramm) in der Zutaten-Tabelle von rezept.php -
   gleiches Prinzip wie die bereits bestehenden Spalten-Toggle-Leisten
   (.col-toggle-bar), hier als Button-Gruppe mit aktivem Zustand statt
   Checkboxen. */
.unit-toggle {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
}
.unit-toggle .btn.active {
    background: var(--color-primary);
    color: #fff;
}

/* Auftrag 22, Kategorie B (2026-08-28): Sterne-Bewertung + Unterschriften-
   Qualitätskontrolle in rezept.php/rezepte_liste.php, 1:1 aus der
   Referenz-App übernommen (gleiche Klassennamen/Werte). */
.star-rating { font-size: 1.1rem; margin-left: 8px; vertical-align: middle; }
.star-filled { color: #d4a017; }
.star-empty { color: #d8dad5; }

.signature-grid { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.signature-slot {
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 8px 12px;
}
.signature-slot.is-signed { border-color: #cfe3d8; background: #f5faf7; }
/* Support-Ticket #326 (2026-09-10, "mache die Schriftart fuer folgende Texte
   kleiner"): Erklaersatz zur Qualitaetskontrolle und die drei
   Unterschriftszeilen jetzt auf 0.85rem - dieselbe Groesse wie die uebrigen
   Hilfstexte. Beim DRUCK bleibt die volle Groesse, dort werden die
   Unterschriftslinien wirklich gebraucht. */
.signature-slot summary { cursor: pointer; font-weight: 500; font-size: 0.85rem; }
.qualitaetskontrolle-hinweis { font-size: 0.85rem; }
@media print {
    .signature-slot summary { font-size: 1rem; }
}
.signature-form { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 8px; }
.signature-form input[type="text"] {
    padding: 6px 8px;
    border: 1px solid var(--color-border);
    border-radius: 6px;
}
.signature-form input[name="name"] { width: 160px; }
/* Review-Fix (2026-08-28, vor Auslieferung gefunden): das Namensfeld im
   Unterschriften-Formular hatte nur ein Platzhalter-Attribut, kein <label>
   (a11y-Standard dieses Projekts) - neue, wiederverwendbare
   visuell-versteckte Label-Klasse, für Screenreader weiterhin lesbar. Das
   ursprüngliche Datumsfeld wurde seit Auftrag 27 ganz aus dem Formular
   entfernt (Datum ist seither immer automatisch das Server-Datum, siehe
   rezept_unterschrift_speichern.php) - die zugehörige CSS-Regel
   entsprechend mitentfernt. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
/* Gegenstück zu .screen-only (siehe @media print unten): standardmässig
   ausgeblendet, erscheint nur beim Drucken (z.B. die Punktlinie bei einer
   noch offenen Unterschriften-Position). */
.print-only { display: none; }

/* Auftrag 22, Kategorie B, zweiter Teil (2026-08-28): .print-hide - im
   Unterschied zu .screen-only (das Element ist NIE beim Drucken sichtbar)
   wird .print-hide erst zur Laufzeit per JS gesetzt/entfernt (z.B. die
   Verkaufspreis-"Beim Drucken zeigen"-Radioauswahl in rezept.php blendet
   damit genau eine der beiden Zeilen aus) - auf dem Bildschirm bleibt das
   Element trotz der Klasse immer sichtbar. */
@media print {
    .print-hide { display: none !important; }
}

/* Support-Ticket Auftrag 26, Stufe 4 (2026-08-28): Ampel-Punkte für die
   Glyx-Anzeige (glykämische Last) auf der Rezept- und Menü-Detailseite -
   grün/gelb/rot nach den in stammdaten_konfiguration.php einstellbaren
   Schwellenwerten (siehe glyx_ampel_for_gl() in includes/functions.php).
   "Gelb" nutzt bewusst einen eigenen Farbton statt einer bestehenden
   --color-* Variable, da es dafür bisher keine gibt. */
.glyx-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin-right: 4px;
    vertical-align: middle;
}
.glyx-dot-gruen { background: var(--color-secondary); }
.glyx-dot-gelb { background: #c99a2e; }
.glyx-dot-rot { background: var(--color-danger); }

/* Support-Tickets #66/#67/#68 (2026-08-29): Rezepte-/Menü-Sammeldruck
   1:1 nach Vorbild kuechenplaner/assets/style.css (dortige Regeln für
   rezepte_drucken.php/menue_drucken.php) portiert. */
.print-options {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 12px 16px;
    margin-bottom: 16px;
}
.print-options label { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
@media print {
    .print-options { display: none !important; }
}

.print-recipe, .print-menu { margin-bottom: 20px; }
.print-recipe h3, .print-menu h3 { margin-top: 16px; margin-bottom: 6px; }
@media print {
    .print-recipe, .print-menu { page-break-after: always; break-after: page; }
    .print-recipe:last-child, .print-menu:last-child { page-break-after: auto; break-after: auto; }
    /* Rahmen/Hintergrund von .stammdaten-panel sollen beim gedruckten
       Rezept/Menü wegfallen - nur für die Druck-Variante, damit normale
       Stammdaten-Panels (Waren, Quellen usw.) unverändert bleiben. */
    .stammdaten-panel.print-recipe, .stammdaten-panel.print-menu {
        background: none;
        box-shadow: none;
        border-radius: 0;
        padding: 0 0 20px;
    }
}

/* Zutaten-Tabelle im Sammeldruck: engerer Zeilenabstand + alternierende
   Zeilenfärbung, per Häkchen "Alternierende Zeilenfarben" abschaltbar
   (body.zebra-off, Standard: an). */
.print-section-zutaten .data-table td,
.print-section-zutaten .data-table th {
    padding: 3px 14px;
    line-height: 1.15;
}
.print-section-zutaten .data-table tbody tr:nth-child(even) {
    background: #ececec;
}
body.zebra-off .print-section-zutaten .data-table tbody tr:nth-child(even) {
    background: none;
}
@media print {
    .print-section-zutaten .data-table tbody tr:nth-child(even) {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }
}

.print-recipe .print-section-qk { font-size: 9pt; }

.print-menu .data-table td,
.print-menu .data-table th {
    line-height: 1;
}

/* Zeilenabstand des Zubereitungstexts auf den Druckseiten
   (rezepte_drucken.php UND menue_drucken.php - beide nutzen dieselbe
   Klasse, eine Aenderung hier wirkt auf beiden).
   Auftrag 119 (2026-08-29): vom globalen body-Wert 1.6 auf 1 verringert,
   weil 1.6 auf der engen Druckansicht zu grosszuegig wirkte.
   Support-Ticket #331 (2026-09-11, PO woertlich: "Der Zeilenabstand bei
   Zubereitung ist zu eng. mache ihn wenig weiter."): 1 war der
   Gegenausschlag - jetzt 1.25, also spuerbar luftiger als 1 und immer
   noch deutlich enger als der globale Wert 1.6. */
.print-section-zubereitung .instructions-text {
    line-height: 1.25;
}

/* ===================================================================
   Design-Review (2026-08-31, separate Design-Review-Sitzung, per Zip
   übergeben): sichtbare Labels über den Suchfeldern (a11y - Placeholder
   allein verschwindet beim Fokussieren und wird von Screenreadern nicht
   zuverlässig als Feldname vorgelesen), Kennzeichnung technischer/
   Sammel-Positionen aus dem Fremdsystem-Import in der Waren-Liste, sowie
   horizontales Scrollen der Übersichtstabellen auf schmalen Bildschirmen
   statt Quetschen/Umbruch (gleiche Technik wie bereits .menueplan-table
   oben). Verwendet ausschliesslich bereits vorhandene CSS-Variablen.
=================================================================== */

/* 1) Sichtbare, platzsparende Labels ueber Filterfeldern
   (rezepte_liste.php, artikel_liste.php, menue_liste.php) - ersetzt
   reinen Placeholder-Text, der beim Fokussieren verschwindet und von
   Screenreadern nicht zuverlaessig als Feldname vorgelesen wird.
   Eigene Ergänzung ggü. der Design-Review-Vorlage: .filter-bar ist
   display:flex mit .search-input als direktem Kind (flex:1;
   min-width:220px, siehe weiter oben in dieser Datei), damit das
   Suchfeld die restliche Zeilenbreite ausfüllt. Da .search-input durch
   das neue Wrapper-Div jetzt nicht mehr direktes Flex-Kind ist, muss
   .filter-field dieselben Flex-Eigenschaften übernehmen - sonst würde
   das Suchfeld schmal auf seine Inhaltsbreite zurückfallen. */
.filter-field {
    display: flex;
    flex-direction: column;
    gap: 3px;
    flex: 1;
    min-width: 220px;
}
.filter-label {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--color-text-muted);
}

/* 2) Technische/Sammel-Positionen aus dem Fremdsystem-Import (Namen
   beginnen mit "@" oder "*", z.B. "*gesamtmenge (blattsalat)") optisch
   von echten Waren abheben (artikel_liste.php). */
.artikel-technisch {
    color: var(--color-text-muted);
    font-style: italic;
}
.badge-technisch {
    display: inline-block;
    font-size: 0.68rem;
    font-weight: 600;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    color: var(--color-text-muted);
    border-radius: 999px;
    padding: 1px 8px;
    margin-left: 6px;
}

/* 3) .data-table (Waren-/Rezepte-/Menues-Uebersichten) bekommt auf
   schmalen Bildschirmen horizontales Scrollen statt Quetschen oder
   Umbruch - identische Technik wie bereits bei .menueplan-table (siehe
   @media (max-width: 720px) weiter oben in dieser Datei). */
@media (max-width: 720px) {
    .data-table {
        display: block;
        overflow-x: auto;
    }
}

/* Support-Ticket #244 (2026-09-06, "Was nicht vollständig ist, als nicht
   vollständig markieren"): kleine Status-Badges für die "Wartet auf
   Prüfung"-Tabelle in daten_import_export.php - gleiche Bauart wie
   .badge-technisch weiter oben (inline, kein position:absolute wie beim
   generischen .badge), damit sie sauber in einer normalen Tabellenzelle
   sitzen. Farben: bestehende --color-danger für "nicht vollständig"
   wiederverwendet (siehe .btn-danger/.flash-error), ein gedämpftes Grün
   für "vollständig" (bisher in diesem Projekt noch keine eigene
   --color-success-Variable - hier bewusst lokal begrenzt, um keine neue
   globale Variable für einen einzigen Anwendungsfall einzuführen). */
.badge-status-unvollstaendig,
.badge-status-ok {
    display: inline-block;
    font-size: 0.78rem;
    font-weight: 600;
    border-radius: 999px;
    padding: 2px 10px;
}
.badge-status-unvollstaendig {
    background: #f6e2df;
    color: var(--color-danger);
    cursor: help;
}
.badge-status-ok {
    background: #e9f0e6;
    color: #5c7a52;
}

/* Support-Ticket #261 (2026-09-07, PO wörtlich: "Die Zutatenliste muss
   gekennzeichnet sein, welche Waren bereits gefunden wurden. mit einem
   Grünen Häckchen. Was noch nicht verknüpft ist mit einem Roten X"): kleines
   Status-Symbol je Zutatenzeile in rezept_form.php (.ing-match-status,
   siehe $renderIngredientRow()/#ingredient-row-template/setIngMatchStatus()
   dort) - dieselbe Grün/Rot-Farbgebung wie .badge-status-ok/
   .badge-status-unvollstaendig (Ticket #244) wiederverwendet statt neu
   erfunden, hier aber als reines Text-Symbol (✓/✗) statt als Pille, damit es
   kompakt in die bestehende Flex-Zeile neben Name/Einheit/Menge passt. Leer/
   ohne Klasse (Textbaustein-/Ausrüstung-Zeilen, noch leeres Namensfeld)
   nimmt trotzdem Platz ein, damit die übrigen Felder nicht je nach Zeilenart
   horizontal verrutschen. */
.ing-match-status {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 20px;
    font-size: 0.95rem;
    font-weight: 700;
}
.ing-match-status.ing-match-ok { color: #5c7a52; }
.ing-match-status.ing-match-missing { color: var(--color-danger); }
/* Support-Ticket #392 (2026-09-12): Verknuepfung zeigt auf eine Ware,
   die es nicht mehr gibt - eigene Farbe, damit es nicht mit "gar nicht
   verknuepft" verwechselt wird. */
.ing-match-status.ing-match-fehlt { color: #b45309; }

/* Statusabgleich Support-Uebersicht (2026-09-12, PO-Auftrag "das Supporttool
   auch so machen, dass es in Zukunft richtig funktioniert"). Bewusst dieselbe
   Amber-Warnoptik wie .kosten-warnhinweis - der PO soll auf einen Blick
   erkennen, dass hier etwas klemmt, ohne eine neue Farbsprache lernen zu
   muessen. Das Panel erscheint nur, wenn wirklich etwas nicht zusammenpasst. */
.support-abgleich {
    background: #fffbeb;
    border: 1px solid #d4a017;
    border-radius: var(--radius);
    padding: 10px 14px;
    margin: 0 0 16px;
    color: #92620a;
    font-size: 0.9rem;
}
.support-abgleich > summary {
    cursor: pointer;
    font-weight: 600;
    list-style: none;
}
.support-abgleich > summary::-webkit-details-marker { display: none; }
.support-abgleich > summary::before {
    content: "\25B8";
    display: inline-block;
    margin-right: 6px;
    transition: transform 0.15s ease;
}
.support-abgleich[open] > summary::before { transform: rotate(90deg); }
.support-abgleich .muted { color: #92620a; opacity: 0.85; }
.support-abgleich-titel {
    margin: 12px 0 4px;
    font-weight: 600;
}
.support-abgleich-liste {
    margin: 0;
    padding-left: 18px;
    line-height: 1.6;
    word-break: break-word;
}
p.support-abgleich-liste { padding-left: 0; }
.support-abgleich-fuss { margin-top: 12px; font-size: 0.8rem; }

@media (max-width: 600px) {
    .support-abgleich { font-size: 0.85rem; padding: 8px 10px; }
}

/* Gleiches Panel, aber ohne echte Widersprueche - dann nur eine ruhige,
   neutrale Notiz statt eines Alarms. Sonst gewoehnt man sich an Gelb. */
.support-abgleich-ruhig {
    background: #f4f2ef;
    border-color: #d8d1c7;
    color: #5c5145;
}
.support-abgleich-ruhig .muted { color: #5c5145; }

/* Popup-Modus (Support-Tickets #336/#340/#341, 2026-09-11): Seiten, die in
   einem 500x600-Fenster geoeffnet werden, tragen <body class="popup-modus">
   (gesetzt in includes/header.php, sobald popup=1 in der Adresse steht).
   Kopf- und Fusszeile entfallen dort ohnehin - hier geht es nur darum, dass
   der Inhalt den schmalen Platz auch nutzt statt in der Mitte zu kleben. */
body.popup-modus .container {
    max-width: none;
    padding-left: 14px;
    padding-right: 14px;
}
body.popup-modus main.container { padding-top: 14px; padding-bottom: 14px; }
body.popup-modus .page-head { margin-bottom: 12px; }
body.popup-modus .page-head h1 { font-size: 1.35rem; }
/* Die breiten Formular-Varianten sprengen 500px sonst sofort. */
body.popup-modus .recipe-form,
body.popup-modus .recipe-form.article-form,
body.popup-modus .stammdaten-panel { max-width: none; }

/* Support-Ticket #285 (2026-09-12): Bilder in den Druckansichten. Bewusst
   klein gehalten - eine Waren-Liste mit 50 Zeilen soll durch die Spalte
   nicht auf das Doppelte an Seiten anwachsen. */
.druck-thumb {
    width: 48px;
    height: 48px;
    object-fit: contain;
    background: var(--color-bg);
    border-radius: 4px;
    display: block;
}

.print-section-bild { margin: 0 0 12px; }

.druck-bild {
    max-width: 220px;
    max-height: 160px;
    object-fit: contain;
    background: var(--color-bg);
    border-radius: 6px;
    display: block;
}

/* Support-Tickets #315/#316 (2026-09-12): Anhaenge (Links und Dateien) an
   Rezepten und Menues. */
.anhaenge-liste {
    list-style: none;
    margin: 0 0 14px;
    padding: 0;
}

.anhaenge-liste li {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 5px 0;
    border-bottom: 1px solid var(--color-border);
}

.anhaenge-liste li:last-child { border-bottom: 0; }

.anhaenge-form {
    display: flex;
    gap: 12px;
    align-items: flex-end;
    flex-wrap: wrap;
}

.anhaenge-form .form-group {
    margin: 0;
    min-width: 180px;
    flex: 1 1 200px;
}

.anhaenge-form input[type="file"] { max-width: 100%; }

@media (max-width: 600px) {
    .anhaenge-form { flex-direction: column; align-items: stretch; }
    .anhaenge-form .form-group { min-width: 0; }
}

/* Support-Ticket #307 (2026-09-12): Videolinks am Rezept. Der Rahmen haelt
   das Seitenverhaeltnis 16:9, damit der Player auf dem Handy nicht seitlich
   hinausragt. */
.videos-block > summary { cursor: pointer; font-weight: 600; }

/* PO-Nachtrag 2026-09-12: eine Liste, EIN Player. Die Liste zeigt nur
   Ueberschrift und Dienst; abgespielt wird erst auf Klick, und immer nur
   ein Video. */
.video-liste {
    list-style: none;
    margin: 10px 0 0;
    padding: 0;
}

.video-liste li {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 6px 0;
    border-bottom: 1px solid var(--color-border);
}

.video-liste li:last-child { border-bottom: 0; }

.video-titel { font-weight: 600; }

.video-dienst { font-size: 0.82rem; }

.video-player { margin-top: 14px; }

.video-player-kopf {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 6px;
}

.video-rahmen {
    position: relative;
    width: 100%;
    max-width: 640px;
    aspect-ratio: 16 / 9;
    background: var(--color-bg);
    border-radius: 6px;
    overflow: hidden;
}

.video-rahmen iframe,
.video-rahmen video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    background: #000;
}

@media print {
    .videos-block { display: none !important; }
}

/* Support-Ticket #419 (2026-09-14): Videolinks und Datei-Anhaenge eines
   Rezepts als EIN gemeinsam auf-/zuklappbarer Block ("Anhänge") statt
   zwei getrennter Panels - siehe render_rezept_anhaenge_gesamt_block() in
   includes/functions.php. */
.anhaenge-video-block > summary { cursor: pointer; font-weight: 600; }
.anhaenge-video-unterabschnitt { margin-top: 16px; }
.anhaenge-video-unterabschnitt:first-of-type { margin-top: 12px; }
.anhaenge-video-unterueberschrift {
    margin: 0 0 6px;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--color-primary);
}
.anhaenge-video-trennlinie {
    padding-top: 16px;
    border-top: 1px solid var(--color-border);
}
@media print {
    .anhaenge-video-block { display: none !important; }
}

/* Support-Ticket #303 (2026-09-12): Haekchen ueber der Geschirr-Liste im
   Rezept-Formular. */
.ausruestung-warenkorb-label {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-top: 4px;
    font-weight: 600;
}

/* Support-Ticket #313 (2026-09-12): Verlauf am Rezept. */
.verlauf-block > summary { cursor: pointer; font-weight: 600; }
/* Support-Ticket #404 (2026-09-12, "gleichgrosse Schrift wie die anderen
   auf der Seite"): die Ueberschrift steht seit diesem Ticket als <h3> im
   summary (wie bei .recipe-detail-toggle) - derselbe Margin-Reset wie dort,
   damit kein zusaetzlicher h3-Standardabstand die Klapp-Zeile aufbläht. */
.verlauf-block > summary > h3 {
    display: inline-block;
    margin: 0;
}

.verlauf-daten {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 4px 14px;
    margin: 10px 0 16px;
}

.verlauf-daten dt { font-weight: 600; }

.verlauf-daten dd { margin: 0; }

.verlauf-liste {
    list-style: none;
    margin: 0;
    padding: 0;
}

.verlauf-liste li {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    padding: 4px 0;
    border-bottom: 1px solid var(--color-border);
    font-size: 0.9rem;
}

.verlauf-liste li:last-child { border-bottom: 0; }

.verlauf-zeit { min-width: 130px; }

.verlauf-aktion { font-weight: 600; }

@media (max-width: 600px) {
    .verlauf-daten { grid-template-columns: 1fr; gap: 2px; }
    .verlauf-daten dd { margin-bottom: 8px; }
}

@media print {
    .verlauf-block { display: none !important; }
}

/* Support-Ticket #314 (2026-09-12): Zubereitungszeit in Schritten. Die
   Zahlenfelder bleiben schmal, damit die Tabelle auf dem Handy nicht
   auseinanderfaellt. */
.zeiten-block > summary { cursor: pointer; font-weight: 600; }

.zeiten-tabelle input[type="number"] { max-width: 72px; }

.zeiten-tabelle .zeit-aktionen {
    white-space: nowrap;
    text-align: right;
}

.zeiten-tabelle tfoot th { font-weight: 700; }

.zeiten-anzeige .data-table td:last-child,
.zeiten-anzeige .data-table th:last-child { text-align: right; }

/* Support-Ticket #314, PO-Nachtrag 2026-09-12: Zeitmessung mit Stoppuhr auf
   der Rezeptseite. */
.zeiten-anzeige > summary { cursor: pointer; font-weight: 600; }

.zeiten-personen {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin: 10px 0 12px;
}

.zeiten-mess-tabelle input[type="number"] { max-width: 68px; }

.zeiten-mess-tabelle .uhr-anzeige {
    display: inline-block;
    min-width: 46px;
    font-variant-numeric: tabular-nums;
}

.zeiten-senden {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 12px;
}

.zeiten-senden input[type="text"] { flex: 1 1 220px; max-width: 360px; }

.zeiten-messungen { margin-top: 18px; }

@media (max-width: 600px) {
    .zeiten-senden { align-items: stretch; }
    .zeiten-senden input[type="text"] { max-width: none; }
}

@media print {
    .zeiten-anzeige .zeit-uhr,
    .zeiten-anzeige .zeiten-senden,
    .zeiten-anzeige .zeiten-personen { display: none !important; }
}

/* PO-Meldung 2026-09-12: Hilfslinks bei einer Zutat, die noch keiner Ware
   zugeordnet ist - dezent, aber erreichbar. */
.zutat-hilfslinks {
    display: inline-flex;
    gap: 10px;
    margin-left: 6px;
    font-size: 0.82rem;
}

.zutat-hilfslinks a { white-space: nowrap; }


/* Befund B1 (2026-09-13): Luecken in den Menue-Warenkosten - je Position
   der Grund und ein direkter Weg dorthin, wo sie sich schliessen laesst.
   PO-Vorgabe: "Der fehler muss aber gut erreichbar sein mit den nicht
   verknuepften Waren." */
.kosten-luecken {
    margin: 8px 0 0;
    padding-left: 18px;
    list-style: disc;
}
.kosten-luecken > li {
    margin-bottom: 8px;
    line-height: 1.5;
}
.kosten-luecken-zutaten {
    margin: 4px 0 0;
    padding-left: 16px;
    list-style: circle;
}
.kosten-luecken-zutaten > li {
    margin-bottom: 2px;
    font-size: 0.92em;
}
.kosten-luecken-zutaten .zutat-name {
    font-weight: 600;
}
.luecke-link {
    margin-left: 8px;
    white-space: nowrap;
    font-size: 0.9em;
}

/* Befund B7/B9 (2026-09-13): Einkaufsliste - Gewicht als Nebenangabe unter
   der bestellbaren Menge, und eine Summenzeile unter der Tabelle. */
.einkaufsliste-table .menge-zusatz {
    display: block;
    font-size: 0.82em;
    color: var(--color-muted, #6b7280);
}
.einkaufsliste-table tfoot .einkaufsliste-summe td {
    border-top: 2px solid var(--color-border, #d1d5db);
    padding-top: 8px;
    font-weight: 600;
}
.einkaufsliste-table tfoot .einkaufsliste-summe .muted {
    font-weight: 400;
    font-size: 0.88em;
}


/* PO-Auftrag 2026-09-13: Quellen zusammenfuehren - Auswahlleiste ueber der
   Tabelle und der Hinweis auf den letzten Lauf mit Ruecknahme. */
.quellen-merge {
    border: 1px solid var(--color-border, #d1d5db);
    border-radius: 6px;
    padding: 10px 12px;
    margin-bottom: 12px;
    background: var(--color-surface-2, #f9fafb);
}
.quellen-merge-zeile {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
}
.quellen-merge-anzahl {
    font-weight: 600;
    min-width: 170px;
}
.quellen-merge-rueck {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    margin-bottom: 12px;
    padding: 8px 12px;
    border-left: 3px solid var(--color-accent, #b45309);
    background: var(--color-surface-2, #f9fafb);
    border-radius: 0 4px 4px 0;
    font-size: 0.92em;
}
#quellen-tabelle td input[type="text"] {
    box-sizing: border-box;
}

/* --------------------------------------------------------------
   Aktionspreise (PO-Auftrag 2026-09-13)

   Rot hervorgehoben, damit ein laufender Aktionspreis in Waren- und
   Rezeptliste sofort auffaellt. Der Warenpreis selbst bleibt unveraendert -
   ein Aktionspreis wird nie automatisch uebernommen (PO-Entscheid).

   Barrierefreiheit: die Farbe traegt die Information NICHT allein - daneben
   steht immer das Wort "Aktionspreis" bzw. "Aktion", und jedes Element hat
   ein title-Attribut mit Quelle und Gueltigkeitsdatum. Der Rotton
   (#b3413a, --color-danger) erreicht auf hellem Grund ein Kontrast-
   verhaeltnis von rund 5.2:1 und damit WCAG AA fuer normalen Text.
   -------------------------------------------------------------- */
.aktionspreis {
    display: inline-block;
    color: var(--color-danger);
    font-weight: 600;
    font-size: 0.85em;
    line-height: 1.3;
}

.aktionspreis-bis {
    font-weight: 400;
    white-space: nowrap;
}

/* Filter-Kontrollkaestchen "Aktionspreise suchen" in den Suchleisten. */
.filter-aktion {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
    cursor: pointer;
    font-size: 0.92rem;
}

.filter-aktion input[type="checkbox"] {
    margin: 0;
    /* Grosszuegige Trefferflaeche fuer Touch-Bedienung. */
    width: 18px;
    height: 18px;
}

@media (max-width: 640px) {
    .filter-aktion {
        width: 100%;
    }
}
