/* Heimküche Design-System - flach, modern, responsive. Konventionen: DESIGN.md */

/* Roboto lokal eingebunden (aus dem alten System uebernommen, assets/fonts/) -
   vorher deklarierte die App "Inter" als Schrift, ohne sie je zu laden,
   und fiel damit auf System-Schriften zurueck. Die haben meist nur zwei
   eigene Schnitte (normal/fett), wodurch sich Zwischenstufen wie
   font-weight:600 oder 800 kaum von 700 unterschieden. Mit echten 400/
   500/700-Dateien gibt es jetzt sichtbar unterscheidbare Stufen. */
@font-face {
    font-family: 'Roboto';
    src: url('../fonts/roboto-400.woff2') format('woff2'),
         url('../fonts/roboto-400.woff') format('woff');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Roboto';
    src: url('../fonts/roboto-400-italic.woff2') format('woff2'),
         url('../fonts/roboto-400-italic.woff') format('woff');
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}
@font-face {
    font-family: 'Roboto';
    src: url('../fonts/roboto-500.woff2') format('woff2'),
         url('../fonts/roboto-500.woff') format('woff');
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Roboto';
    src: url('../fonts/roboto-700.woff2') format('woff2'),
         url('../fonts/roboto-700.woff') format('woff');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

/* Eigenstaendige Palette, direkt vom Logo abgeleitet: Teal (#014d5a) als
   Haupt-Akzent, Salbeigruen (#91a16a) als zweiter Akzent/Erfolgsfarbe.
   Dark Mode: neutrales, kuehles Anthrazit statt Braun oder Blaugrau -
   ruhiger Hintergrund, der die Teal-/Gruen-Akzente wirken laesst. */
:root,
:root[data-theme="dark"] {
    /* Erzwingt die dunkle Variante fuer native Browser-UI (z.B. die
       aufgeklappte <select>-Optionsliste), die sich sonst am
       Betriebssystem-Theme statt am data-theme dieser Seite orientiert. */
    color-scheme: dark;
    --bg-primary: #15191a;
    --bg-secondary: #1d2223;
    --bg-tertiary: #262c2d;
    --bg-input: #15191a;
    --border-color: #333b3c;
    --border-light: rgba(255, 255, 255, 0.07);
    --text-primary: #edf2f1;
    --text-secondary: #9aa6a5;
    --text-muted: #66716f;
    --accent-primary: #edf2f1;
    --accent-primary-hover: #ffffff;
    --accent-secondary: #2f9c93;
    --accent-secondary-hover: #3dbab0;
    --accent-secondary-rgb: 47, 156, 147;
    --success: #91a16a;
    --warning: #e0a83f;
    --error: #d16358;
}

:root[data-theme="light"] {
    color-scheme: light;
    --bg-primary: #ffffff;
    --bg-secondary: #f4f7f6;
    --bg-tertiary: #e6edec;
    /* Bewusst etwas dunkler/gedeckter als die Karte (--bg-tertiary), statt
       reinem Weiss - Formularfelder sollen wie ein leicht eingesenktes
       Feld wirken statt wie eine grelle weisse Standard-Box, die sich vom
       Rest der (gedeckten) Palette abhebt. */
    --bg-input: #dde8e6;
    --border-color: #b9c7c5;
    --border-light: rgba(0, 0, 0, 0.05);
    --text-primary: #15191a;
    --text-secondary: #454f4e;
    --text-muted: #6b7574;
    --accent-primary: #15191a;
    --accent-primary-hover: #000000;
    --accent-secondary: #147d74;
    --accent-secondary-hover: #0f605a;
    --accent-secondary-rgb: 20, 125, 116;
    --success: #5e7a42;
    --warning: #b0791d;
    --error: #b8483b;
}

:root {
    --font-family: 'Roboto', -apple-system, BlinkMacSystemFont, sans-serif;
    --radius-sm: 4px;
    --radius-md: 6px;
    --radius-lg: 8px;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.3);
    --shadow-lg: 0 10px 25px rgba(0, 0, 0, 0.4);
    --transition: all 0.15s ease-in-out;
    --topnav-height: 72px;
}

/* Reset & Base */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
    background-color: var(--bg-primary);
    color: var(--text-primary);
    font-family: var(--font-family);
    line-height: 1.5;
    /* Skaliert dezent mit der Fensterbreite statt starr 16px. Nutzer-
       Feedback war deutlich: "das sind 75%" von dem, was es sein sollte -
       das ist jetzt die zentrale Stellschraube dafuer, da praktisch alle
       Masse im Stylesheet in rem gerechnet sind. Nicht weiter absenken,
       ohne die Lesbarkeit gegenzuchecken. */
    font-size: clamp(12px, 0.5vw + 10px, 12.5px);
    -webkit-font-smoothing: antialiased;
}
a { color: var(--accent-secondary); text-decoration: none; transition: var(--transition); }
a:hover { color: var(--accent-secondary-hover); }

/* Buttons/Inputs/Selects erben Schriftart nicht automatisch vom Body -
   ohne das faellt der Browser fuer sie auf seine eigene Standard-
   schrift (z.B. Arial) zurueck, auch wenn .btn/input das eigentlich
   schon einzeln setzen. Als Netz fuer wirklich jedes <button>/<input>/
   <select>/<textarea>, auch ohne eigene Klasse (z.B. reine Icon-
   Buttons). */
button, input, select, textarea { font-family: inherit; }

h1, h2, h3, h4 { color: var(--text-primary); margin-bottom: 0.6rem; font-weight: 500; line-height: 1.2; }
/* Globaler Standard: Seitentitel (h1) UND Zwischenueberschriften (h2)
   bekommen dieselbe Trennlinie in Akzentfarbe - sonst wirken Seiten wie
   "Profil"/"Favoriten" ohne sie im Vergleich zu Seiten mit h2-Abschnitten
   optisch unfertig. Gilt bewusst auch fuer den Rezeptnamen in
   recipe_view.php, fuer ein einheitliches Bild ueber die ganze App. */
h1,
h2 {
    padding-bottom: 0.12rem;
    border-bottom: 3px solid var(--accent-secondary);
    /* In einer Flex-Zeile mit Button (z.B. "Rezepte" + "Neues Rezept")
       soll die Linie bis zum Button durchlaufen statt nur unter dem Wort
       zu enden - als Flex-Kind streckt flex-grow die Box, solange noch
       Platz da ist. */
    flex-grow: 1;
}
h1 { font-size: 1.25rem; font-weight: 700; }
h2 {
    font-size: 1.05rem;
    font-style: italic;
    /* h2 ist (anders als h1) als Block-Element sonst automatisch so
       breit wie der Elternrahmen - die Linie liefe dadurch quer durch
       die ganze Seite statt nur unter dem Wort zu enden (z.B. "Kategorien"
       ohne Button daneben). width:fit-content zieht die Box auf
       Textbreite zusammen; in einer Flex-Zeile gewinnt weiterhin
       flex-grow und die Linie laeuft trotzdem bis zum Button durch. */
    width: fit-content;
}
/* Gemeinsame Zeile "Seitentitel + Aktions-Button" (Rezepte, Benutzer-
   verwaltung, Einheiten, ...) - bodenbuendig statt zentriert, damit der
   (meist hoehere) Button nicht ueber die Trennlinie der Ueberschrift
   ragt, mit etwas Luft, damit der Button nicht direkt auf der Linie
   aufsitzt. */
.page-title-row {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.9rem;
}
.page-title-row .btn { margin-bottom: 3px; }
h3 { font-size: 0.92rem; }
p { color: var(--text-secondary); margin-bottom: 0.75rem; }
label { display: inline-block; margin-bottom: 0.25rem; color: var(--text-primary); font-weight: 500; font-size: 0.8rem; }
small { font-size: 0.875em; color: var(--text-muted); }

/* Top-Navigation statt Sidebar - passt besser zu einer Rezeptseite:
   volle Breite fuer Inhalte/Bilder statt permanent belegter Seitenspalte.
   Verwaltungsfunktionen sind in einem Dropdown gebuendelt statt einzeln
   aufgelistet, damit die Leiste schlank bleibt. */
.topnav {
    position: sticky;
    top: 0;
    z-index: 2000;
    height: var(--topnav-height);
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border-color);
    box-shadow: var(--shadow-sm);
}
.topnav-inner {
    width: 93%;
    max-width: 1400px; /* wie .content, damit Navi und Inhalt buendig sind */
    height: 100%;
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: 1.25rem;
    padding: 0 1.5rem;
}
.topnav-brand { display: flex; align-items: center; flex-shrink: 0; }
.topnav-brand img { height: 38px; width: auto; }

.topnav-links {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 1;
}
.topnav-links > a,
.topnav-dropdown-toggle,
.topnav-dropdown-link {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 0.55rem 0.9rem;
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    font-weight: 500;
    font-size: 0.98rem;
    background: none;
    border: none;
    cursor: pointer;
    font-family: var(--font-family);
    white-space: nowrap;
}
.topnav-links > a:hover,
.topnav-links > a.active,
.topnav-dropdown-toggle:hover {
    background: var(--bg-tertiary);
    color: var(--text-primary);
}
.topnav-links .mdi { font-size: 1.2rem; }
.topnav-mobile-footer { display: none; }

.topnav-dropdown { position: relative; }
.topnav-dropdown-menu {
    display: none;
    position: absolute;
    /* Kein Abstand zum Ausloeser mehr (vorher calc(100% + 6px)) - die
       Luecke war eine "tote Zone": beim Runterfahren mit der Maus vom
       Link zum Menue verliess der Cursor dabei kurz den hoverbaren
       Bereich, wodurch das Menue sofort wieder zuklappte, bevor man es
       erreichte. Oben eckig statt rund + direkt anschliessend wirkt das
       Menue jetzt wie eine Erweiterung des Haupteintrags statt wie eine
       separat schwebende Box. */
    top: 100%;
    left: 0;
    min-width: 210px;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: 0 0 var(--radius-md) var(--radius-md);
    box-shadow: var(--shadow-lg);
    padding: 0.2rem;
    flex-direction: column;
    gap: 1px;
    z-index: 2001;
}
.topnav-dropdown.open > .topnav-dropdown-menu { display: flex; }
.topnav-dropdown-menu a {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0.15rem 0.6rem;
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    font-size: 0.88rem;
    font-weight: 500;
}
.topnav-dropdown-menu a:hover { background: var(--bg-tertiary); color: var(--text-primary); }
.topnav-dropdown-menu a.topnav-dropdown-sub { padding-left: 1.5rem; font-size: 0.85rem; }

/* "Rezepte" ist Link und Dropdown-Ausloeser zugleich: Klick auf den Text
   fuehrt zur Kategorie-Uebersicht, der kleine Pfeil daneben klappt das
   Kategorien-Menue auf (wie bei "Verwaltung"), ohne zu navigieren. Auf
   Mobilbreite gilt dasselbe Prinzip nochmal pro Hauptkategorie mit
   Unterkategorien (.topnav-category-dropdown) - eigener Pfeil klappt nur
   deren Unterkategorien auf. Auf Desktop-Breite (siehe @media unten)
   verschwinden alle diese Pfeile zugunsten von Hover. */
.topnav-dropdown-combo { display: flex; align-items: center; }
.topnav-dropdown-arrow { padding: 0.55rem 0.5rem; }
/* Unterkategorien-Menue steht IMMER (Mobil wie Desktop) unter statt
   neben der Hauptkategorie, dezent eingerueckt - flex-wrap sorgt dafuer,
   dass es in eine eigene, volle Zeile umbricht statt als drittes
   Flex-Element daneben zu landen. */
.topnav-category-dropdown { display: flex; align-items: center; flex-wrap: wrap; }
.topnav-category-arrow { padding: 0.4rem; font-size: 1rem; }
.topnav-category-dropdown .topnav-subcategory-menu { flex-basis: 100%; width: 100%; padding-left: 1.6rem; }
@media (min-width: 901px) {
    /* Kein Klick/Antippen mehr noetig - Hover blendet das Menue ein,
       die Pfeile entfallen (bei "Rezepte"/den Hauptkategorien gibt es ja
       bereits den eigentlichen Link zum Klicken; bei "Verwaltung" ist der
       Pfeil ohnehin nur Dekoration). Eine einzige, generische Regel statt
       einer pro Dropdown-Ebene. */
    .topnav-dropdown-arrow,
    .topnav-category-arrow,
    .topnav-dropdown-caret { display: none; }
    .topnav-dropdown:hover > .topnav-dropdown-menu { display: flex; }
    /* Unterkategorien laufen bewusst wieder IMMER mit, sobald "Rezepte"
       offen ist, statt erst bei eigenem Hover auf der Hauptkategorie
       (z.B. "Backen") - letzteres liess beim Runterfahren der Maus durch
       die Liste staendig Eintraege auf-/zuklappen und darunter liegende
       Kategorien hin- und herspringen. */
    .topnav-subcategory-menu {
        display: flex !important;
        position: static;
        box-shadow: none;
        border: none;
    }
}

.topnav-actions { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.topnav-actions button,
.topnav-icon-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    background: transparent;
    border: none;
    cursor: pointer;
    font-size: 1.3rem;
    transition: var(--transition);
}
.topnav-actions button:hover,
.topnav-icon-btn:hover { background: var(--bg-tertiary); color: var(--text-primary); }
.topnav-user { font-size: 0.95rem; color: var(--text-secondary); margin: 0 0.3rem; }

/* Dezente Deko im leeren Seitenrand auf breiten Monitoren (siehe
   .content max-width unten) - kleine Muetzen-Icons, schraeg gekachelt,
   sehr geringer Kontrast. Ein einziger Layer hinter der gesamten Seite
   statt zweier schmaler Seitenstreifen - Topnav/.content haben ein
   deckendes eigenes Hintergrund und ueberdecken sie in der Mitte
   einfach, dadurch passt es bei jeder Fensterbreite und jedem Zoomstand
   automatisch statt an einer festen Breite/einem Breakpoint zu haengen. */
.side-decor {
    position: fixed;
    inset: 0;
    overflow: hidden;
    opacity: 0.045;
    pointer-events: none;
    /* Negativ, damit sie garantiert HINTER .content/.topnav liegt (die
       haben kein eigenes z-index und wuerden sonst als normale
       Fluss-Elemente ueber einem positiv positionierten Layer landen). */
    z-index: -1;
}
/* Ueberdimensioniert + gedreht, damit beim Kacheln keine Luecken an den
   Raendern des schraegen Musters entstehen (vom Elternelement mit
   overflow:hidden sauber abgeschnitten). */
.side-decor::before {
    content: "";
    position: absolute;
    top: -60%;
    left: -60%;
    width: 220%;
    height: 220%;
    background-image: var(--decor-icon);
    background-repeat: repeat;
    background-size: 26px 26px;
    transform: rotate(25deg);
}
:root[data-theme="dark"] .side-decor { filter: invert(1) brightness(1.6); }

.content {
    width: 93%;
    /* Gemessen an den breitesten Inhalten (z.B. Benutzer-Tabelle ~1375px
       im ausgeklappten Zustand) - auf sehr breiten Monitoren sonst
       ausufernde Breite mit viel Leerraum *innerhalb* der Karte statt
       schlicht mehr Rand links/rechts. */
    max-width: 1400px;
    margin: 1rem auto;
    padding: 1.1rem;
    min-height: calc(100vh - var(--topnav-height) - 2rem);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    background: var(--bg-secondary);
    box-shadow: var(--shadow-sm);
}

.mobile-menu-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    background: transparent;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--accent-secondary);
    cursor: pointer;
    font-size: 1.2rem;
}

@media (max-width: 900px) {
    .mobile-menu-toggle {
        display: flex;
        order: 5;
        margin-left: auto;
        width: 40px;
        height: 40px;
        font-size: 1.7rem;
    }
    .topnav-links {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 2px;
        background: var(--bg-secondary);
        border-bottom: 1px solid var(--border-color);
        box-shadow: var(--shadow-lg);
        padding: 0.5rem;
    }
    .topnav-links.open { display: flex; }
    /* Deutlich kompakter als die Desktop-Groesse (die urspruenglich fuer
       Mobil einfach mit uebernommen wurde) - Nutzer-Feedback: "wesentlich
       weniger Padding, Zeilen muessen nicht so hoch sein". */
    .topnav-links > a,
    .topnav-dropdown-toggle,
    .topnav-dropdown-link {
        padding: 0.35rem 0.6rem;
        font-size: 0.92rem;
    }
    .topnav-dropdown-menu a { padding: 0.3rem 0.5rem; font-size: 0.85rem; }
    .topnav-category-arrow { padding: 0.25rem; }
    .topnav-links .mdi { font-size: 1.05rem; }
    /* Linker Akzentstreifen + leicht abgesetzter Hintergrund, damit das
       aufgeklappte Kategorien-Menue sichtbar als eingerueckter Unterpunkt
       von "Rezepte" erkennbar ist statt gleichrangig/kontrastarm wie die
       Hauptpunkte zu wirken (Nutzer-Feedback: "etwas Kontrast oder
       Akzente"). */
    .topnav-dropdown-menu {
        position: static;
        box-shadow: none;
        border: none;
        border-left: 3px solid var(--accent-secondary);
        background: var(--bg-tertiary);
        border-radius: 0;
        margin: 0.15rem 0 0.15rem 0.6rem;
        padding: 0.15rem 0 0.15rem 0.7rem;
    }
    .topnav-dropdown.open > .topnav-dropdown-menu { display: flex; }
    /* Unterkategorien (z.B. "Torten"/"Kuchen" unter "Backen") zusaetzlich
       zur kleineren Schrift auch gedaempfter in der Farbe, damit sie sich
       von den Hauptkategorien abheben. */
    .topnav-dropdown-menu a.topnav-dropdown-sub { color: var(--text-muted); }
    /* .topnav-dropdown-combo ("Rezepte" + Pfeil + Kategorien-Menue) ist
       display:flex mit 3 direkten Kindern (Link, Pfeil, Menue). Auf
       Mobilbreite wird das Menue von position:absolute auf static
       umgeschaltet (siehe oben) und landete dadurch als drittes Element
       in derselben Reihe NEBEN "Rezepte" statt als eigene Zeile darunter -
       flex-wrap zwingt es in eine neue, volle Zeile. */
    .topnav-dropdown-combo { flex-wrap: wrap; }
    .topnav-dropdown-combo .topnav-dropdown-menu { flex-basis: 100%; width: 100%; }
    .topnav-user { display: none; }
    .topnav-mobile-footer {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 0.35rem 0.6rem;
        margin-top: 0.3rem;
        border-top: 1px solid var(--border-light);
        color: var(--text-secondary);
        font-size: 0.85rem;
    }
    .topnav-mobile-footer a { display: flex; align-items: center; gap: 6px; color: var(--text-secondary); }
    .content { width: 96%; padding: 0.75rem 0.9rem; }
    .topnav-inner { width: 100%; padding: 0 0.5rem; gap: 0.4rem; }
    /* Das Wortmarken-Logo ist recht breit - auf schmalen Handybreiten
       verdraengt es sonst die Icons rechts (Suche/Theme/Abmelden) aus
       dem sichtbaren Bereich. */
    .topnav-brand img { height: 28px; }
    .topnav-actions { gap: 0; }
    .topnav-actions button,
    .topnav-icon-btn { width: 32px; height: 32px; font-size: 1.15rem; }
}

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 0.3rem 0.65rem;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    font-family: var(--font-family);
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    transition: var(--transition);
}
.btn:active { transform: scale(0.96); }
.btn-primary { background: var(--accent-secondary); color: #fff; box-shadow: var(--shadow-sm); }
.btn-primary:hover { background: var(--accent-secondary-hover); }
/* Ghost-Button statt fest ausgefuellter grauer Flaeche - wirkt moderner/
   leichter, Farbe kommt erst beim Hover dazu. */
.btn-secondary { background: transparent; color: var(--text-secondary); border-color: var(--border-color); }
.btn-secondary:hover { background: var(--bg-tertiary); color: var(--text-primary); border-color: var(--text-muted); }
.btn-danger { background: var(--error); color: #fff; }
.btn-danger:hover { filter: brightness(0.9); }
.btn-block { width: 100%; justify-content: center; }
.btn-icon {
    padding: 0.25rem;
    width: 26px;
    height: 26px;
    justify-content: center;
    background: transparent;
    color: var(--text-secondary);
    border: 1px solid var(--border-color);
}
.btn-icon:hover { background: var(--bg-tertiary); color: var(--text-primary); }
.btn-icon.btn-danger { background: transparent; color: var(--error); border-color: var(--border-color); }
.btn-icon.btn-danger:hover { background: var(--error); color: #fff; }

/* Forms */
input:not([type="checkbox"]):not([type="radio"]), textarea, select {
    width: 100%;
    padding: 0.3rem 0.45rem;
    background: var(--bg-input);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    font-family: var(--font-family);
    font-size: 0.8rem;
    margin-bottom: 0.45rem;
    transition: var(--transition);
    box-sizing: border-box;
    /* Leicht eingesenkter Look statt einer flachen Standard-Box */
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.12);
}
/* Browser rendern <select> und <input> trotz identischem Padding oft
   minimal unterschiedlich hoch (eigenes Chrome fuer den Dropdown-Pfeil,
   abweichende Font-Metriken) - feste Hoehe + line-height erzwingt exakt
   gleiche Zeilenhoehe bei allen einzeiligen Feldern nebeneinander
   (z.B. Name/Menge/Einheit in einer Zutatenzeile). */
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
select {
    height: 1.9rem;
    line-height: 1.3;
}
/* Passwort-Feld mit Augen-Icon zum Anzeigen/Verstecken (per JS eingefuegt) */
.password-field {
    position: relative;
    margin-bottom: 0.45rem;
}
.password-field input:not([type="checkbox"]):not([type="radio"]) {
    margin-bottom: 0;
    padding-right: 2rem;
}
.password-toggle {
    position: absolute;
    top: 0;
    right: 0;
    height: 1.9rem;
    width: 1.9rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 1rem;
}
.password-toggle:hover { color: var(--text-primary); }

input:not([type="checkbox"]):not([type="radio"]):focus,
textarea:focus,
select:focus,
.richtext-editor:focus {
    outline: none;
    border-color: var(--accent-secondary);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.12), 0 0 0 3px rgba(var(--accent-secondary-rgb), 0.2);
}
textarea { resize: vertical; min-height: 5rem; }

/* Zahlenfeld-Spinner (Auf/Ab-Pfeile) entfernen - Chrome reserviert dafuer
   sonst trotz appearance:none auf dem <input> selbst noch Layout-Platz
   fuer die Pseudo-Elemente, was das Feld in einer Flexbox-Zeile (z.B.
   Portionen-Stepper) minimal aus der Reihe der Nachbar-Elemente ruecken
   kann, obwohl beide dieselbe CSS-Hoehe haben. */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
input[type="number"] { -moz-appearance: textfield; }


/* Select: eigener Pfeil statt Browser-Default, passend zum Theme.
   -moz-appearance ergaenzt, da Firefox ohne das trotz appearance:none
   eigenes Innenabstand-Chrome fuer den Pfeil behaelt und dadurch minimal
   hoeher rendert als ein <input> mit identischer CSS-Hoehe. */
select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%239cbdb8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 7l5 5 5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.6rem center;
    background-size: 16px;
    padding-right: 2.2rem;
}
select option { background: var(--bg-input); color: var(--text-primary); }

/* Checkbox & Radio: eigenes Design statt Browser-Default */
input[type="checkbox"],
input[type="radio"] {
    appearance: none;
    -webkit-appearance: none;
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    margin: 0;
    background: var(--bg-input);
    border: 2px solid var(--text-muted);
    cursor: pointer;
    position: relative;
    transition: var(--transition);
}
input[type="checkbox"]:hover,
input[type="radio"]:hover { border-color: var(--accent-secondary); }
input[type="checkbox"] { border-radius: 4px; }
input[type="radio"] { border-radius: 50%; }
input[type="checkbox"]:checked,
input[type="radio"]:checked {
    background: var(--accent-secondary);
    border-color: var(--accent-secondary);
}
input[type="checkbox"]:checked::after {
    content: "";
    position: absolute;
    left: 4px;
    top: 1px;
    width: 4px;
    height: 8px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}
input[type="radio"]:checked::after {
    content: "";
    position: absolute;
    inset: 3px;
    border-radius: 50%;
    background: #fff;
}
input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible {
    outline: 2px solid var(--accent-secondary);
    outline-offset: 2px;
}

.checkbox-label {
    display: flex;
    align-items: center;
    gap: 7px;
    font-weight: 400;
    font-size: 0.85rem;
    margin-bottom: 0.3rem;
    cursor: pointer;
}
/* Checkbox-Gruppen (z.B. erlaubte Einheiten) nebeneinander statt
   untereinander - spart deutlich Hoehe bei langen Listen. */
.checkbox-group { display: flex; flex-wrap: wrap; column-gap: 1rem; row-gap: 0.2rem; margin-bottom: 0.5rem; }
.checkbox-group .checkbox-label { margin-bottom: 0; }

/* Cards / Tables */
.card {
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 0.6rem;
    overflow: hidden;
    box-shadow: var(--shadow-sm);
}
/* Scrollbarer Tabellen-Wrapper: Kopfzeile bleibt fixiert (position:sticky),
   nur der Body scrollt darunter - Scrollbalken beginnt erst unterhalb des
   thead (::-webkit-scrollbar-track margin-top), analog mynetdoc. Gilt nur
   ab Desktop-Breite; auf Mobile darf die Tabelle natuerlich mitwachsen.
   Negative margin laesst die Tabelle bis an den Kartenrand reichen statt
   als eigene, sichtbar abgesetzte Box innerhalb der Karte zu wirken -
   .card { overflow: hidden } schneidet die eckigen th-Hintergruende an
   den abgerundeten Kartenecken sauber mit. */
.card > .table-responsive {
    margin: -0.6rem;
    /* overflow-y: scroll (statt auto) haelt die Scrollbalken-Spur immer
       sichtbar, auch wenn (noch) nichts zu scrollen ist - sonst existiert
       das ::-webkit-scrollbar-track-Pseudoelement bei kurzen Tabellen gar
       nicht und die Kopfzeilen-Ecke/-Linie fehlt dort inkonsistent. */
    overflow-y: scroll;
    overflow-x: auto;
    scrollbar-gutter: stable;
}
@media (min-width: 901px) {
    .table-responsive { max-height: calc(100vh - 260px); }
    /* Seiten mit zwei gestapelten Tabellen (Gruppen+Einheiten,
       Haupt-+Unterkategorien, ...): jede bekommt nur die Haelfte statt
       beide unabhaengig fast die volle Hoehe zu beanspruchen - sonst
       wird die Seite trotz Tabellen-internem Scroll insgesamt zu lang. */
    .table-split { max-height: 32vh; }
}
/* Scrollbalken-Kanal einheitlich in Kopfzeilen-Farbe statt zu versuchen,
   eine eigene Linie exakt an die th-Trennlinie anzuschliessen - zwei
   verschiedene Rendering-Systeme (Tabellen-Layout vs. Browser-Scrollbar-
   Chrome) lassen sich nie zuverlaessig pixelgenau aneinanderfuegen. */
.table-responsive::-webkit-scrollbar { width: 8px; height: 8px; background: var(--bg-tertiary); }
.table-responsive::-webkit-scrollbar-track { background: transparent; margin-top: 36px; }
.table-responsive::-webkit-scrollbar-thumb { background: var(--border-color); border-radius: 4px; }
.table-responsive::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }

/* Kategorie-Reiter ueber einer Tabelle (z.B. Zutaten nach Kategorie
   filtern) + Suchleiste im Karten-Kopf darueber - beides rein
   client-seitig, kein Reload noetig. */
.tab-bar { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-bottom: 0.6rem; }

/* Seiten-Reiter fuer mehrere eigenstaendige Tabellen/Bereiche auf einer
   Seite (z.B. Zutaten/Kategorien in admin/ingredients.php) - bewusst
   anderer Stil als .tab-bar (Unterstrich statt Pille), damit die zwei
   Ebenen "Seitenbereich waehlen" vs. "Tabelle filtern" klar auseinander
   zu halten sind, wenn beide auf derselben Seite vorkommen. */
.section-tabs { display: flex; gap: 1.5rem; border-bottom: 1px solid var(--border-color); margin-bottom: 1.1rem; }
.section-tab {
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    padding: 0.5rem 0.1rem;
    font-family: var(--font-family);
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text-secondary);
    cursor: pointer;
    transition: var(--transition);
}
.section-tab:hover { color: var(--text-primary); }
.section-tab.active { color: var(--accent-secondary); border-bottom-color: var(--accent-secondary); }
.tab-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.7rem;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    background: transparent;
    color: var(--text-secondary);
    font-size: 0.8rem;
    font-family: var(--font-family);
    cursor: pointer;
    transition: var(--transition);
}
.tab-btn:hover { background: var(--bg-tertiary); color: var(--text-primary); }
.tab-btn.active { background: var(--accent-secondary); border-color: var(--accent-secondary); color: #fff; }
.tab-count { font-size: 0.68rem; background: rgba(0, 0, 0, 0.15); padding: 0.05rem 0.4rem; border-radius: 1rem; }
.tab-btn.active .tab-count { background: rgba(255, 255, 255, 0.25); }

.table-toolbar {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin: -0.2rem 0 0.6rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--border-color);
    color: var(--text-muted);
}
.table-toolbar input {
    flex: 1;
    border: none;
    background: transparent;
    margin: 0;
    height: auto;
    padding: 0.1rem 0;
    font-size: 0.8rem;
}
.table-toolbar input:focus { outline: none; box-shadow: none; border-color: transparent; }

table { width: 100%; border-collapse: separate; border-spacing: 0; }
th, td { text-align: left; padding: 0.2rem 0.7rem; border-bottom: 1px solid var(--border-light); }
tbody tr:nth-child(even) { background: var(--border-light); }

/* Klickbare Tabellenkopf-Spalte zum Sortieren (admin/recipes.php) */
.sortable-th { cursor: pointer; user-select: none; white-space: nowrap; }
.sortable-th:hover { color: var(--text-primary); }
.sort-icon { font-size: 0.9rem; color: var(--text-muted); vertical-align: middle; }

/* Drag & Drop-Sortierung (siehe initDragSort() in app.js) */
.drag-handle { width: 34px; text-align: center !important; cursor: grab; color: var(--text-muted); }
.drag-handle:active { cursor: grabbing; }
tr[draggable="true"].dragging { opacity: 0.4; }
tr[draggable="true"].drag-over { box-shadow: inset 0 2px 0 var(--accent-secondary); }
th {
    position: sticky;
    top: 0;
    z-index: 10;
    background: var(--bg-tertiary);
    color: var(--text-primary);
    font-weight: 700;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    border-bottom: 2px solid var(--accent-secondary);
}
/* Kopfzelle selbst abrunden statt sich auf das Zuschneiden durch die
   Karte (overflow:hidden) zu verlassen - position:sticky-Elemente
   werden vom Browser oft in eine eigene Compositing-Ebene ausgelagert,
   die die runde Kartenecke der Karte nicht zuverlaessig mitschneidet
   (sichtbar als eckige "Kerbe" an der oberen Kartenecke). */
tr:first-child th:first-child { border-top-left-radius: var(--radius-md); }
tr:first-child th:last-child { border-top-right-radius: var(--radius-md); }

/* Login */
.login-page { display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 1rem; }
.login-box {
    width: 100%;
    max-width: 320px;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 1.25rem;
    text-align: center;
}
.login-logo { width: 160px; height: auto; margin-bottom: 0.7rem; }
.alert { padding: 0.5rem 0.7rem; border-radius: var(--radius-sm); margin-bottom: 0.7rem; font-size: 0.85rem; }
.alert-error { background: rgba(239, 68, 68, 0.12); color: var(--error); border: 1px solid rgba(239, 68, 68, 0.3); }

/* Toast */
#toast-container {
    position: fixed;
    top: 1.25rem;
    right: 1.25rem;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.toast-card {
    pointer-events: auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 15px;
    padding: 0.5rem 0.75rem;
    border-radius: var(--radius-sm);
    background: var(--bg-secondary);
    color: var(--text-primary);
    border-left: 3px solid var(--accent-secondary);
    box-shadow: var(--shadow-lg);
    font-weight: 500;
    font-size: 0.85rem;
    transform: translateX(120%);
    transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.toast-success { border-left-color: var(--success); }
.toast-error, .toast-danger { border-left-color: var(--error); }
.toast-warning { border-left-color: var(--warning); }

/* Modal */
.modal-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 3000;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}
.modal-overlay.open { display: flex; }
.modal {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 0.85rem;
    width: 100%;
    max-width: 400px;
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
    box-shadow: var(--shadow-lg);
}
.modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.4rem;
    margin-top: 0.75rem;
    /* Bleibt beim Scrollen langer Formulare (z.B. Zutat mit Naehrwerten)
       sichtbar, statt dass man erst ganz nach unten scrollen muss, um
       "Speichern" ueberhaupt zu erreichen. */
    position: sticky;
    bottom: -0.85rem;
    margin-left: -0.85rem;
    margin-right: -0.85rem;
    margin-bottom: -0.85rem;
    padding: 0.6rem 0.85rem;
    background: var(--bg-secondary);
    border-top: 1px solid var(--border-color);
}

/* Rezeptanzeige: kompakt statt ueber die volle Breite gezogen (analog
   mynetdoc) - Bildergalerie mit Karussell + Punkte-Navigation und
   Lightbox zum Vergroessern. */
.recipe-view { max-width: 1200px; margin: 0 auto; }
/* Variante 2 der Breiten-Diskussion (gewaehlt): statt Foto/Naehrwerte
   einfach in die Breite zu ziehen (Variante 1, verworfen) laeuft der
   Steckbrief (Kategorie/Ersteller/Portionen) jetzt als durchgehende
   Seitenspalte NEBEN dem kompletten Hauptinhalt (Foto+Naehrwerte,
   Zutaten, Zubereitung, Kommentare) statt nur neben der Kopfzeile -
   fuellt den auf breiten Bildschirmen sonst leeren Platz durchgaengig
   nach unten, ohne den Fliesstext breiter/schwerer lesbar zu machen. */
.recipe-layout { display: grid; grid-template-columns: 1fr minmax(220px, 260px); gap: 1.5rem; align-items: start; }
.recipe-main { min-width: 0; }
.recipe-sidebar { position: sticky; top: calc(var(--topnav-height) + 1rem); margin-top: 12px; }
@media (max-width: 800px) {
    .recipe-layout { grid-template-columns: 1fr; }
    .recipe-sidebar { position: static; }
}
/* Nur die Kopfzeile (Bild + Naehrwerte) ist zweispaltig, alles danach
   (Zutaten/Zubereitung/Kommentare) laeuft einspaltig durch - Nutzer-
   Feedback: eine durchgehende Zweispaltigkeit (Zutaten neben
   Zubereitung) wirkte "komplett durcheinander". */
.recipe-top-row { display: grid; grid-template-columns: minmax(220px, 280px) 1fr; gap: 1rem; align-items: stretch; margin-top: 0.75rem; margin-bottom: 1.8rem; }
@media (max-width: 640px) {
    .recipe-top-row { grid-template-columns: 1fr; }
    /* Einspaltig untereinander soll die Naehrwerttabelle genauso breit
       wie Foto/Zutaten/Zubereitung sein statt rechtsbuendig schmal. */
    .nutrition-table-card { margin-left: 0; max-width: none; width: 100%; }
}
/* Foto so hoch wie die Naehrwerttabelle daneben: die Bild-Spalte wird
   ueber align-items:stretch auf die (von der Naehrwerttabelle
   vorgegebene) Zeilenhoehe gestreckt, das Bild selbst faellt per
   flex:1 auf diese Hoehe. */
.recipe-top-row > div:first-child { display: flex; flex-direction: column; }
/* Naehrwerttabelle rechtsbuendig statt am linken Spaltenrand kleben
   (nur zweispaltig auf breiteren Bildschirmen relevant). */
@media (min-width: 641px) {
    .nutrition-table-card { margin-left: auto; }
}
/* Steckbrief-Kaertchen in der Seitenspalte: Kategorie/Ersteller/
   Portionen als eigene, beschriftete Zeilen statt der engen Ein-Zeiler-
   Zusammenfassung unter dem Rezeptnamen. */
.recipe-info-card { display: flex; flex-direction: column; gap: 0.9rem; }
.recipe-info-row { display: flex; flex-direction: column; gap: 0.1rem; font-size: 0.85rem; }
.recipe-info-row .mdi { color: var(--accent-secondary); font-size: 1.1rem; margin-bottom: 0.1rem; }
.recipe-info-label { color: var(--text-secondary); font-size: 0.75rem; }
.gallery {
    position: relative;
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--bg-secondary);
    margin: 0 0 0.5rem;
    /* Deutlich sichtbarer "Passepartout"-Rahmen statt einer duennen,
       kaum wahrnehmbaren Linie - Feedback: der alte 1px-Rand "fiel kaum
       auf". */
    padding: 6px;
    border: 1px solid var(--border-color);
    box-shadow: var(--shadow-md);
    flex: 1;
    min-height: 160px;
    display: flex;
}
.gallery-viewport { overflow: hidden; flex: 1; border-radius: 4px; }
.gallery-track { display: flex; height: 100%; transition: transform 0.6s ease; }
.gallery-track img { width: 100%; height: 100%; object-fit: cover; flex-shrink: 0; cursor: zoom-in; }
.gallery-nav {
    position: absolute; top: 50%; transform: translateY(-50%);
    background: rgba(0, 0, 0, 0.45); color: #fff; border: none;
    width: 2rem; height: 2rem; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    cursor: pointer; font-size: 1.1rem;
}
.gallery-nav:hover { background: rgba(0, 0, 0, 0.65); }
.gallery-nav.prev { left: 0.5rem; }
.gallery-nav.next { right: 0.5rem; }
.gallery-dots { display: flex; justify-content: center; gap: 0.4rem; margin-bottom: 0.75rem; }
.gallery-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--border-color); border: none; padding: 0; cursor: pointer; }
.gallery-dot.active { background: var(--accent-secondary); }

.lightbox-overlay { background: rgba(0, 0, 0, 0.85); }
.lightbox-content { position: relative; max-width: 92vw; max-height: 92vh; }
.lightbox-content img { display: block; max-width: 92vw; max-height: 88vh; object-fit: contain; border-radius: var(--radius-sm); }
.lightbox-close { position: absolute; top: -2.4rem; right: 0; background: transparent; color: #fff; border-color: rgba(255,255,255,0.3); }
.lightbox-close:hover { background: rgba(255, 255, 255, 0.15); }
.lightbox-content .gallery-nav { top: 50%; }

/* Eigenes Dropdown statt <datalist> (das native Element liess sich nicht
   zuverlaessig live filtern und die Browser-Vorschlagsliste war nicht
   konsistent steuerbar) - Liste erscheint unter dem Feld, Tastatur- und
   Maus-Auswahl moeglich. */
.ing-name-wrap { position: relative; }
.ing-name-dropdown {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 20;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    max-height: 220px;
    overflow-y: auto;
    margin-top: 4px;
    padding: 0.3rem;
    box-shadow: var(--shadow-lg);
    animation: ing-dropdown-in 0.12s ease-out;
}
@keyframes ing-dropdown-in {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: translateY(0); }
}
.ing-name-dropdown.open { display: block; }
.ing-name-dropdown-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.55rem;
    font-size: 0.8rem;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: var(--transition);
}
.ing-name-dropdown-item .mdi { color: var(--text-muted); font-size: 0.95rem; }
.ing-name-dropdown-item:hover, .ing-name-dropdown-item.active { background: var(--bg-tertiary); }
.ing-name-dropdown-item mark { background: none; color: var(--accent-secondary); font-weight: 700; }

/* Nährwerte-Status-Spalte (admin/ingredients.php) */
.nutrition-status {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 0.8rem;
}
.nutrition-status .mdi { font-size: 1rem; }
.nutrition-status-yes { color: var(--accent-secondary); }
.nutrition-status-no { color: var(--text-muted); }

/* Trefferliste der Online-Naehrwertsuche (admin/ingredients.php) */
.nutrition-result-item {
    padding: 0.45rem 0.6rem;
    font-size: 0.8rem;
    cursor: pointer;
    border-bottom: 1px solid var(--border-light);
    transition: var(--transition);
}
.nutrition-result-item:last-child { border-bottom: none; }
.nutrition-result-item:hover { background: var(--bg-tertiary); }

/* Kommentare (recipe_view.php) */
.comment-item { padding: 0.5rem 0; border-bottom: 1px solid var(--border-light); }
.comment-item:last-child { border-bottom: none; }
.comment-meta { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.2rem; font-size: 0.75rem; color: var(--text-muted); }
.comment-meta strong { color: var(--text-primary); font-size: 0.82rem; }
.comment-meta .btn-icon { margin-left: auto; width: 22px; height: 22px; }
.comment-text { margin: 0; font-size: 0.85rem; white-space: pre-wrap; }
.comment-form { margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px solid var(--border-color); }

/* Schnellsuche (Strg+K), siehe templates/footer.php + app.js */
.quick-search-modal { max-width: 520px; padding: 0; overflow: hidden; }
.quick-search-input-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.7rem 0.8rem;
    border-bottom: 1px solid var(--border-color);
    color: var(--text-muted);
}
.quick-search-input-row input {
    flex: 1;
    border: none;
    background: transparent;
    margin: 0;
    height: auto;
    padding: 0.2rem 0;
    font-size: 0.95rem;
    box-shadow: none;
}
.quick-search-input-row input:focus { box-shadow: none; border-color: transparent; }
.quick-search-results { max-height: 60vh; overflow-y: auto; padding: 0.4rem; }
.quick-search-empty { padding: 0.8rem; text-align: center; color: var(--text-muted); font-size: 0.85rem; }
.quick-search-item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.6rem;
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    transition: var(--transition);
}
.quick-search-item:hover { background: var(--bg-tertiary); }
.quick-search-item .mdi { color: var(--text-muted); font-size: 1.1rem; flex-shrink: 0; }
.quick-search-item-text { display: flex; flex-direction: column; gap: 0.1rem; font-size: 0.85rem; }
.quick-search-draft { color: var(--warning); font-weight: 600; }
.quick-search-match { color: var(--text-muted); font-size: 0.75rem; }

/* Portionen-Stepper (recipe_view.php), Vorbild Chefkoch-Style */
.portions-stepper {
    margin-bottom: 0.6rem;
    max-width: 320px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
}
.portions-label { font-size: 0.85rem; }
.portions-stepper-controls { display: flex; align-items: center; gap: 0.5rem; }
.portions-step-btn {
    width: 1.25rem;
    height: 1.25rem;
    font-size: 0.7rem;
    border-radius: 50%;
    border: 1px solid var(--accent-secondary);
    background: transparent;
    color: var(--accent-secondary);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: var(--transition);
    flex-shrink: 0;
}
.portions-step-btn:hover { background: var(--accent-secondary); color: #fff; }
/* Per ID statt nur Klasse: die globale Input-Hoehenregel
   (input:not(...):not(...):not(...) { height: 1.9rem; }) ist per
   CSS-Spezifitaet staerker als eine einfache Klassenregel und wuerde
   sonst weiterhin 1.9rem erzwingen, obwohl die Stepper-Buttons nur
   1.8rem hoch sind - gleicher Bug wie zuvor schon einmal bei diesem
   Input gefunden. */
#portionsInput { height: 1.25rem; text-align: center; font-size: 0.75rem; margin-bottom: 0; }
.portions-stepper-controls input {
    width: 2.6rem;
    text-align: center;
    margin-bottom: 0;
    padding: 0.3rem 0.2rem;
}
/* Per ID statt nur Klasse noetig - die globale "input:not(...)
   {width:100%}"-Regel ist per CSS-Spezifitaet staerker als eine einfache
   Klassenregel und wuerde die 2.6rem sonst ueberschreiben (gleicher Bug
   wie beim #portionsInput in recipe_view.php, siehe Kommentar dort). */
#fPortions { width: 2.6rem; }

/* Gesundheits-Ampel (recipe_view.php) - Nutri-Score A-E auf 3 Stufen
   verdichtet, als Outline-Smileys statt Buchstabe. Der passende Smiley
   hat volle Deckkraft, die anderen beiden sind ausgeblichen. */
.health-traffic-light { display: flex; align-items: center; gap: 0.4rem; margin-bottom: 0.5rem; padding-bottom: 0.5rem; border-bottom: 1px solid var(--border-color); cursor: help; }
.health-label { font-size: 0.8rem; font-weight: 600; color: var(--text-secondary); margin-right: 0.2rem; }
.health-smiley { font-size: 1.35rem; opacity: 0.25; transition: var(--transition); }
.health-smiley.active { opacity: 1; }
.health-good { color: #1e8f4e; }
.health-medium { color: #f2b705; }
.health-bad { color: #d0021b; }
.nutrition-tags { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.nutrition-tag {
    font-size: 0.7rem;
    padding: 0.1rem 0.5rem;
    border-radius: 1rem;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    color: var(--text-secondary);
}

/* Naehrwerte wieder als Tabelle (Kachel-Variante gefiel nicht), aber
   spuerbar kleiner als die urspruengliche Version - halbe Schriftgroesse/
   Zeilenhoehe. */
@media (min-width: 641px) {
    .nutrition-table-card { max-width: 320px; }
}
.nutrition-table th, .nutrition-table td { padding: 0.15rem 0.4rem; font-size: 0.72rem; }
.nutrition-table th { position: static; background: none; border-bottom: 1px solid var(--border-color); color: var(--text-muted); font-weight: 600; text-transform: none; letter-spacing: normal; }
.nutrition-table th:not(:first-child), .nutrition-table td:not(:first-child) { text-align: right; }
.nutrition-sub-label { color: var(--text-muted); padding-left: 1rem !important; }

/* Kompakte Zutatenliste (recipe_view.php) statt einer breiten Tabelle mit
   viel Leerraum zwischen den Spalten - Menge+Einheit rechtsbuendig eng
   beieinander, Name folgt mit knappem Abstand. */
.ingredients-compact { margin-bottom: 2.4rem; }
.ingredients-compact h3 { margin-top: 0; }
/* Mehrere Komponenten (Boden, Belag, ...) stehen nebeneinander, solange
   der Platz reicht - bei nur einer Komponente nimmt sie die volle Breite
   ein, weil sie das einzige Flex-Kind ist. */
.ingredients-components { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.8rem; }
.ingredient-component { flex: 1 1 260px; min-width: 220px; }
/* .ingredient-component selbst ist das Grid, nicht die einzelne Zeile -
   dadurch teilen sich ALLE Zeilen einer Komponente dieselbe Spalten-
   breite und der Name faengt bei jeder Zeile an derselben Stelle an,
   statt dass jede Zeile ihr eigenes, unabhaengig breites Grid waere.
   .ingredient-row selbst wird per display:contents "aufgeloest", ihre
   beiden Kind-Elemente werden direkte Grid-Zellen. Die Mengen-Spalte hat
   eine Obergrenze (7rem) statt sich beliebig an lange Einheitennamen
   ("gestrichener Teelöffel") anzupassen - stattdessen bricht die Einheit
   dort um, der Name bleibt garantiert einzeilig und rechts daneben. */
.ingredient-component {
    display: grid;
    /* max-content statt einer festen Mindestbreite (frueher minmax(4rem,7rem))
       - die Spalte ist pro Komponenten-Box nur so breit wie ihr eigener
       groesster Eintrag (z.B. "500 Teelöffel"), nicht global einheitlich.
       .ingredient-qty deckelt lange Einheiten weiterhin bei 7rem, ab da
       bricht die Einheit um statt die Spalte weiter aufzublaehen. */
    grid-template-columns: max-content 1fr;
    gap: 0 0.6rem;
    font-size: 0.85rem;
    /* Eigene Box je Komponente statt nur Fliesstext nebeneinander -
       macht "Boden"/"Belag" auf den ersten Blick als getrennte Gruppen
       erkennbar statt wie eine durchgehende Liste zu wirken. */
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 0.5rem 0.7rem;
}
/* Die Komponenten-Ueberschrift ("Boden"/"Belag") ist selbst ein
   einzelnes Grid-Item - ohne volle Spaltenbreite wuerde sie nur eine
   Zelle belegen und dadurch alle folgenden Menge/Name-Paare um eine
   Spalte verschieben (Zickzack-Effekt). */
.ingredient-component h3 { grid-column: 1 / -1; }
.ingredient-row { display: contents; }
.ingredient-qty,
.ingredient-name {
    padding: 0.2rem 0;
    border-bottom: 1px solid var(--border-light);
}
.ingredient-qty { max-width: 7rem; }
.ingredient-component .ingredient-row:last-of-type .ingredient-qty,
.ingredient-component .ingredient-row:last-of-type .ingredient-name {
    border-bottom: none;
}
.ingredient-qty { text-align: right; color: var(--text-secondary); white-space: normal; }
.ingredient-name { color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Optionaler Kommentar zu einer Zutatenzeile (z.B. "fein gehackt") -
   eigene Zeile unter dem Namen statt direkt angehaengt, sonst wuerde er
   zusammen mit ihm per Ellipsis abgeschnitten. Startet aber wie der Name
   erst in der zweiten Spalte (nicht ueber die volle Breite ab ganz
   links) - sonst wirkt er wie ein eigener, von der Zutat abgekoppelter
   Eintrag statt sichtbar zu ihr zu gehoeren. */
.ingredient-comment {
    grid-column: 2 / -1;
    margin-top: -0.35rem;
    padding: 0 0 0.3rem;
    line-height: 1.1;
    font-size: 0.75rem;
    font-style: italic;
    color: var(--text-muted);
}

/* Portionen-Stepper im Header-Bereich: schrumpft auf Inhaltsbreite statt
   die ganze Spalte auszufuellen, Eingabefeld deutlich schmaler. */
.portions-stepper-compact { width: fit-content; margin-bottom: 0; }
.portions-stepper-compact .portions-stepper-controls input { width: 1.6rem; padding: 0.1rem; }

/* "Zutaten"-Ueberschrift + Portionen-Stepper in einer Zeile statt der
   Stepper in einer eigenen Box darueber. */
.ingredients-heading-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    padding-bottom: 0.12rem;
    border-bottom: 3px solid var(--accent-secondary);
    margin-bottom: 0.6rem;
}
.ingredients-heading-row h2 { margin-bottom: 0; padding-bottom: 0; border-bottom: none; }

.comments-compact { padding-bottom: 0.4rem; }
.comments-compact .comment-form { margin-top: 0.5rem; padding-top: 0.5rem; }

/* Einfacher WYSIWYG-Editor fuer die Zubereitung (contenteditable +
   execCommand, siehe recipe_form.php) - bewusst kein externes Editor-Paket,
   nur fett/kursiv/unterstrichen + 3 Schriftgroessen. */
.richtext-toolbar {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.3rem;
    border: 1px solid var(--border-color);
    border-bottom: none;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
    background: var(--bg-tertiary);
}
.richtext-toolbar-sep { width: 1px; height: 1.2rem; background: var(--border-color); margin: 0 0.2rem; }
.richtext-editor {
    min-height: 220px;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--border-color);
    border-radius: 0 0 var(--radius-sm) var(--radius-sm);
    background: var(--bg-input);
    color: var(--text-primary);
    font-family: var(--font-family);
    font-size: 0.85rem;
    line-height: 1.5;
    margin-bottom: 0.45rem;
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.12);
}
.richtext-content p, .richtext-editor p,
.richtext-content div, .richtext-editor div { margin: 0 0 0.4rem; }

/* Nummerierte Zubereitungsschritte (Toolbar-Button "Nummerierte Schritte") -
   runde Nummern-Badges statt nackter Zahlen, angelehnt an Chefkoch. */
.richtext-content ol, .richtext-editor ol {
    list-style: none;
    counter-reset: step;
    margin: 0 0 0.4rem;
    padding: 0;
}
.richtext-content ol li, .richtext-editor ol li {
    counter-increment: step;
    position: relative;
    padding-left: 2rem;
    margin-bottom: 0.6rem;
}
.richtext-content ol li::before, .richtext-editor ol li::before {
    content: counter(step);
    position: absolute;
    left: 0;
    top: 0.05rem;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    background: var(--accent-secondary);
    color: #fff;
    font-size: 0.75rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}
.richtext-content ul, .richtext-editor ul { margin: 0 0 0.4rem 1.1rem; }

/* Icon-Auswahl fuer Kategorien (assets/js/icon-picker.js) - Suchfeld +
   Ergebnis-Grid mit anklickbaren Icon-Kacheln. */
.icon-picker-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(42px, 1fr));
    gap: 0.4rem;
    max-height: 260px;
    overflow-y: auto;
    margin: 0.5rem 0;
}
.icon-picker-item {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 42px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    background: var(--bg-input);
    color: var(--text-primary);
    font-size: 1.3rem;
    cursor: pointer;
    transition: var(--transition);
}
.icon-picker-item:hover { background: var(--bg-tertiary); border-color: var(--accent-secondary); }
.icon-picker-hint { color: var(--text-secondary); font-size: 0.85rem; margin: 0.5rem 0; }

/* Kategorie-Kacheln (recipes.php Uebersicht): farbiges rundes Icon-Badge
   statt duenner grauer Strich-Icons, etwas mehr Weissraum, dezentes
   Anheben beim Hover - wirkte vorher zu trostlos/gleichfoermig. */
.category-tile {
    padding: 1.5rem 1rem;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.category-tile:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.category-icon-badge {
    width: 60px;
    height: 60px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.7rem;
    color: #fff;
    margin-bottom: 0.2rem;
}

/* Icon-Auswahlfeld im Kategorie-Formular: aktuelles Icon + "Aendern"-Knopf */
.category-icon-field {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.75rem;
}
.category-icon-preview {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.4rem;
    height: 2.4rem;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    font-size: 1.4rem;
    color: var(--accent-secondary);
    flex-shrink: 0;
}

/* Favoriten (favorites.php): jedes Rezept ein eigenes Badge/Card statt
   einer durchgehenden Liste, nach Hauptkategorie gruppiert - kleineres
   Foto als in der normalen Kategorie-/Rezeptuebersicht. Zwei Spalten
   nebeneinander auf breiteren Bildschirmen (viel ungenutzter Platz bei
   nur einer Spalte), eine Spalte auf Mobilbreite. */
.favorite-list {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.4rem;
    margin-bottom: 1.5rem;
}
@media (min-width: 640px) {
    .favorite-list { grid-template-columns: repeat(2, 1fr); }
}
.favorite-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    color: inherit;
    transition: var(--transition);
}
.favorite-row:hover { border-color: var(--accent-secondary); }
.favorite-row-thumb {
    width: 52px;
    height: 52px;
    border-radius: var(--radius-sm);
    overflow: hidden;
    flex-shrink: 0;
    background: var(--bg-secondary);
}
.favorite-row-thumb img { width: 100%; height: 100%; object-fit: cover; }
.favorite-row-text { min-width: 0; }
.favorite-row-name { display: block; font-weight: 600; }
.favorite-row-desc {
    display: block;
    color: var(--text-secondary);
    font-weight: 400;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ---------- Live-Editor (recipe_form.php) ----------
   Die Seite uebernimmt bewusst dieselben Klassen/dasselbe Layout wie
   recipe_view.php (siehe dort), damit man waehrend des Bearbeitens
   direkt am spaeteren Ergebnis arbeitet statt an einer separaten
   Formular-Optik. Diese Regeln ergaenzen nur die Bearbeiten-Affordanzen
   (editierbare Felder, Icons, Greifer), die recipe_view.php nie
   rendert. */

/* Titel/Kurzbeschreibung als Eingabefelder, aber optisch wie die reine
   Anzeige in recipe_view.php - Rahmen/Hintergrund nur bei Fokus/Hover,
   damit es nicht wie ein "normales Formular" aussieht. */
/* Im Ruhezustand sieht das Feld wie die normale <h1> aus (gleiche
   Schrift + Unterstrich-Linie wie ueberall sonst), erst beim Bearbeiten
   wird sichtbar, dass es ein Eingabefeld ist (Nutzer-Feedback: "nur
   beim Ändern zum Textfeld werden, beim Verlassen wieder als H1"). */
input:not([type="checkbox"]):not([type="radio"]).recipe-title-input {
    display: block;
    width: 100%;
    margin: 0 0 0.1rem;
    padding: 0.1rem 0.15rem 0.12rem;
    border: none;
    border-bottom: 3px solid var(--accent-secondary);
    border-radius: 0;
    background: transparent;
    font-family: var(--font-family);
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--text-primary);
    box-shadow: none;
}
input:not([type="checkbox"]):not([type="radio"]).recipe-title-input:hover { background: var(--bg-tertiary); }
input:not([type="checkbox"]):not([type="radio"]).recipe-title-input:focus {
    border-bottom-color: var(--border-color);
    background: var(--bg-input);
    box-shadow: 0 0 0 3px rgba(var(--accent-secondary-rgb), 0.15);
}
textarea.recipe-description-input {
    display: block;
    width: 100%;
    margin: 0.3rem 0 0;
    padding: 0.15rem 0.3rem;
    border: 1px solid transparent;
    background: transparent;
    resize: vertical;
    min-height: 1.6rem;
    font-family: var(--font-family);
    font-size: 0.85rem;
    color: var(--text-primary);
    box-shadow: none;
}
textarea.recipe-description-input:hover { border-color: var(--border-color); }
textarea.recipe-description-input:focus {
    border-color: var(--accent-secondary);
    background: var(--bg-input);
    box-shadow: 0 0 0 3px rgba(var(--accent-secondary-rgb), 0.15);
}

/* Sidebar-Felder (Kategorie/Portionen/Quelle) inline editierbar statt
   nur Text - Select/Input sollen sich in die schmale Sidebar-Zeile
   einfuegen statt die volle Formular-Feldhoehe zu beanspruchen. */
.recipe-info-row select,
.recipe-info-row input:not([type="checkbox"]):not([type="radio"]) {
    margin-bottom: 0;
    font-size: 0.85rem;
}
.recipe-info-row .portions-stepper-controls { margin-top: 0.1rem; }

/* Bereiche, die erst nutzbar sind, sobald ein Rezeptname vergeben wurde
   (neues Rezept) - dezent ausgegraut statt komplett zu verschwinden,
   damit klar ist, dass dort gleich etwas passiert. */
.gated-section { position: relative; opacity: 0.45; pointer-events: none; transition: opacity 0.15s; }
.gated-hint {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    font-size: 0.8rem;
    color: var(--text-muted);
    background: var(--bg-secondary);
    opacity: 0.9;
    border-radius: var(--radius-md);
    z-index: 5;
    padding: 1rem;
}

/* Dritte (Aktionen) bzw. vierte (Greifer) Grid-Spalte nur im Editor -
   recipe_view.php rendert diese Elemente gar nicht erst, bleibt also
   bei den zwei Spalten aus dem Grundrezept-Regelsatz weiter oben. */
.ingredient-component-editable { grid-template-columns: auto max-content 1fr auto; }
.ingredient-component-editable .ingredient-comment { grid-column: 3 / -1; }
.ingredient-drag-handle {
    display: flex;
    align-items: center;
    color: var(--text-muted);
    cursor: grab;
    padding: 0.2rem 0;
    border-bottom: 1px solid var(--border-light);
    /* Verhindert, dass der Browser bei Touch-Bedienung waehrend des Ziehens
       stattdessen die Seite scrollt (Pointer-Events-Drag, siehe makeSortable()
       in recipe_form.php). */
    touch-action: none;
}
/* Greifer fuer die Komponenten-Reihenfolge selbst (nur bei mehr als
   einer Komponente sichtbar) - eigene Klasse statt .ingredient-drag-handle,
   damit pointerdown eindeutig zwischen "Zutat sortieren" und "Komponente
   sortieren" unterscheiden kann. */
.component-drag-handle {
    display: flex;
    align-items: center;
    color: var(--text-muted);
    cursor: grab;
    flex-shrink: 0;
    touch-action: none;
}
.ingredient-component-editable.dragging { opacity: 0.4; }
.ingredient-component-editable.drag-over { outline: 2px dashed var(--accent-secondary); outline-offset: 2px; }
.ingredient-component-editable .ingredient-row:last-of-type .ingredient-drag-handle,
.ingredient-component-editable .ingredient-row:last-of-type .ingredient-row-actions {
    border-bottom: none;
}
.ingredient-row-actions {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 0.1rem 0;
    border-bottom: 1px solid var(--border-light);
}
.ingredient-row-actions .btn-icon { width: 22px; height: 22px; font-size: 0.85rem; }
/* .ingredient-row ist display:contents (siehe oben) und erzeugt darum
   keine eigene gerenderte Box - opacity/outline direkt am Element haben
   keine Wirkung, darum auf die tatsaechlichen Kind-Elemente umgeleitet. */
.ingredient-row.drag-over > * { outline: 2px dashed var(--accent-secondary); outline-offset: -2px; }
.ingredient-row.dragging > * { opacity: 0.4; }

.ingredient-component-head {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.4rem;
}
.ingredient-component-head .component-name-input { margin: 0; font-size: 0.9rem; }
.ingredient-component-head .btn-icon { flex-shrink: 0; }
.add-ingredient-to-component-btn { grid-column: 1 / -1; width: fit-content; }

/* Stift-Icon oben auf der Galerie im Live-Editor - oeffnet das
   Bilder-verwalten-Popup, die Galerie selbst sieht sonst genauso aus
   wie in recipe_view.php (Nutzer-Feedback: "Bilder nur anzeigen wie bei
   der Ansicht"). */
.gallery-manage-btn {
    position: absolute;
    top: 0.4rem;
    right: 0.4rem;
    z-index: 3;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    border: none;
}
.gallery-manage-btn:hover { background: rgba(0, 0, 0, 0.75); color: #fff; }

/* Bildkarten im "Bilder verwalten"-Popup per Pointer-Events umsortierbar
   (siehe makeSortable() in recipe_form.php) - eigener Greifer statt der
   ganzen Karte, damit Stern/Drehen/Löschen weiter antippbar bleiben. */
.image-card-draggable.dragging { opacity: 0.4; }
.image-card-draggable.drag-over { outline: 2px dashed var(--accent-secondary); outline-offset: -2px; }
.image-card-drag-handle {
    position: absolute;
    top: 0.3rem;
    left: 0.3rem;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: var(--radius-sm);
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    cursor: grab;
    touch-action: none;
}

/* "+"-Kachel im Bilder-Grid, passend zu den bestehenden .card-Bildkarten
   in addImageCard() (recipe_form.php). */
.image-add-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    aspect-ratio: 1;
    border: 2px dashed var(--border-color);
    border-radius: var(--radius-md);
    color: var(--text-muted);
    cursor: pointer;
    font-size: 0.8rem;
    transition: var(--transition);
}
.image-add-tile:hover, .image-add-tile.dragover { border-color: var(--accent-secondary); color: var(--accent-secondary); }
.image-add-tile .mdi { font-size: 1.6rem; }

.zubereitung-heading-row { display: flex; align-items: center; gap: 0.5rem; padding-bottom: 0.12rem; border-bottom: 3px solid var(--accent-secondary); margin-bottom: 0.6rem; }
.zubereitung-heading-row h2 { margin-bottom: 0; padding-bottom: 0; border-bottom: none; }
