/* Literata traegt die Ueberschriften, Instrument Sans den Fliesstext.
   Space Grotesk/Space Mono und Ohno Softie (Adobe) sind damit abgeloest;
   Zahlen, die frueher die Monospace brauchten, stehen auf tabular-nums.

   Literata ist eine variable Schrift mit optischer Groesse (opsz 7-72):
   der Browser waehlt die Strichstaerke passend zur Schriftgroesse selbst,
   solange font-optical-sizing auf auto steht (Standard). Deshalb hier
   bewusst KEIN font-variation-settings — das wuerde die Automatik abschalten
   und opsz auf einen festen Wert nageln.

   Vorgeschichte: davor stand hier Fraunces. Dessen WONK-Achse erzeugte ein
   f mit weit ausschwingendem Kopf; als Bereich angefordert (WONK@0..1)
   liefert Google eine Datei, in der die Achse auf 1 haengt und sich per CSS
   nicht mehr zurueckstellen laesst. Literata hat dieses Problem nicht. */
@import url('https://fonts.googleapis.com/css2?family=Literata:ital,opsz,wght@0,7..72,300..700;1,7..72,300..700&family=Instrument+Sans:ital,wght@0,400..700;1,400..700&display=swap');

/* Basic (hell+dunkel) traegt seit dem neuen Logo beide Markenfarben: Orange
   (--primary/--rezept, fuer Buttons/Aktionen) und Gruen (--active-accent,
   fuer "das hier ist gerade ausgewaehlt" — aktives Sortier-Icon, Foto-
   Auswahl, Titelbild-Stern, Zutat-Schritt-Zuordnung u.ae., ueberall dort wo
   bisher var(--rezept) fuer .active-Zustaende stand). Alle anderen Themes
   setzen --active-accent bewusst gleich ihrem eigenen --rezept, damit sich
   an ihnen nichts aendert — die zweite Markenfarbe ist ein Basic-Merkmal.
   ACHTUNG: "Basic" im Profil-Theme-Picker ist NICHT [data-theme="dark"]
   (das zeigt main.js als "Ocean" an, siehe Kommentar weiter unten), sondern
   [data-theme="dark-neutral"] — dort steht die Orange/Gruen-Faerbung, hier
   bei :root/[data-theme="dark"] bleiben die urspruenglichen Ocean-Blautoene
   unveraendert. */
:root,[data-theme="dark"]{--bg:#131415;--surface:#1f2123;--surface2:#1d1f21;--raise:#393b3d;--field:#0d0e0e;--border:#33373a;--text:#f0f8fb;--text-sub:#9ea8ad;--primary:#6db4d8;--primary-text:#131415;--done:#1e3326;--done-text:#7fb98d;--done-border:#7fb98d;--err:#3b201b;--err-text:#e89584;--err-border:#e89584;--overlay:#0009;--card-shadow:none;--rezept:#6db4d8;--star:#e0b45a;--star-empty:#463c34;--cat-text-dark:#2a211c;--active-accent:#6db4d8;--active-accent-text:#131415;}
[data-theme="light"]{--bg:#f6f2ec;--surface:#fefdfb;--surface2:#efe9e1;--raise:#fefdfb;--field:#fefdfb;--border:#dfd7cb;--text:#2a211c;--text-sub:#7b6b5e;--primary:#b34f3c;--primary-text:#f6f2ec;--done:#e7f0e4;--done-text:#3f6b4a;--done-border:#3f6b4a;--err:#fbe8e3;--err-text:#a8402f;--err-border:#a8402f;--overlay:#0004;--card-shadow:0 1px 2px #3a2b1c0f,0 4px 14px #3a2b1c0d;--rezept:#b34f3c;--star:#c9922f;--star-empty:#ded2c0;--cat-text-dark:#2a211c;--active-accent:#4f7a5f;--active-accent-text:#f6f2ec;}
[data-theme="ocean"]{--bg:#e6eff5;--surface:#ffffff;--surface2:#dbe8f0;--raise:#ffffff;--field:#ffffff;--border:#c3d9e6;--text:#12313f;--text-sub:#4e6f83;--primary:#2f6f92;--primary-text:#e6eff5;--done:#e7f0e4;--done-text:#3f6b4a;--done-border:#3f6b4a;--err:#fbe8e3;--err-text:#a8402f;--err-border:#a8402f;--overlay:#0004;--card-shadow:0 1px 2px #3a2b1c0f,0 4px 14px #3a2b1c0d;--rezept:#2f6f92;--star:#c9922f;--star-empty:#ded2c0;--cat-text-dark:#12313f;--active-accent:#2f6f92;--active-accent-text:#e6eff5;}
[data-theme="peach"]{--bg:#fce9da;--surface:#fffbf7;--surface2:#f9e0cd;--raise:#fffbf7;--field:#fffbf7;--border:#f2ccb2;--text:#43221a;--text-sub:#896155;--primary:#ad5a3c;--primary-text:#fce9da;--done:#e7f0e4;--done-text:#3f6b4a;--done-border:#3f6b4a;--err:#fbe8e3;--err-text:#a8402f;--err-border:#a8402f;--overlay:#0004;--card-shadow:0 1px 2px #3a2b1c0f,0 4px 14px #3a2b1c0d;--rezept:#ad5a3c;--star:#c9922f;--star-empty:#ded2c0;--cat-text-dark:#43221a;--active-accent:#ad5a3c;--active-accent-text:#fce9da;}
[data-theme="forest"]{--bg:#eaf1ec;--surface:#fffefc;--surface2:#e0ebe4;--raise:#fffefc;--field:#fffefc;--border:#ccdfd2;--text:#1c3327;--text-sub:#597264;--primary:#3f7466;--primary-text:#eaf1ec;--done:#e7f0e4;--done-text:#3f6b4a;--done-border:#3f6b4a;--err:#fbe8e3;--err-text:#a8402f;--err-border:#a8402f;--overlay:#0004;--card-shadow:0 1px 2px #3a2b1c0f,0 4px 14px #3a2b1c0d;--rezept:#3f7466;--star:#c9922f;--star-empty:#ded2c0;--cat-text-dark:#1c3327;--active-accent:#3f7466;--active-accent-text:#eaf1ec;}
[data-theme="lavender"]{--bg:#f0ecf5;--surface:#fffdfd;--surface2:#e9e3f0;--raise:#fffdfd;--field:#fffdfd;--border:#d9cfe4;--text:#2c2338;--text-sub:#6f6480;--primary:#75619e;--primary-text:#f0ecf5;--done:#e7f0e4;--done-text:#3f6b4a;--done-border:#3f6b4a;--err:#fbe8e3;--err-text:#a8402f;--err-border:#a8402f;--overlay:#0004;--card-shadow:0 1px 2px #3a2b1c0f,0 4px 14px #3a2b1c0d;--rezept:#75619e;--star:#c9922f;--star-empty:#ded2c0;--cat-text-dark:#2c2338;--active-accent:#75619e;--active-accent-text:#f0ecf5;}
[data-theme="berry"]{--bg:#f8ecec;--surface:#fffdfc;--surface2:#f4e3e4;--raise:#fffdfc;--field:#fffdfc;--border:#ebd0d3;--text:#3a1e24;--text-sub:#86636a;--primary:#a65164;--primary-text:#f8ecec;--done:#e7f0e4;--done-text:#3f6b4a;--done-border:#3f6b4a;--err:#fbe8e3;--err-text:#a8402f;--err-border:#a8402f;--overlay:#0004;--card-shadow:0 1px 2px #3a2b1c0f,0 4px 14px #3a2b1c0d;--rezept:#a65164;--star:#c9922f;--star-empty:#ded2c0;--cat-text-dark:#3a1e24;--active-accent:#a65164;--active-accent-text:#f8ecec;}

/* Theme-Schema: pro Grundton (hell/dunkel) eine Neutral-Variante als Basis,
   dazu farbige Varianten (Ocean, Peach, Forest, Lavender, Berry, ...). "dark"
   traegt aus historischen Gruenden noch den blossen Namen, ist inhaltlich
   aber die Ocean-Variante von Dunkel — das Attribut bleibt unveraendert,
   damit gespeicherte Praeferenzen (localStorage) gueltig bleiben; nur die
   Anzeige in main.js zeigt "Ocean". Neue Varianten: einfach einen weiteren
   [data-theme="..."]-Block ergaenzen und in main.js (THEMES) mit group
   'dark'/'light' eintragen. */
/* Das ist die echte "Basic"-Dunkel-Variante aus dem Profil-Theme-Picker
   (main.js THEMES: key 'dark-neutral' -> name 'Basic') — hier, nicht bei
   :root/[data-theme="dark"] ("Ocean"), gehoert die Orange/Gruen-Faerbung
   hin, siehe Kommentar oben bei :root. */
[data-theme="dark-neutral"]{--bg:#151414;--surface:#1e1d1c;--surface2:#1e1d1d;--raise:#383736;--field:#0e0e0e;--border:#32302f;--text:#fcf1ef;--text-sub:#ae9f9b;--primary:#e0715a;--primary-text:#151414;--done:#1e3326;--done-text:#7fb98d;--done-border:#7fb98d;--err:#3b201b;--err-text:#e89584;--err-border:#e89584;--overlay:#0009;--card-shadow:none;--rezept:#e0715a;--star:#e0b45a;--star-empty:#463c34;--cat-text-dark:#2a211c;--active-accent:#6fa87d;--active-accent-text:#151414;}
[data-theme="dark-peach"]{--bg:#151313;--surface:#1f1c1c;--surface2:#1f1c1c;--raise:#3a3635;--field:#0e0d0d;--border:#352f2d;--text:#fef3f1;--text-sub:#b1a29e;--primary:#f2896f;--primary-text:#151313;--done:#1e3326;--done-text:#7fb98d;--done-border:#7fb98d;--err:#3b201b;--err-text:#e89584;--err-border:#e89584;--overlay:#0009;--card-shadow:none;--rezept:#f2896f;--star:#e0b45a;--star-empty:#463c34;--cat-text-dark:#2a211c;--active-accent:#f2896f;--active-accent-text:#151313;}
[data-theme="dark-forest"]{--bg:#121313;--surface:#1d1f1e;--surface2:#1c1e1d;--raise:#363938;--field:#0c0d0d;--border:#303533;--text:#eef8f4;--text-sub:#9ba8a4;--primary:#55b795;--primary-text:#121313;--done:#1e3326;--done-text:#7fb98d;--done-border:#7fb98d;--err:#3b201b;--err-text:#e89584;--err-border:#e89584;--overlay:#0009;--card-shadow:none;--rezept:#55b795;--star:#e0b45a;--star-empty:#463c34;--cat-text-dark:#2a211c;--active-accent:#55b795;--active-accent-text:#121313;}
[data-theme="dark-lavender"]{--bg:#161516;--surface:#201f21;--surface2:#1f1e20;--raise:#3a393c;--field:#0f0e0f;--border:#343237;--text:#f6f4fb;--text-sub:#a6a3ac;--primary:#a992d4;--primary-text:#161516;--done:#1e3326;--done-text:#7fb98d;--done-border:#7fb98d;--err:#3b201b;--err-text:#e89584;--err-border:#e89584;--overlay:#0009;--card-shadow:none;--rezept:#a992d4;--star:#e0b45a;--star-empty:#463c34;--cat-text-dark:#2a211c;--active-accent:#a992d4;--active-accent-text:#161516;}
[data-theme="dark-berry"]{--bg:#161516;--surface:#211e1f;--surface2:#201e1f;--raise:#3b3839;--field:#0f0e0f;--border:#363032;--text:#fcf1f4;--text-sub:#af9fa2;--primary:#e4718c;--primary-text:#161516;--done:#1e3326;--done-text:#7fb98d;--done-border:#7fb98d;--err:#3b201b;--err-text:#e89584;--err-border:#e89584;--overlay:#0009;--card-shadow:none;--rezept:#e4718c;--star:#e0b45a;--star-empty:#463c34;--cat-text-dark:#2a211c;--active-accent:#e4718c;--active-accent-text:#161516;}

/* --surface2 war an sieben Stellen in Gebrauch (Import-Karten, Einstiegs-
   Karten, Pruefschritt-Zeilen, Hinweisfelder, Bildplatzhalter), aber in KEINEM
   Theme definiert — alle diese Flaechen blieben dadurch transparent und hoben
   sich nur ueber ihren Rahmen ab. Hier einmal zentral abgeleitet statt in
   jedem der dreizehn Themes einzeln: data-theme sitzt auf demselben Element
   wie :root, deshalb loest var() hier pro Theme den richtigen Wert auf. Wer
   spaeter einen eigenen Ton dafuer will, ueberschreibt --surface2 einfach im
   jeweiligen Theme.

   Abgeleitet von --bg, NICHT von --surface: alle sieben Fundstellen liegen in
   einem Modal, und dessen .modal-box ist bereits --surface. Eine Flaeche in
   derselben Farbe waere dort unsichtbar. --bg ist im Modal die vertiefte
   Flaeche und funktioniert in beide Richtungen von selbst: in dunklen Themes
   dunkler als die Box, in hellen leicht getoent statt weiss.

   Genommen wird aber nur der HALBE Schritt dorthin. Ganz auf --bg lagen
   Karte und die transparenten Knoepfe darin optisch gleichauf, weil ein
   .btn-sec seine Flaeche von der Karte bezieht — die Abstufung
   Modal > Karte > Feld war dadurch zu grob.

   @supports statt zweier Deklarationen hintereinander: ein Browser ohne
   color-mix wuerde den ungueltigen Wert in die Custom Property uebernehmen
   und ihn erst bei der Verwendung verwerfen — die Flaeche waere dann gar
   nicht da statt nur etwas anders. So bleibt --bg der saubere Rueckfall. */
/* Formstufen. Bewusst wenige: je zwei benachbarte Werte waren im Ergebnis
   nicht unterscheidbar, haben das Blatt aber unuebersichtlich gemacht. */
:root{
  --r-xs:8px;   /* Bedienelement IN einem anderen (Schrittzaehler-Knopf) */
  --r-sm:12px;  /* deckungsgleich mit --r-md, siehe Kommentar */
  --r-md:12px;  /* Feld, Knopf, alles was in einer Formularzeile steht */
  --r-lg:16px;  /* Flaeche: Karte, Listeneintrag, Panel */
  --r-xl:20px;  /* Fenster */
}

/* --surface2, --raise und --field stehen jetzt in jedem Theme-Block:
   --surface2 = vertiefte Flaeche im Modal, --raise = angehobene Ebene fuer
   Reiter und Icon-Knoepfe (im Dunklen sonst nicht vom Grund zu trennen),
   --field = Flaeche der Eingabefelder. --field ist im Dunklen dunkler als
   --bg: ein Feld ist eine Mulde, keine erhabene Karte — vorher hatte es
   denselben Wert wie .modal-box und war nur ueber seinen Rahmen sichtbar. */

/* Native Steuerelemente (Dropdown-Liste, Datumsauswahl, Scrollbalken) an das
   Theme koppeln — hell bei hellen Themes, dunkel bei Dark. */
[data-theme="dark"],[data-theme="dark-neutral"],[data-theme="dark-peach"],[data-theme="dark-forest"],[data-theme="dark-lavender"],[data-theme="dark-berry"]{color-scheme:dark;}
[data-theme="light"],[data-theme="ocean"],[data-theme="peach"],[data-theme="forest"],[data-theme="lavender"],[data-theme="berry"]{color-scheme:light;}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent;}
body{background:var(--bg);color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;min-height:100vh;display:flex;flex-direction:column;align-items:center;padding:0 1rem 5rem;transition:background .25s,color .25s;}
/* Literata nur fuer Ueberschriften. .detail-section-label ("Zutaten" etc.)
   und .prefs-section-title ("Ernaehrung" etc.) sind optisch auch
   Ueberschriften, tragen im Markup aber kein h1/h2/h3 — deshalb hier mit
   aufgefuehrt. */
h1,h2,h3,.detail-section-label,.prefs-section-title{font-family:'Literata',Georgia,serif;font-weight:600;letter-spacing:-0.005em;}
a{color:var(--rezept);}
button{font-family:'Instrument Sans',system-ui,sans-serif;cursor:pointer;}

/* Standard-Styling für alle Text-Eingabefelder (bewusst früh + geringe
   Spezifität, damit spezialisierte Felder wie im Rezept-Editor es überschreiben).
   So ist jedes neue Eingabefeld automatisch korrekt gestylt. */
input[type="text"],input[type="email"],input[type="password"],input[type="search"],input[type="number"],input[type="date"],input[type="url"],input[type="tel"],textarea{
  width:100%;background:var(--field);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.6rem 0.8rem;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.9rem;outline:none;transition:border-color .2s;
}
input:focus,textarea:focus{border-color:var(--rezept);}
/* Datumsfeld: das native Symbol rechts sass als Pfeil bzw. Kalender HINTER
   dem Datum und zog das Feld ueber die volle Breite. Jetzt traegt der Rahmen
   .date-field ein eigenes Kalender-Icon VOR dem Datum — dadurch faerbt es
   sich ueber currentColor mit dem Theme mit (das alte Icon steckte als
   Daten-URL fest auf einem Blaugrau aus der alten Palette) und laesst sich
   in derselben Strichstaerke zeichnen wie jedes andere Icon.
   Das native Symbol entfaellt nicht ersatzlos, sondern wird durchsichtig
   ueber das GANZE Feld gelegt: so oeffnet ein Tipser irgendwo im Feld
   weiterhin die native Auswahl, ohne dass wir showPicker() brauchen (das
   Safari nicht kennt). */
.date-field{display:inline-flex;align-items:center;position:relative;
  width:max-content;max-width:100%;background:var(--field);border:1.5px solid var(--border);
  border-radius:var(--r-md);padding:0.6rem 0.8rem;transition:border-color .2s;}
.date-field:focus-within{border-color:var(--rezept);}
/* Das Icon liegt UEBER der linken Polsterung des Feldes statt daneben: so
   reicht das Eingabefeld (und damit der durchsichtige native Indikator
   darueber) bis unter das Icon, und ein Tipser aufs Icon oeffnet die Auswahl
   mit. Als Flex-Geschwister waere das Icon eine tote Flaeche gewesen.
   pointer-events:none, damit der Klick durchfaellt. */
.date-field>svg{position:absolute;left:0.8rem;top:50%;transform:translateY(-50%);
  pointer-events:none;display:block;color:var(--text-sub);}
.date-field input[type="date"]{width:auto;min-width:0;background:none;border:none;
  border-radius:0;padding:0 0 0 1.5rem;font-size:0.9rem;}
.date-field input[type="date"]:focus{border:none;}
.date-field input[type="date"]::-webkit-calendar-picker-indicator{
  position:absolute;inset:0;width:100%;height:100%;margin:0;padding:0;opacity:0;cursor:pointer;}
/* Platzhalter deutlich blasser als echter Text, damit klar ist: das ist ein
   Beispielwert und keine Eingabe (z.B. die "0" im Mengenfeld). */
input::placeholder,textarea::placeholder,#auth-view input::placeholder{color:var(--text-sub);opacity:0.55;}

/* ── Start-Overlay ─────────────────────────────────────────── */
/* Deckt die Luecke zwischen Speichern und geoeffnetem Rezept ab. Liegt ueber
   den Modals, damit in der Zeit nicht das Dashboard durchblitzt. */
#busy-overlay{position:fixed;inset:0;background:color-mix(in srgb, var(--bg) 88%, transparent);display:flex;align-items:center;justify-content:center;z-index:900;}
#busy-overlay[hidden]{display:none;}
.busy-box{display:flex;align-items:center;gap:0.6rem;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);padding:0.8rem 1.1rem;color:var(--text);font-size:0.85rem;box-shadow:0 8px 28px rgba(0,0,0,0.25);}
/* Dasselbe Logo wie der Splash beim Seitenstart, nur kleiner — damit Laden
   ueberall gleich aussieht statt mal Ring, mal Logo. */
.busy-logo{width:1.5rem;height:1.5rem;flex-shrink:0;color:var(--text);animation:spin 1.1s linear infinite;}
#app-loading{position:fixed;inset:0;background:var(--bg);display:flex;align-items:center;justify-content:center;z-index:500;}
/* --text ist in jedem Theme automatisch die passende hoch-kontrastige Farbe
   (nahezu weiss im Dunklen, nahezu schwarz im Hellen) — kein eigener
   Hell/Dunkel-Fall noetig. stroke=var(--bg) trennt Rot/Gruen normalerweise
   farblich, hier einfarbig einfach der "Ausschnitt" zum Hintergrund. */
.app-loading-logo{width:2.6rem;height:2.6rem;color:var(--text);animation:spin 1.1s linear infinite;}
@keyframes spin{to{transform:rotate(360deg);}}

/* ── Auth (Login/Registrieren) ─────────────────────────────── */
/* padding-top deutlich reduziert, seit das Logo 3x so gross ist (12.6rem
   statt 4.2rem) — sonst waechst die zusaetzliche Hoehe nach unten obendrauf
   und schiebt das Formular weit unter die erste Bildschirmseite. Das Logo
   waechst dadurch effektiv nach oben in den frei gewordenen Platz. */
#auth-view{width:100%;max-width:420px;margin:auto;padding-top:0.5rem;}
/* Ohne eigene Breite schrumpft #app-view als zentriertes Flex-Kind auf seinen
   Inhalt — bei leerem Raster sprang dadurch das ganze Layout schmal. */
#app-view{width:100%;max-width:860px;}
.auth-logo{display:block;height:12.6rem;width:auto;margin:0 auto 1.5rem;}
@media(max-width:600px){.auth-logo{height:10.08rem;}}
#auth-view h2{font-size:1.2rem;font-weight:500;margin-bottom:1rem;color:var(--rezept);}
#auth-view input{width:100%;background:var(--field);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.65rem 0.9rem;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.9rem;outline:none;transition:border-color .2s;margin-bottom:0;}
#auth-view input:focus{border-color:var(--rezept);}
#auth-view>div>button,#auth-view #login-btn,#auth-view #signup-btn{width:100%;padding:0.7rem;border-radius:var(--r-md);border:none;font-weight:700;font-size:0.92rem;background:var(--primary);color:var(--primary-text);margin-top:0.4rem;}
#auth-view p{margin-top:0.9rem;font-size:0.85rem;}
#auth-view p a{color:var(--active-accent);}
#auth-message{text-align:center;color:var(--err-text);min-height:1rem;}
.avatar-section-label{font-size:0.75rem;font-weight:600;letter-spacing:0;text-transform:none;color:var(--text-sub);margin:0.8rem 0 0.35rem;}
.avatar-picker{display:grid;grid-template-columns:repeat(8,1fr);gap:0.3rem;margin-bottom:0.4rem;}
.avatar-opt{font-size:1.3rem;padding:0.25rem;border-radius:var(--r-xs);cursor:pointer;border:2px solid transparent;transition:all .15s;text-align:center;}
@media(hover:hover){.avatar-opt:hover{background:var(--surface);}}
.avatar-opt.selected{border-color:var(--active-accent);background:var(--surface);}
.field-wrap{position:relative;margin-bottom:0.6rem;}
.field-wrap input{margin-bottom:0!important;}
/* Auge sitzt am rechten Rand. Nur wenn zusätzlich das Fehler-Icon erscheint,
   rückt es nach links, damit sich beide nicht überlagern. */
.field-wrap input[type="password"],.field-wrap input[type="text"].pw-visible{padding-right:2.8rem!important;}
.field-wrap.has-error input[type="password"],.field-wrap.has-error input[type="text"].pw-visible{padding-right:4.4rem!important;}
.pw-toggle{display:flex;align-items:center;justify-content:center;position:absolute;right:0.5rem;top:50%;transform:translateY(-50%);width:1.8rem;height:1.8rem;padding:0;background:transparent;border:none;border-radius:var(--r-md);color:var(--text-sub);line-height:1;opacity:0.75;}
.field-wrap.has-error .pw-toggle{right:2.3rem;}
@media(hover:hover){.pw-toggle:hover{opacity:1;background:var(--surface);}}
.field-error-icon{display:none;position:absolute;right:0.6rem;top:50%;transform:translateY(-50%);width:18px;height:18px;align-items:center;justify-content:center;border:2px solid var(--err-border);border-radius:50%;color:var(--err-text);font-weight:700;font-size:0.75rem;line-height:1;background:var(--surface);}
.field-wrap.has-error input{border-color:var(--err-border);}
.field-wrap.has-error .field-error-icon{display:flex;}

/* ── Header ─────────────────────────────────────────────────── */
header{width:100%;max-width:860px;display:flex;align-items:center;justify-content:space-between;padding:1.5rem 0 0.5rem;margin-bottom:1.2rem;}
.header-left{display:flex;align-items:center;gap:0.6rem;min-width:0;}
#hdr-avatar{font-size:1.4rem;line-height:1;}
header h1{font-size:1.05rem;font-weight:600;text-transform:none;letter-spacing:0;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.hdr-actions{display:flex;gap:0.3rem;flex-wrap:wrap;justify-content:flex-end;}
.hdr-icon-btn{position:relative;width:2.3rem;height:2.3rem;flex-shrink:0;border-radius:50%;border:1px solid var(--border);background:var(--raise);box-shadow:var(--card-shadow,none);color:var(--rezept);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .15s;padding:0;}
/* Zähler für offene Beitrittsanfragen */
.hdr-badge{position:absolute;top:-5px;right:-5px;min-width:1.05rem;height:1.05rem;padding:0 0.22rem;border-radius:99px;background:#dc2626;color:#fff;font-size:0.62rem;font-weight:700;line-height:1.05rem;text-align:center;box-shadow:0 0 0 2px var(--bg);}
@media(hover:hover){.hdr-icon-btn:hover{opacity:0.8;}}

.main{width:100%;max-width:860px;}

/* ── Toolbar / Suche / Sortierung / Filter ─────────────────── */
/* ── Herkunft-Reiter ────────────────────────────────────────────
   Die Reiter nutzen die volle Breite, teilen sie aber nach Textlaenge auf
   (flex:1 1 auto + gleicher Innenabstand) statt in gleiche Drittel: bei
   gleichen Dritteln waere der Unterstrich unter "Alle" dreimal so breit wie
   das Wort. */
/* Sind die Reiter da, uebernehmen sie die Trennung vom Kopfbereich — sonst
   liefen zwei fast gleiche Linien mit wenigen Pixeln Abstand parallel. Die
   Regel haengt am body, weil der Kopf ausserhalb von .main liegt. */
body.hat-reiter header{border-bottom:none;margin-bottom:0.6rem;}
.lib-tabs{display:flex;gap:0.25rem;background:var(--surface2);border:1.5px solid var(--btn-edge2);padding:0.2rem;border-radius:99px;margin-bottom:0.8rem;}
.lib-tab{flex:1 1 auto;padding:0.32rem 0.6rem;border:none;border-radius:99px;background:none;font-size:0.8rem;color:var(--text-sub);white-space:nowrap;text-align:center;cursor:pointer;transition:background .15s,color .15s;}
.lib-tab.active{background:var(--raise);color:var(--text);font-weight:600;box-shadow:var(--card-shadow,none);}

.toolbar-row{display:flex;gap:0.5rem;align-items:center;margin-bottom:0.8rem;}
.search-wrap{flex:1;min-width:0;position:relative;display:flex;}
#search-input{width:100%;min-width:0;background:var(--field);border:1.5px solid var(--btn-edge2);border-radius:var(--r-md);padding:0.7rem 2.3rem 0.7rem 1rem;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.9rem;outline:none;transition:border-color .2s;appearance:none;-webkit-appearance:none;}
#search-input:focus{border-color:var(--rezept);}
/* Der native Lösch-Knopf erscheint je nach Browser gar nicht oder nur bei
   Fokus — deshalb ein eigener, immer sichtbar sobald etwas im Feld steht. */
#search-input::-webkit-search-cancel-button{display:none;}
.search-clear{position:absolute;right:0.4rem;top:50%;transform:translateY(-50%);width:1.7rem;height:1.7rem;display:flex;align-items:center;justify-content:center;border:none;background:none;color:var(--text-sub);cursor:pointer;border-radius:50%;padding:0;}
.search-clear[hidden]{display:none;}
@media(hover:hover){.search-clear:hover{color:var(--text);}}
/* ── Sortieren ──────────────────────────────────────────────────
   Statt drei Icons ein Knopf, der selbst sagt, was gerade gilt ("A–Z ↓").
   Ein stummes Sortier-Symbol haette verschwiegen, wonach sortiert wird —
   genau das war am aufklappbaren Panel sonst der wunde Punkt. */
/* Feste Breite: Das Icon wechselt, der Knopf bleibt gleich gross — sonst
   huepfte das Suchfeld daneben bei jedem Sortierwechsel. */
.sort-btn{
  /* align-self:stretch statt fester Hoehe: so ist der Knopf immer exakt so
     hoch wie das Suchfeld daneben, auch wenn dessen Polsterung sich aendert. */
  flex-shrink:0;width:3.4rem;align-self:stretch;border-radius:var(--r-md);
  border:1.5px solid transparent;background:var(--active-accent);
  color:var(--active-accent-text);cursor:pointer;font-weight:700;
  display:flex;align-items:center;justify-content:center;gap:0.15rem;
  white-space:nowrap;transition:background .15s;
}
.sort-btn .sort-dir{font-size:0.72rem;line-height:1;}
.sort-panel{
  background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-sm);
  padding:0.5rem;margin:-0.2rem 0 0.9rem;
}
.sort-row{
  display:flex;align-items:center;justify-content:space-between;gap:0.5rem;width:100%;
  padding:0.45rem 0.55rem;border-radius:var(--r-xs);border:none;background:none;
  font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.84rem;color:var(--text-sub);
  cursor:pointer;text-align:left;transition:background .15s;
}
@media(hover:hover){.sort-row:hover{background:var(--bg);}}
.sort-row.active{color:var(--active-accent);font-weight:700;}
/* Dieselben drei Icons wie am Knopf, damit die Zeile und der eingeklappte
   Zustand sichtbar zusammengehoeren. */
.sort-row-name{display:inline-flex;align-items:center;gap:0.5rem;min-width:0;}
.sort-row-icon{display:inline-flex;align-items:center;justify-content:center;width:1.1rem;flex-shrink:0;color:var(--text-sub);}
.sort-row.active .sort-row-icon{color:var(--active-accent);}
/* Rahmen und Polsterung tragen ALLE Zeilen, sichtbar ist er nur bei der
   aktiven. Sonst war die aktive Zeile 4 px hoeher als die uebrigen, und beim
   Wechseln der Auswahl rutschten die Zeilen sichtbar hin und her. */
.sort-row .sort-state{
  display:inline-flex;align-items:center;gap:0.3rem;font-size:0.76rem;flex-shrink:0;
}
.sort-panel-hint{font-size:0.7rem;color:var(--text-sub);padding:0.35rem 0.55rem 0.1rem;}
.sort-panel-label{
  font-size:0.62rem;letter-spacing:0.13em;text-transform:uppercase;
  color:var(--text-sub);padding:0.7rem 0.55rem 0.35rem;
}
.sort-panel-probe{text-transform:none;letter-spacing:0;opacity:0.7;}
/* Status-Chips eckig, die Kategorie-Chips im Dashboard bleiben rund: rund
   heisst "worum geht es", eckig heisst "in welchem Verhaeltnis stehe ich
   dazu". Die Kachelliste selbst ist ebenfalls randlos-eckig. */
.status-chips{display:flex;flex-wrap:wrap;gap:0.3rem;padding:0 0.55rem 0.2rem;}
.status-chip{
  font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.75rem;
  padding:0.3rem 0.55rem;border-radius:var(--r-xs);
  border:1.5px solid var(--border);background:transparent;color:var(--text-sub);
  cursor:pointer;display:inline-flex;align-items:center;gap:0.35rem;
  transition:border-color .15s,color .15s;
}
@media(hover:hover){.status-chip:hover{border-color:var(--active-accent);color:var(--active-accent);}}
.status-chip.active{border-color:var(--active-accent);color:var(--active-accent);font-weight:700;}
.status-chip svg{flex-shrink:0;}
.filter-row{display:flex;flex-wrap:wrap;gap:0.35rem;margin-bottom:1.2rem;}
.cat-chip{font-size:0.72rem;padding:0.25rem 0.62rem;border-radius:var(--r-xl);border:1.5px solid transparent;background:var(--surface2);color:var(--text-sub);cursor:pointer;transition:all .15s;display:inline-flex;align-items:center;gap:0.35rem;}
.cat-chip.active{color:#fff;border-color:transparent;}
.cat-dot{width:0.55rem;height:0.55rem;border-radius:50%;flex-shrink:0;}
/* Behaelt seinen Platz, damit der Chip beim Aktivieren nicht schrumpft. */
.cat-dot-leer{visibility:hidden;}
.cat-add-btn{font-size:0.75rem;padding:0.3rem 0.65rem;border-radius:var(--r-xl);border:1.5px dashed var(--border);background:transparent;color:var(--text-sub);cursor:pointer;}
@media(hover:hover){.cat-add-btn:hover{border-color:var(--rezept);color:var(--rezept);}}
/* Vertikales Polster von 0.1 auf 0.28rem: die Chips waren so flach, dass sie
   neben den uebrigen Zeilen wie ein Farbstreifen wirkten statt wie Etiketten.
   Die Schriftgroesse bleibt — es ging nur um die Hoehe. */
.cat-pill{font-size:0.68rem;font-weight:600;padding:0.28rem 0.6rem;border-radius:var(--r-md);color:#fff;display:inline-block;margin:0 0.3rem 0.3rem 0;}
#empty-hint,#filter-empty-hint{text-align:center;color:var(--text-sub);font-size:0.85rem;padding:2.5rem 1rem;}

/* ── Bibliothek ─────────────────────────────────────────────── */
/* Der Rahmen kappt die zur Seite gleitende Liste beim Reiterwechsel. Er darf
   NICHT overflow-y:hidden bekommen — sonst waere die Liste in sich scrollbar
   statt mit der Seite zu scrollen. */
.lib-viewport{position:relative;overflow-x:clip;margin:0;}
.lib-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:7px;will-change:transform;}
/* Abbild der bisherigen Liste waehrend des Reiterwechsels: liegt absolut im
   Rahmen, damit es die Hoehe nicht mitbestimmt, und faengt keine Tipser ab. */
.lib-grid-klon{position:absolute;top:0;left:0;width:100%;pointer-events:none;}

/* ── Marker auf der Kachel ──────────────────────────────────────
   Die Zeichen sitzen im Sockel unten, vor Autor und Bewertung — auf dem
   Verlauf, der dort ohnehin liegt und weissen Text auf jedem Foto traegt.
   Frei auf dem Foto brauchte der Marker einen eigenen Schein oder eine
   Abdunklung und sah dadurch aufgelegt aus; hier fuehrt er keine neue
   Flaeche ein und braucht keine Ausnahme. Weiss wie der Titel darueber,
   nur leicht gedaempft: eine private Notiz, keine Auszeichnung.
   Merkliste und Liebling in derselben Farbe — die Form unterscheidet sie,
   und keiner der beiden ist wichtiger als der andere. */
.recipe-card-sub .card-mark{
  display:inline-flex;align-items:center;gap:3px;flex-shrink:0;
  color:rgba(255,255,255,0.92);
}

/* ── Merkliste/Liebling im Detail ───────────────────────────────
   Titel links, die beiden Zeichen rechts daneben. Der Abstand rechts am
   Container haelt den Schliessen-Knopf frei — er lag vorher am Titel selbst. */
.detail-head{display:flex;align-items:flex-start;gap:0.6rem;}
#detail-modal:not(.has-cover) .detail-head{padding-right:2rem;}
.detail-head #detail-title{flex:1;min-width:0;padding-right:0;}
.detail-marks{display:flex;gap:0.25rem;flex-shrink:0;margin-top:0.1rem;}
/* Reine Zeichen ohne Beschriftung: gefuellt heisst gesetzt, Kontur offen. */
.mark-btn{
  width:2.1rem;height:2.1rem;flex-shrink:0;
  display:flex;align-items:center;justify-content:center;
  border:none;background:none;padding:0;cursor:pointer;
  transition:color .15s,transform .15s;
}
/* Farbe der beiden Schalter, ueber zwei Marken gesteuert.

   Im Dunklen wie auf der Kachel: gesetzt in --text (dort praktisch Weiss),
   offen gedaempft in --text-sub. Ein festes Weiss geht nicht, der Untergrund
   im Rezept ist in den hellen Themes selbst fast weiss.

   In den hellen Themes tragen BEIDE Zustaende die Markenfarbe. --text waere
   dort ein fast schwarzes Braun und damit schwerer, als die Sache ist. Dass
   die Zustaende dieselbe Farbe haben, macht nichts: unterschieden werden sie
   ohnehin ueber Kontur gegen Fuellung — dieselbe Regel wie auf der Kachel. */
.mark-btn{color:var(--mark-offen,var(--text-sub));}
.mark-btn.active{color:var(--mark-gesetzt,var(--text));}
@media(hover:hover){.mark-btn:hover{color:var(--mark-gesetzt,var(--text));}}
[data-theme="light"],[data-theme="ocean"],[data-theme="peach"],
[data-theme="forest"],[data-theme="lavender"],[data-theme="berry"]{
  --mark-offen:var(--primary);
  --mark-gesetzt:var(--primary);
}
.mark-btn:active{transform:scale(0.88);}
/* Transition hier bewusst langsam: sie gilt fuers Zurueckschrumpfen weg vom
   Hover-Zustand, damit die Karte noch sichtbar "nachzieht". Das Reinzoomen
   selbst ist ueber die schnellere Transition bei :hover definiert. */
/* Poster-Kachel: das Foto fuellt die ganze (hochformatige) Karte, Titel und
   Bewertungszeile liegen unten auf einem Verlauf. Kategorie nur noch als
   Farbstreifen an der Unterkante. */
.recipe-card{position:relative;background:var(--surface2);overflow:hidden;border-radius:var(--r-lg);box-shadow:var(--card-shadow,none);cursor:pointer;transition:box-shadow .9s ease-out;aspect-ratio:0.74;touch-action:pan-y;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;}
/* card-badges/card-badge* werden noch von #lightbox-badge (Foto-Autor in der
   Vollbild-Ansicht, index.html) gebraucht - hier stehen lassen. Die Rezept-
   Kachel selbst zeigt Attribution/Sharing seit dem Redesign nicht mehr auf
   dem Foto, sondern als card-meta* in der Bewertungszeile (siehe unten). */
.recipe-cover-wrap{position:absolute;inset:0;overflow:hidden;}
.card-badges{position:absolute;z-index:2;display:flex;gap:4px;max-width:calc(100% - 12px);pointer-events:none;}
.card-badges-bl{left:6px;bottom:6px;}
.card-badges-tr{right:6px;top:6px;}
.card-badge{display:inline-flex;align-items:center;gap:3px;padding:3px 6px;border-radius:7px;background:rgba(0,0,0,0.62);color:#fff;font-size:0.7rem;line-height:1;min-width:0;}
.card-badge-emoji{font-size:0.72rem;flex-shrink:0;}
.card-badge-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* Nur das Cover-Foto zoomt beim Hover leicht rein - Karten-Aussenmasse
   bleiben stabil (kein Ueberlappen im engen Grid). Auf Touch-Geraeten gibt es
   das nicht mehr: dort wischt man jetzt waagerecht durch die Herkunft-Reiter
   (siehe onLibGridPointerDown in recipes.js). */
@media(hover:hover){.recipe-card:hover .recipe-cover{transform:scale(1.2);transition:transform .4s ease-out;}}
/* Platzhalter ohne Foto bewusst nicht mit --bg: das ist ueberall um die
   randlose Karte herum (Seiten- und Luecken-Hintergrund) identisch, die
   Kachel wuerde unsichtbar mit der Seite verschmelzen. Volles --border war
   zu kraeftig (Rezepte ohne Foto stachen staerker heraus als welche mit) -
   auf halbem Weg zwischen --border und --bg gemischt, dezent aber sichtbar
   abgesetzt. */
.recipe-cover{width:100%;height:100%;object-fit:cover;display:block;background:color-mix(in srgb,var(--border) 50%,var(--bg) 50%);-webkit-user-drag:none;transition:transform .9s ease-out;}
/* Ohne Foto: hat das Rezept eine Kategorie, setzt das JS einen Verlauf in
   deren Farbe. Sonst ein dezenter Ton zwischen --border und --bg — kraeftig
   genug, dass die Kachel in beiden Themes sichtbar von der Seite absteht,
   aber ruhiger als ein Foto. */
/* Ohne Foto: Verlauf als Grund + heller Text wie bei den Foto-Kacheln, damit
   die Kachel klar von der Seite absteht. Mit Kategorie setzt das JS stattdessen
   einen Verlauf in deren Farbe. Das Symbol sitzt etwas oberhalb der Mitte,
   damit es nicht mit dem Titel unten kollidiert. */
.recipe-cover-empty{display:flex;align-items:center;justify-content:center;padding-bottom:3.6rem;color:rgba(255,255,255,0.32);background:linear-gradient(150deg,#3b3937,#1b1a19);}
/* Mit Kategorie: derselbe Verlauf, nur in der Kategoriefarbe — im Dunkeln
   gedaempft (nicht die volle Sattheit), im Hellen als leichte Toenung. */
.recipe-cover-empty.has-cat{background:linear-gradient(190deg,color-mix(in srgb,var(--cat) 42%,#20201e),color-mix(in srgb,var(--cat) 13%,#141413));}
/* Hell, ohne Kategorie: ruhiger Grauverlauf (die Markenfarbe stach hier zu
   sehr heraus), dunkles Symbol. */
[data-theme="light"] .recipe-cover-empty,[data-theme="ocean"] .recipe-cover-empty,[data-theme="peach"] .recipe-cover-empty,[data-theme="forest"] .recipe-cover-empty,[data-theme="lavender"] .recipe-cover-empty,[data-theme="berry"] .recipe-cover-empty{background:linear-gradient(190deg,#ebe8e3,#b6b1a9);color:rgba(58,50,43,0.3);}
/* Hell, mit Kategorie: leichte Toenung in deren Farbe, helles Symbol. */
[data-theme="light"] .recipe-cover-empty.has-cat,[data-theme="ocean"] .recipe-cover-empty.has-cat,[data-theme="peach"] .recipe-cover-empty.has-cat,[data-theme="forest"] .recipe-cover-empty.has-cat,[data-theme="lavender"] .recipe-cover-empty.has-cat,[data-theme="berry"] .recipe-cover-empty.has-cat{background:linear-gradient(190deg,color-mix(in srgb,var(--cat) 15%,#fff),var(--cat));color:rgba(255,255,255,0.62);}
/* Verlauf unten, gross genug dass auch ein zweizeiliger Titel klar lesbar
   bleibt. Waechst mit dem Textkoerper (mehr Zeilen -> mehr Verlauf). */
.recipe-card-body{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:4rem 0.8rem 0.72rem;background:linear-gradient(to top,rgb(0 0 0 / 89%) 0%,rgb(0 0 0 / 60%) 28%,rgba(0,0,0,0.34) 52%,rgba(0,0,0,0.15) 76%,rgba(0,0,0,0.04) 90%,transparent 100%);}
.recipe-card-title{font-family:'Literata',Georgia,serif;font-size:0.95rem;font-weight:500;color:#fff;text-shadow:0 1px 4px rgba(0,0,0,0.55);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;line-height:1.3;letter-spacing:-0.002em;}
/* margin-top:auto statt fixem Abstand: die Zeile sitzt dadurch immer ganz
   unten in der Karte, auch wenn der Titel nur eine statt zwei Zeilen braucht. */
/* Links bei fremden Rezepten der Autor (Icon + Name), beim eigenen Rezept
   nur - falls geteilt - Teilen-Icon + Haushalte. Rechts die Bewertung.
   margin-top:auto pinnt die Zeile immer ans Kartenende, egal ob der Titel
   eine oder zwei Zeilen braucht. Nur die linke Seite darf schrumpfen/
   abschneiden, die Bewertung rechts bleibt immer vollstaendig sichtbar.
   Emoji bewusst ohne Kreis/Rahmen. */
/* min-height: die Zeile haengt per margin-top:auto am Kartenboden, ihre Hoehe
   richtet sich also nach oben. Ohne feste Hoehe war sie bei Karten MIT
   Bewertung 17px hoch (.star-row mit eigener Zeilenbox) und ohne Bewertung nur
   12,5px (.card-meta-emoji hat line-height:1) — dadurch sass das Emoji auf
   bewerteten Karten rund 7px hoeher als nebenan, und die ganze Kachel wirkte
   in der Zeile verschoben. Die Bilder waren davon nie betroffen. */
/* Zeile auf dem Verlauf: alles in hellen Toenen statt der --text*-Farben. */
.recipe-card-sub{font-size:0.76rem;color:rgba(255,255,255,0.82);margin-top:0.32rem;display:flex;align-items:center;justify-content:space-between;gap:0.4rem;min-width:0;}
.recipe-card-sub .card-meta-left{display:flex;align-items:center;gap:0.22rem;min-width:0;overflow:hidden;flex:1;}
.recipe-card-sub .card-meta-emoji{flex-shrink:0;font-size:0.78rem;line-height:1;}
.recipe-card-sub .card-meta-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;color:rgba(255,255,255,0.85);}
.recipe-card-sub .card-meta-share{flex-shrink:0;display:inline-flex;width:1rem;height:0.8rem;color:rgba(255,255,255,0.7);}
.recipe-card-sub .card-meta-share svg{display:block;width:100%;height:100%;}
.recipe-card-sub .card-meta-hh-icons{flex-shrink:0;font-size:0.76rem;line-height:1;}
.recipe-card-sub .star-row{display:inline-flex;align-items:center;gap:0.25rem;flex-shrink:0;}
.recipe-card-sub .star-compact{display:inline-flex;width:13px;height:13px;color:#ffd27a;}
.recipe-card-sub .star-compact svg{display:block;width:100%;height:100%;}
.recipe-card-sub .rating-avg{font-weight:700;color:#fff;}
.recipe-card-sub .rating-count{flex-shrink:0;color:rgba(255,255,255,0.72);}
.recipe-card-sub .rater-avatar{margin-left:0.15rem;}
.recipe-card-strip{position:absolute;left:0;right:0;bottom:0;z-index:3;height:5px;}
/* Rezept ohne Foto UND ohne Kategorie: ruhiger Ton statt Verlauf, dunkler
   Text statt hell — ein schwarzer Verlauf auf der hellen Flaeche saehe fremd
   aus. */
/* Frisch per Code eingeloestes Rezept kurzzeitig hervorheben — Rahmen pulsiert
   ein paar Mal, "Neu"-Badge blinkt leicht. Beides entfernt sich nach ein paar
   Sekunden von selbst (JS setzt highlightRecipeId zurueck + rendert neu). */
@keyframes card-new-pulse{0%,100%{box-shadow:0 0 0 0 color-mix(in srgb, var(--active-accent) 55%, transparent);}50%{box-shadow:0 0 0 5px color-mix(in srgb, var(--active-accent) 0%, transparent);}}
.recipe-card-new{border-color:var(--active-accent);animation:card-new-pulse 1.1s ease-out 3;}
@keyframes card-new-badge-blink{0%,100%{opacity:1;}50%{opacity:0.45;}}
.card-new-badge{position:absolute;top:6px;right:6px;z-index:2;background:var(--active-accent);color:var(--active-accent-text);font-size:0.65rem;font-weight:700;letter-spacing:0.03em;padding:2px 7px;border-radius:99px;animation:card-new-badge-blink 1s ease-in-out 3;}
/* Ein bisschen Magie beim frisch per Code eingeloesten Rezept: drei
   Funken poppen versetzt auf, drehen sich leicht und verblassen wieder.
   Innerhalb von .recipe-cover-wrap positioniert (nicht ausserhalb der
   Karte), weil .recipe-card selbst overflow:hidden hat und alles
   ausserhalb der Kante sonst abgeschnitten wuerde. */
@keyframes card-sparkle-pop{0%{opacity:0;transform:scale(0) rotate(-15deg);}35%{opacity:1;transform:scale(1.2) rotate(8deg);}100%{opacity:0;transform:scale(0.7) rotate(20deg) translateY(-6px);}}
.card-sparkle{position:absolute;z-index:2;pointer-events:none;font-size:1rem;opacity:0;animation:card-sparkle-pop 1.4s ease-out 1;filter:drop-shadow(0 0 3px color-mix(in srgb, var(--active-accent) 70%, transparent));}
.card-sparkle.s1{top:12%;left:8%;animation-delay:.05s;}
.card-sparkle.s2{bottom:14%;left:42%;font-size:0.8rem;animation-delay:.4s;}
.card-sparkle.s3{top:42%;right:10%;animation-delay:.22s;}

/* ── FAB ────────────────────────────────────────────────────── */
#fab{position:fixed;bottom:1.5rem;right:1.5rem;width:3.4rem;height:3.4rem;border-radius:50%;border:none;background:var(--rezept);color:var(--primary-text);font-size:1.7rem;line-height:1;cursor:pointer;box-shadow:0 6px 18px #0000002e;z-index:50;transition:transform .15s;}
@media(hover:hover){#fab:hover{transform:scale(1.06);}}

/* ── Modal ──────────────────────────────────────────────────── */
.modal-overlay{display:none;position:fixed;inset:0;background:var(--overlay);z-index:100;align-items:flex-start;justify-content:center;padding:1rem;overflow-y:auto;overscroll-behavior:contain;}
.modal-overlay.open{display:flex;}
/* Kompakte, themenkonforme Ja/Nein-Abfrage (Ersatz fuer natives confirm()). */
.confirm-overlay{align-items:center;z-index:300;}
.confirm-box{background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-xl);padding:1.3rem;max-width:340px;width:100%;margin:auto;box-shadow:var(--card-shadow,0 8px 30px #00000040);}
.confirm-box #confirm-message{font-size:0.9rem;line-height:1.45;color:var(--text);margin-bottom:1.1rem;white-space:pre-line;}
.confirm-actions{display:flex;gap:0.6rem;}
.confirm-actions button{flex:1;margin:0;}
@media(max-width:600px){.confirm-overlay .confirm-box{width:100%!important;max-width:340px!important;height:auto!important;border-radius:var(--r-lg)!important;border:1.5px solid var(--border)!important;}}
/* Wenn ein Modal offen ist: Hintergrund (Seite) nicht mehr mitscrollen/rubber-banden,
   damit man beim "Ziehen und Halten" am Rand nicht aus dem Modal heraus scrollt. */
html:has(.modal-overlay.open),body:has(.modal-overlay.open){overflow:hidden;height:100%;}
/* Ausnahme fuer den Rezept-Einstiegsbildschirm: dessen Bottom-Sheet zeigt den
   Hintergrund bewusst noch halb sichtbar (Fade-Animation) — die Sperre oben
   wirft dabei die Scrollposition der Bibliothek auf 0 zurueck (per Geraete-Test
   bestaetigt), sichtbar als kurzes "auf grau springen", bevor das Sheet
   fertig ist. Ein position:fixed-Body-Trick dagegen loeste auf Android ein
   eigenes Rendering-Problem aus (Hintergrund blieb waehrend offenem Modal
   komplett grau). Einfacher & zuverlaessiger: die Sperre hier schlicht nicht
   anwenden — der volle Overlay faengt Touches auf der abgedunkelten Flaeche
   ohnehin ab, echtes Durchscrollen zum Hintergrund ist dadurch nicht moeglich. */
html:has(#recipe-modal.step0-active.open),body:has(#recipe-modal.step0-active.open){overflow:visible;height:auto;}
.modal-box,.wizard-content{overscroll-behavior:contain;}
.modal-box{background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-xl);padding:1.5rem;max-width:540px;width:100%;max-height:90vh;overflow-y:auto;position:relative;margin:auto;box-shadow:var(--card-shadow,none);}
@media(max-width:600px){
  .modal-overlay.open{padding:0;align-items:stretch;}
  /* 100dvh = dynamische Viewport-Höhe: berücksichtigt ein-/ausblendende Handy-
     Toolbars, damit das Modal exakt den sichtbaren Bereich füllt und die
     Wizard-Buttons wirklich am unteren Rand kleben. */
  .modal-box{width:100%!important;max-width:none!important;height:100dvh!important;max-height:none!important;border-radius:0!important;border:none!important;box-shadow:none!important;margin:0!important;}
}
.modal-box h2{font-size:1.2rem;font-weight:500;margin-bottom:1.1rem;color:var(--rezept);}
.step-indicator{font-size:0.78rem;color:var(--text-sub);letter-spacing:0;text-transform:none;margin-top:-0.6rem;margin-bottom:1rem;}
.wizard-footer{position:sticky;bottom:-1.5rem;margin:0.8rem -1.5rem -1.5rem;padding:0.8rem 1.5rem calc(1.5rem + env(safe-area-inset-bottom,0px));background:var(--surface);border-top:1px solid var(--border);}
.wizard-footer .btn-primary,.wizard-footer .btn-sec{margin-top:0;margin-bottom:0;}
.wizard-msg{font-size:0.82rem;text-align:center;min-height:0;color:var(--text-sub);}
.wizard-msg:not(:empty){margin-bottom:0.7rem;}
#recipe-step0,#recipe-import-step,#recipe-rotate-step,#recipe-step1,#recipe-step2,#recipe-step3{flex-direction:column;min-height:0;}
@media(max-width:600px){
  /* padding-bottom:0 → der Footer (mit eigenem unteren Padding inkl. Safe-Area)
     sitzt bündig am unteren Bildschirmrand statt 24px darüber zu schweben. */
  #recipe-modal .modal-box{display:flex;flex-direction:column;overflow-y:hidden;padding-bottom:0;}
  #recipe-step0,#recipe-import-step,#recipe-rotate-step,#recipe-step1,#recipe-step2,#recipe-step3{flex:1;min-height:0;}
  .wizard-content{flex:1;min-height:0;overflow-y:auto;}
  /* Inneren Scrollbalken ausblenden (z.B. wenn der Import-Bereich aufklappt) —
     der Inhalt scrollt weiterhin, nur ohne sichtbare Leiste. */
  .wizard-content{scrollbar-width:none;-ms-overflow-style:none;}
  .wizard-content::-webkit-scrollbar{display:none;}
  .wizard-footer{position:static;flex-shrink:0;margin:0.8rem -1.5rem 0;}
  /* leere Meldungszeile darf unter dem Footer keinen Platz einnehmen */
  #recipe-msg{flex-shrink:0;min-height:0;margin-top:0;}
}
/* Der Einstiegsbildschirm ("Wie möchtest du starten?") ist kein langes
   Formular wie die anderen Wizard-Schritte — statt der vollen 100dvh-Seite
   bekommt er ein content-großes Bottom-Sheet, das nur so hoch reicht wie die
   3 Karten. Faehrt beim Oeffnen von unten hoch (Transform-Transition, per
   rAF in showRecipeScreen() ausgeloest, siehe .sheet-enter unten), damit
   alle 3 Karten sofort mit dem Daumen erreichbar sind, ohne die zweite Hand
   zum Scrollen zu brauchen. */
@media(max-width:600px){
  /* Der dunkle Scrim hinter dem Sheet wurde bisher rein durch den
     display:none->flex-Sprung sichtbar (kein transition moeglich) — auf dem
     Handy kam er dadurch spuerbar NACH dem fertig hochgefahrenen Sheet an
     (Video-Analyse: Sheet bei ~0.15s fertig, Scrim erst bei ~0.3s ploetzlich
     dunkel), vermutlich weil die eigene GPU-Layer-Promotion der Box (wegen
     ihrer transform-Transition) den Hintergrund-Repaint des Elternelements
     ausbremst. Jetzt bekommt der Scrim dieselbe Transition/denselben
     .sheet-enter-Start wie die Box, damit beides sichtbar synchron laeuft. */
  #recipe-modal.step0-active{
    transition:background-color .28s cubic-bezier(0.22,1,0.36,1);
  }
  #recipe-modal.step0-active.sheet-enter{background-color:transparent;}
  #recipe-modal.step0-active .modal-box{
    height:auto!important;max-height:85dvh!important;overflow-y:auto;
    align-self:flex-end;border-radius:var(--r-lg) var(--r-lg) 0 0!important;
    padding-bottom:calc(1.5rem + env(safe-area-inset-bottom,0px));
    /* Reines Ease-out ohne jegliches Ueberschwingen (keine y-Kontrollpunkte
       ausserhalb [0,1]) — bewusst kein "Spring"/Bounce-Feeling. */
    transition:transform .28s cubic-bezier(0.22,1,0.36,1);transform:translateY(0);
  }
  /* Start-Zustand fuer die Hochfahr-Animation: eine rAF-Runde in
     showRecipeScreen() entfernt diese Klasse wieder, sobald der Sheet-Rand
     sicher unterhalb des Bildschirms gemalt wurde. */
  #recipe-modal.step0-active.sheet-enter .modal-box{transform:translateY(100%);}
  #recipe-modal.step0-active #recipe-step0{flex:none;}
  #recipe-modal.step0-active .wizard-content{flex:none;overflow-y:visible;}
}
.modal-close{position:absolute;top:0.9rem;right:1rem;background:none;border:none;color:var(--text-sub);font-size:1.3rem;cursor:pointer;}
/* Rechts Platz fuer das absolut positionierte X reservieren — ohne den
   Puffer kann der Titeltext bis unter den Schliessen-Button laufen, weil das
   X selbst keinen Raum im normalen Textfluss beansprucht. */
#detail-title{overflow-wrap:break-word;padding-right:2rem;}

/* ── Formularfelder ─────────────────────────────────────────── */
.field{margin-bottom:0.9rem;position:relative;}
.field label{display:block;font-size:0.78rem;font-weight:600;color:var(--text);margin-bottom:0.3rem;letter-spacing:0;text-transform:none;}
.field input,.field textarea{width:100%;background:var(--field);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.6rem 0.8rem;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.9rem;outline:none;transition:border-color .2s;}
.field select,select{width:100%;background:var(--field);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.6rem 2.2rem 0.6rem 0.8rem;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.9rem;outline:none;transition:border-color .2s;cursor:pointer;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='%238895b3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 8l4 4 4-4'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 0.7rem center;background-size:0.7rem;}
/* Native Auswahl-Liste (vom OS gerendert) an Hell/Dunkel des Themes koppeln —
   mehr laesst sich am aufgeklappten Systemdialog nicht beeinflussen. */
select option{background:var(--surface);color:var(--text);}
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;appearance:textfield;}
.input-suffix-wrap{position:relative;}
.input-suffix-wrap input{padding-right:2.6rem;}
.input-suffix{position:absolute;right:0.8rem;top:50%;transform:translateY(-50%);color:var(--text-sub);font-size:0.85rem;pointer-events:none;}
/* Die Einheit am Zeitfeld ist ein Schalter: ein Tipp stellt zwischen Minuten
   und Stunden um und rechnet den Wert mit (zeitEinheitUmschalten in
   recipes.js). Alle anderen Suffixe bleiben reine Beschriftung — deren
   pointer-events:none oben sorgt dafuer, dass ein Tipp daneben weiterhin ins
   Feld fuehrt statt ins Leere.
   right kleiner als beim span + gleich grosses padding: die Schrift steht an
   derselben Stelle wie vorher, die antippbare Flaeche ist aber deutlich
   groesser als die vier Buchstaben. */
button.input-suffix{
  pointer-events:auto;cursor:pointer;right:0.55rem;
  background:none;border:none;padding:0.25rem;margin:0;
  font-family:inherit;font-size:0.85rem;line-height:1;color:var(--rezept);
  border-radius:var(--r-sm);
  text-decoration:underline;text-decoration-style:dotted;text-underline-offset:2px;
}
@media(hover:hover){button.input-suffix:hover{background:var(--surface2);}}
.field textarea{resize:vertical;min-height:3rem;}
.field input:focus,.field textarea:focus,.field select:focus{border-color:var(--rezept);}
/* Naehrwerte: Bezugsgroesse als Zweier-Wahl, damit klar ist, worauf sich die
   Zahlen beziehen. */
.nutri-basis{display:flex;gap:0.4rem;margin-top:0.6rem;}
.nutri-basis-btn{flex:1;padding:0.4rem 0.5rem;border-radius:var(--r-md);border:1.5px solid var(--border);background:transparent;color:var(--text-sub);font-size:0.78rem;font-weight:600;cursor:pointer;transition:all .15s;}
.nutri-basis-btn.active{border-color:var(--rezept);color:var(--rezept);}
.more-times{margin-bottom:0.9rem;}
.more-times>summary{font-size:0.82rem;color:var(--text-sub);cursor:pointer;padding:0.35rem 0;list-style:none;user-select:none;}
.more-times>summary::-webkit-details-marker{display:none;}
.more-times-hint{font-size:0.75rem;color:var(--text-sub);margin:0.3rem 0 0.1rem;}
.more-times-grid{display:grid;grid-template-columns:1fr 1fr;gap:0.6rem;margin-top:0.4rem;}
#f-preptime:disabled{opacity:0.7;cursor:not-allowed;}
.row2{display:flex;gap:0.6rem;flex-wrap:wrap;}
.cat-grid{display:flex;flex-wrap:wrap;gap:0.35rem;align-items:center;}

.btn-primary{width:100%;padding:0.65rem;border-radius:var(--r-md);border:none;font-size:0.92rem;font-weight:700;cursor:pointer;background:var(--primary);color:var(--primary-text);transition:opacity .2s;margin-top:0.3rem;}
@media(hover:hover){.btn-primary:hover{opacity:0.88;}}
.btn-sec{width:100%;padding:0.55rem;border-radius:var(--r-md);border:1.5px solid transparent;background:var(--surface2);color:var(--text-sub);font-size:0.85rem;font-weight:600;cursor:pointer;margin-top:0.5rem;}
.row2 .btn-sec{width:auto;flex:1;min-width:0;}
.row2 .btn-primary{width:auto;flex:1;min-width:0;}
@media(hover:hover){.btn-sec:hover{border-color:var(--rezept);color:var(--rezept);}}
/* Dritter Knopfstil zwischen den beiden: Umriss in der Akzentfarbe. Fuer
   Aktionen, die auf einer Karte klar erkennbar sein muessen, aber nicht DIE
   eine Handlung der Seite sind — drei gefuellte btn-primary untereinander
   knallen, drei btn-sec verschwinden auf der Karte. Gebaut wie .btn-del, das
   dasselbe fuer die Warnfarbe macht. */
.btn-accent{width:100%;padding:0.55rem;border-radius:var(--r-md);border:1.5px solid var(--rezept);background:transparent;color:var(--rezept);font-size:0.85rem;font-weight:600;cursor:pointer;margin-top:0.5rem;}
@media(hover:hover){.btn-accent:hover{background:var(--rezept);color:var(--primary-text);}}
.btn-link-sec{display:inline-block;background:none;border:none;color:var(--text-sub);font-size:0.78rem;font-weight:600;cursor:pointer;padding:0.4rem 0.2rem;margin:0.6rem 0 0;}
@media(hover:hover){.btn-link-sec:hover{color:var(--rezept);}}

/* ── Neues Rezept: Manuell/Import-Auswahl ─────────────────────── */
.entry-lead{font-size:0.85rem;color:var(--text-sub);margin-bottom:1rem;}
.entry-choice{display:flex;align-items:center;gap:0.8rem;width:100%;text-align:left;padding:0.9rem 1rem;border-radius:var(--r-md);border:1.5px solid var(--border);background:none;color:var(--text);cursor:pointer;transition:border-color .15s;margin-bottom:0.7rem;}
@media(hover:hover){.entry-choice:hover{border-color:var(--rezept);}}
.entry-choice-icon{flex-shrink:0;display:flex;align-items:center;color:var(--rezept);}
.entry-choice strong{font-size:0.92rem;color:var(--text);}
.entry-choice span:last-child{font-size:0.78rem;color:var(--text-sub);line-height:1.4;}
.btn-del{width:100%;padding:0.55rem;border-radius:var(--r-md);border:1.5px solid var(--err-border);background:transparent;color:var(--err-text);font-size:0.82rem;font-weight:600;cursor:pointer;margin-top:0.6rem;}
@media(hover:hover){.btn-del:hover{background:var(--err);}}
/* Loeschen in der Detailansicht: bewusst klein und unauffaellig, damit es nicht
   neben den normalen Aktionen steht — der Klick fragt zusaetzlich nach. */
.detail-del-btn{display:block;margin:1.4rem auto 0.2rem;padding:0.35rem 0.7rem;border:none;border-radius:var(--r-md);background:transparent;color:var(--text-sub);font-size:0.74rem;font-weight:600;opacity:0.65;cursor:pointer;}
@media(hover:hover){.detail-del-btn:hover{opacity:1;color:var(--err-text);}}
.modal-msg{margin-top:0.7rem;font-size:0.8rem;text-align:center;min-height:1rem;}

/* ── Fotos ──────────────────────────────────────────────────── */
/* padding, damit die überstehenden Ecken-Buttons (Titelbild-Stern, Entfernen)
   nicht vom scrollenden Container abgeschnitten werden */
.photo-grid{display:flex;flex-wrap:wrap;gap:0.55rem;padding:6px;}
.photo-thumb-wrap{position:relative;width:36px;height:36px;flex-shrink:0;}
.photo-thumb-wrap img,.photo-thumb{width:100%;height:100%;object-fit:cover;border-radius:var(--r-xs);border:1px solid var(--border);cursor:pointer;}
.photo-thumb-remove,.photo-remove{position:absolute;top:-4px;right:-4px;width:1rem;height:1rem;border-radius:50%;border:none;background:var(--err);color:var(--err-text);font-size:0.6rem;cursor:pointer;display:flex;align-items:center;justify-content:center;line-height:1;}
.photo-cover-btn{position:absolute;bottom:-4px;left:-4px;width:1.05rem;height:1.05rem;border-radius:50%;border:1px solid var(--border);background:var(--field);color:var(--text-sub);font-size:0.6rem;cursor:pointer;display:flex;align-items:center;justify-content:center;line-height:1;}
.photo-cover-btn.active{background:var(--active-accent);color:#fff;border-color:var(--active-accent);}
/* Schritt-Nummer auf zugeordneten Fotos: die erscheinen nur beim Schritt,
   nicht in der Titelbild-Galerie. */
.photo-step-badge{position:absolute;top:-5px;left:-5px;min-width:1rem;height:1rem;padding:0 0.22rem;border-radius:99px;background:var(--active-accent);color:#fff;font-size:0.58rem;font-weight:700;display:flex;align-items:center;justify-content:center;line-height:1;font-variant-numeric:tabular-nums;z-index:1;}
.photo-thumb-wrap.is-step-photo img{opacity:0.78;}
.photo-grid-hint{font-size:0.72rem;color:var(--text-sub);line-height:1.4;margin:0.5rem 0.1rem 0;}
.photo-grid-hint svg{color:var(--active-accent);}
.photo-add-tile,.photo-add-btn{width:36px;height:36px;flex-shrink:0;border:1.5px dashed var(--border);border-radius:var(--r-xs);background:transparent;color:var(--text-sub);cursor:pointer;font-size:1rem;display:flex;align-items:center;justify-content:center;transition:all .15s;}
@media(hover:hover){.photo-add-tile:hover,.photo-add-btn:hover{border-color:var(--rezept);color:var(--rezept);}}
/* Fotos im Editor (eigene + von Nachkochern) um das 1,5-fache groesser als
   sonstige Foto-Thumbs — sonst ist der Titelbild-Stern kaum zu treffen. */
#recipe-photo-grid .photo-thumb-wrap,
#editor-nachkocher-grid .photo-thumb-wrap{width:54px;height:54px;}
#recipe-photo-grid .photo-add-tile{width:54px;height:54px;}
#recipe-photo-grid .photo-cover-btn,
#editor-nachkocher-grid .photo-cover-btn{width:1.4rem;height:1.4rem;font-size:0.8rem;}
#recipe-photo-grid .photo-thumb-remove{width:1.3rem;height:1.3rem;font-size:0.78rem;}
.photo-row{display:flex;gap:0.55rem;flex-wrap:wrap;padding:6px;}
/* Wisch-Galerie im Titelbild: ein scroll-snap-Streifen aller Fotos, statt
   einer Miniaturenreihe im Textblock. Jede Kachel ist ein eigener Wrapper
   (overflow:hidden), damit das leichte Hochskalieren des Bildes gegen
   eingebrannte Wasserzeichen die Nachbarn nicht ueberlappt. */
.detail-cover-track{display:flex;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:none;-ms-overflow-style:none;height:12rem;cursor:zoom-in;}
.detail-cover-track::-webkit-scrollbar{display:none;}
.detail-cover-track>.cover-slide{flex:0 0 100%;height:100%;scroll-snap-align:center;overflow:hidden;}
.detail-cover-track img{width:100%;height:100%;object-fit:cover;object-position:center 40%;display:block;user-select:none;-webkit-user-drag:none;transform:scale(1.08);transform-origin:center top;}
.detail-cover-dots{position:absolute;left:0;right:0;bottom:0.55rem;display:flex;justify-content:center;gap:0.3rem;z-index:3;pointer-events:none;}
.detail-cover-dots:empty{display:none;}
.detail-cover-dots span{width:0.4rem;height:0.4rem;border-radius:99px;background:#ffffff8c;box-shadow:0 0 3px #0006;transition:width .2s,background .2s;pointer-events:auto;cursor:pointer;}
.detail-cover-dots span.on{width:1.1rem;background:#fff;}
/* Pfeile: nur am PC (feiner Zeiger) und nur bei mehreren Fotos — auf dem
   Handy wird gewischt. */
.detail-cover-nav{position:absolute;top:50%;transform:translateY(-50%);z-index:3;width:2rem;height:2rem;border-radius:50%;border:none;background:#00000073;color:#fff;display:none;align-items:center;justify-content:center;cursor:pointer;padding:0;}
.detail-cover-prev{left:0.5rem;}
.detail-cover-next{right:0.5rem;}
@media(hover:hover) and (pointer:fine){
  #detail-cover-wrap.has-multi .detail-cover-nav{display:flex;}
}

/* ── Zutaten / Schritte (Editor) ────────────────────────────── */
#ingredient-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:0.3rem 0.8rem;align-items:start;}
.ing-row{display:flex;flex-wrap:wrap;gap:0.4rem;align-items:center;margin-bottom:0.4rem;}
/* Hinweis-Feld liegt in derselben Zeilen-Box, springt per flex-basis auf eine
   zweite Zeile — so bleiben data-idx, Drag und ✕-Selektoren unveraendert. */
.ing-note-btn{background:none;border:none;color:var(--text-sub);cursor:pointer;flex-shrink:0;padding:0.2rem 0.25rem;display:flex;align-items:center;opacity:0.6;transition:opacity .15s,color .15s;}
@media(hover:hover){.ing-note-btn:hover{opacity:1;color:var(--rezept);}}
.ing-note-btn.active{opacity:1;color:var(--rezept);}
/* Kursiv wie ueberall sonst, wo ein Hinweis steht (.ing-note-hint,
   .detail-step-note, .ir-ing-note im Pruefschritt) — sonst sieht das Feld im
   normalen Editor aus wie ein zweites Namensfeld statt wie eine Zusatzinfo. */
.ing-note-input{flex-basis:100%;width:100%;order:9;background:var(--field);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.45rem 0.7rem;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.82rem;font-style:italic;outline:none;}
.ing-note-input:focus{border-color:var(--rezept);}
/* Hinweis in der Detailansicht: dezent hinter dem Namen. */
.ing-note-hint{color:var(--text-sub);font-size:calc(0.78rem * var(--detail-zoom, 1));font-style:italic;margin-left:0.4rem;}
.ing-row:not(.filled) .ing-amount-unit,.ing-row:not(.filled) .ing-name{border-style:dashed;}
.ing-section-row{grid-column:1/-1;display:flex;gap:0.4rem;align-items:center;margin:0.5rem 0 0.1rem;}
/* Zwischenüberschrift in der SCHRITT-Liste: erbt .step-row (Nummernspalte,
   Aktionsspalte rechts) — dadurch exakt gleich breit wie die Schritte. */
.step-row.step-section-row{align-items:center;margin-top:1rem;margin-bottom:0.55rem;}
#step-list > .step-section-row:first-child{margin-top:0;}
.step-section-row .step-num{padding-top:0;}
/* Linke Polsterung wie beim Schritt-Textfeld (Rahmen + 0.7rem), damit der
   Überschriftentext bündig mit dem Schritt-Text darunter beginnt statt an
   der Kastenkante zu kleben. */
.step-section-row .ing-section-input{padding:0.3rem 0.1rem 0.3rem 0.8rem;}
.ing-section-input{flex:1;min-width:0;font-weight:700;color:var(--rezept);background:transparent;border:none;border-bottom:1.5px solid var(--border);padding:0.3rem 0.1rem;font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.9rem;outline:none;}
.ing-section-input:focus{border-bottom-color:var(--rezept);}
.ing-name{flex:1;min-width:0;background:var(--field);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.6rem 0.8rem;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.9rem;outline:none;transition:border-color .2s;}
.ing-name:focus{border-color:var(--rezept);}
.ing-name-label{flex:1;min-width:0;font-size:0.85rem;color:var(--text);}
.ing-amount-unit{display:flex;align-items:stretch;flex-shrink:0;border:1.5px solid var(--border);border-radius:var(--r-md);overflow:hidden;background:var(--field);transition:border-color .2s;}
.ing-amount-unit:focus-within{border-color:var(--rezept);}
.ing-amount-unit .ing-amount{width:3.2rem;flex:none;border:none;background:transparent;text-align:right;border-radius:0;padding:0.6rem 0.3rem;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.9rem;outline:none;}
.ing-amount-unit .ing-unit{flex:none;width:4rem;border:none;border-left:1.5px solid var(--border);border-radius:0;background-color:var(--surface);color:var(--active-accent);font-weight:600;padding:0.6rem 1.3rem 0.6rem 0.4rem;background-position:right 0.35rem center;background-size:0.6rem;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;}
.ing-remove{background:none;border:none;color:var(--text-sub);cursor:pointer;font-size:0.9rem;flex-shrink:0;padding:0.2rem 0.3rem;}
@media(hover:hover){.ing-remove:hover{color:var(--err-text);}}
.step-row{display:flex;gap:0.45rem;align-items:flex-start;margin-bottom:1.1rem;}
.step-num{font-family:'Literata',Georgia,serif;font-weight:600;font-size:1rem;color:var(--text-sub);flex-shrink:0;padding-top:0.55rem;min-width:1.15rem;text-align:right;}
.step-row textarea{flex:1;min-width:0;background:var(--field);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.5rem 0.7rem;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.9rem;outline:none;resize:none;overflow:hidden;}
.step-row textarea:focus{border-color:var(--rezept);}
/* Leerer Schritt: gestrichelter Rand wie bei einer leeren Zutat. */
.step-row:not(.filled) textarea{border-style:dashed;}
.step-actions{display:flex;flex-direction:column;gap:0.15rem;flex-shrink:0;}
.step-actions button{width:1.6rem;height:1.6rem;border-radius:var(--r-xs);border:1.5px solid var(--border);background:transparent;color:var(--text-sub);cursor:pointer;font-size:0.75rem;}
@media(hover:hover){.step-actions button:hover:not(:disabled){border-color:var(--rezept);color:var(--rezept);}}
.step-actions button:disabled{opacity:0.35;cursor:default;}
/* Hinweis-Taste und Entfernen wie bei den Zutaten ohne Rahmen — nur die
   Pfeile (Reihenfolge aendern) behalten den Rahmen-Look. */
.step-actions button.step-note-btn,.step-actions button.step-remove{border:none;}
.step-note-btn{display:inline-flex;align-items:center;justify-content:center;opacity:0.6;transition:opacity .15s,color .15s;}
@media(hover:hover){.step-note-btn:hover{opacity:1;}}
.step-note-btn.active{opacity:1;color:var(--rezept);}
.step-note-input{display:block;width:100%;margin-top:0.6rem;background:var(--field);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.45rem 0.7rem;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.82rem;font-style:italic;outline:none;resize:none;overflow:hidden;}
.step-note-input:focus{border-color:var(--rezept);}
.step-ing-zone{display:flex;flex-wrap:wrap;gap:0.3rem;align-items:center;margin-top:0.4rem;}
.step-ing-chip{font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.72rem;padding:0.15rem 0.55rem;border-radius:var(--r-md);border:1px dashed var(--border);background:transparent;color:var(--text-sub);cursor:pointer;transition:all .15s;}
@media(hover:hover){.step-ing-chip:hover{border-color:var(--active-accent);color:var(--active-accent);}}
.step-ing-chip.active{border:1px solid var(--active-accent);background:var(--active-accent);color:var(--active-accent-text);}
/* bereits einem anderen Schritt zugeordnet — gedämpft, aber weiterhin wählbar */
.step-ing-chip.assigned{opacity:0.4;text-decoration:line-through;border-style:solid;}
@media(hover:hover){.step-ing-chip.assigned:hover{opacity:0.75;text-decoration:none;}}
/* Fotos einem Schritt zuordnen — gleiche Idee wie step-ing-zone, aber als
   kleine anklickbare Thumbnails statt Text-Chips. */
.step-photo-zone{display:flex;flex-wrap:wrap;gap:0.3rem;align-items:center;margin-top:0.4rem;}
.step-photo-chip{width:2.4rem;height:2.4rem;flex-shrink:0;padding:0;border-radius:99px;border:1.5px dashed var(--border);background:transparent;cursor:pointer;overflow:hidden;transition:all .15s;}
.step-photo-chip img{width:100%;height:100%;object-fit:cover;display:block;}
@media(hover:hover){.step-photo-chip:hover{border-color:var(--active-accent);}}
.step-photo-chip.active{border:2px solid var(--active-accent);}
.step-photo-chip.assigned{opacity:0.4;}
@media(hover:hover){.step-photo-chip.assigned:hover{opacity:0.75;}}

/* ── Zutaten sortieren (Drag & Drop) ────────────────────────── */
#sort-ingredients-list{position:relative;}
.sort-row{display:flex;align-items:center;gap:0.6rem;padding:0.55rem 0.7rem;background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-md);margin-bottom:0.4rem;}
.sort-row.dragging{border-color:var(--rezept);box-shadow:0 8px 20px #0007;cursor:grabbing;}
.sort-handle{cursor:grab;color:var(--text-sub);font-size:1.2rem;flex-shrink:0;user-select:none;touch-action:none;line-height:1;padding:0.2rem 0.3rem;}
.sort-label{flex:1;min-width:0;font-size:0.85rem;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.sort-amount{flex-shrink:0;font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.78rem;color:var(--text-sub);font-variant-numeric:tabular-nums;}
.sort-row.sort-section-row{background:var(--surface);border-color:var(--rezept);}
.sort-label.sort-section-label{font-weight:700;color:var(--rezept);flex:1;}

/* ── Sterne-Bewertung ───────────────────────────────────────── */
.star-picker{display:inline-flex;gap:0.1rem;}
.star-btn{background:none;border:none;font-size:1.15rem;color:var(--border);cursor:pointer;padding:0.1rem;line-height:1;}
.star-btn.filled{color:var(--star);}
.star-row{display:inline-flex;gap:0.1rem;vertical-align:middle;}
.star-wrap{position:relative;display:inline-block;width:15px;height:15px;line-height:1;}
.star-wrap svg{display:block;}
.star-wrap .star-bg{color:var(--star-empty,var(--border));}
.star-wrap .star-fg{position:absolute;left:0;top:0;overflow:hidden;color:var(--star);}
.rating-input-row{display:flex;align-items:center;gap:0.5rem;margin-bottom:0.4rem;flex-wrap:nowrap;}
/* Dropdown nur so breit wie nötig — vorher streckte flex:1 es über die ganze
   Zeile und schob die Sterne ganz nach rechts. */
.rating-input-row select{flex:0 1 auto;width:auto;min-width:0;max-width:11rem;padding:0.45rem 1.8rem 0.45rem 0.6rem;font-size:0.85rem;background-position:right 0.5rem center;text-overflow:ellipsis;}
.rating-input-row .star-picker{flex-shrink:0;}
.rating-self-label{font-size:1.1rem;line-height:1;}
.rating-remove{background:none;border:none;color:var(--text-sub);cursor:pointer;font-size:0.9rem;}
@media(hover:hover){.rating-remove:hover{color:var(--err-text);}}
.rating-count{color:var(--text-sub);font-weight:400;}

/* ── Portionen-Stepper ──────────────────────────────────────── */
/* Gemeinsame Zeile: Portionen-Stepper links, Schriftgrößen-Regler rechts,
   beide auf gleicher Höhe. */
.detail-servings-row{display:flex;align-items:center;justify-content:space-between;gap:0.6rem;margin-bottom:0.9rem;}
.servings-stepper{display:inline-flex;align-items:center;gap:0;background:var(--field);border:1.5px solid var(--border);border-radius:var(--r-sm);padding:0.25rem;}
.servings-stepper button{width:1.9rem;height:1.9rem;border-radius:var(--r-xs);border:none;background:transparent;color:var(--text);cursor:pointer;font-size:1.05rem;font-weight:600;}
@media(hover:hover){.servings-stepper button:hover{background:var(--surface);color:var(--rezept);}}
.servings-stepper input{width:3.2rem;text-align:center;background:transparent;border:none;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:1.05rem;font-weight:700;padding:0;font-variant-numeric:tabular-nums;}

/* Schriftgrößen-Regler für Zutaten/Schritte im Rezept-Detail — auf Höhe des
   Portionen-Reglers, rechts daneben, gleiche Zellengröße. Steuert
   --detail-zoom, worüber die entsprechenden font-size-Regeln skaliert werden. */
.detail-zoom-row{display:inline-flex;align-items:center;gap:0.1rem;background:var(--field);border:1.5px solid var(--border);border-radius:var(--r-sm);padding:0.25rem;flex-shrink:0;}
.detail-zoom-row button{width:1.9rem;height:1.9rem;border-radius:var(--r-xs);border:none;background:transparent;color:var(--text);cursor:pointer;font-size:1.05rem;font-weight:600;}
@media(hover:hover){.detail-zoom-row button:hover:not(:disabled){background:var(--surface);color:var(--rezept);}}
.detail-zoom-row button:disabled{opacity:0.35;cursor:default;}
.detail-zoom-icon{display:flex;align-items:center;justify-content:center;width:1.9rem;height:1.9rem;color:var(--text-sub);}

/* ── Präferenzen ────────────────────────────────────────────── */
/* Wie beim Wizard: Inhalt scrollt, Buttons kleben unten — die Lebensmittel-
   Liste ist lang, ohne das wäre Speichern am Handy nicht erreichbar. */
#prefs-modal .modal-box,#prefs-check-modal .modal-box,#member-modal .modal-box{display:flex;flex-direction:column;overflow-y:hidden;padding-bottom:0;}
#prefs-content,#prefs-check-body,#mp-body{flex:1;min-height:0;overflow-y:auto;}
#prefs-modal .wizard-footer,#prefs-check-modal .wizard-footer,#member-modal .wizard-footer{position:static;flex-shrink:0;margin:0.8rem -1.5rem 0;}
/* Der Kopf mit Avatar und Name bleibt beim Scrollen stehen. */
#member-modal .mp-head{flex-shrink:0;}

.pf-prefs-btn{display:flex;align-items:center;justify-content:space-between;gap:0.6rem;width:100%;text-align:left;padding:0.6rem 0.8rem;border-radius:var(--r-md);border:1.5px solid var(--border);background:var(--field);color:var(--text);font-size:0.85rem;cursor:pointer;transition:border-color .15s;}
@media(hover:hover){.pf-prefs-btn:hover{border-color:var(--rezept);}}
.pf-prefs-chevron{color:var(--text-sub);font-size:1.1rem;line-height:1;flex-shrink:0;}

.pref-group{margin-bottom:0.9rem;}
.pref-group summary{cursor:pointer;font-size:0.8rem;font-weight:600;color:var(--rezept);padding:0.4rem 0;list-style:none;}
.pref-group summary::-webkit-details-marker{display:none;}
.pref-group.disabled summary{color:var(--text-sub);}
.pref-group-hint{font-size:0.75rem;color:var(--text-sub);font-style:italic;margin:0 0 0.4rem;}
/* Haken und Wort mittig zueinander statt ueber vertical-align zurechtgerueckt:
   der Haken ragte sonst deutlich ueber die Oberkante der Schrift hinaus (13 px
   Icon neben 0,62rem Text). Der Abstand kommt aus gap — ein Leerzeichen im
   Text wuerde als erstes Flex-Kind weggeschnitten. */
.pref-complete-tag{display:inline-flex;align-items:center;gap:0.2rem;font-size:0.62rem;font-weight:700;color:var(--done-text);border:1px solid var(--done-border);border-radius:99px;padding:0.05rem 0.35rem;margin-left:0.35rem;vertical-align:middle;}
.pref-complete-tag.partial{color:var(--star);border-color:var(--star);}
/* Legende einmal ganz oben statt in jeder Kategorie wiederholt — nutzt die
   volle Zeilenbreite (Icon+Label nebeneinander je Stufe), statt in die
   schmalen Bewertungs-Spalten gequetscht zu werden. */
/* Bewusst nowrap: die vier Stufen gehören in EINE Zeile, ein Umbruch nach
   "neutral" liest sich wie zwei getrennte Gruppen. Linksbündig und in der
   Schriftgröße von .pf-note, damit die Legende zur erklärenden Zeile darüber
   gehört statt als eigene Spaltenbeschriftung zu wirken. */
.pref-legend{display:flex;flex-wrap:nowrap;justify-content:flex-start;gap:0.7rem;margin-bottom:0.7rem;padding-bottom:0.6rem;border-bottom:1px solid var(--border);}
.pref-legend span{display:flex;align-items:center;gap:0.3rem;min-width:0;}
.pref-legend span img{width:1.45rem;height:1.45rem;display:block;flex-shrink:0;}
.pref-legend span small{font-size:0.78rem;color:var(--text-sub);white-space:nowrap;}
/* Nach unten nur Icon und Abstände verkleinern — die Schriftgröße bleibt an
   .pf-note gekoppelt. Erst unter 356px reicht die Breite dafür nicht mehr. */
@media(max-width:420px){
  .pref-legend{gap:0.4rem;}
  .pref-legend span{gap:0.22rem;}
  .pref-legend span img{width:1.25rem;height:1.25rem;}
}
@media(max-width:355px){
  .pref-legend{gap:0.25rem;}
  .pref-legend span{gap:0.16rem;}
  .pref-legend span img{width:1.05rem;height:1.05rem;}
  .pref-legend span small{font-size:0.7rem;}
}
.pref-row{display:flex;align-items:center;gap:0.5rem;padding:0.25rem 0;border-bottom:1px solid var(--border);}
.pref-row:last-child{border-bottom:none;}
.pref-name{flex:1;min-width:0;font-size:0.84rem;overflow-wrap:break-word;}
.pref-scale{display:flex;gap:0.15rem;flex-shrink:0;}
/* Unausgewählt bewusst nur Graustufen-Icon ohne Button-Rahmen/Hintergrund —
   ausgewählt wird per Farbe sichtbar, nicht per Box drumherum. */
.pref-dot{width:2.3rem;height:2.1rem;border-radius:var(--r-md);border:none;background:transparent;cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center;transition:background .12s;}
.pref-dot img{width:1.6rem;height:1.6rem;display:block;filter:grayscale(1);opacity:0.45;transition:filter .12s,opacity .12s,transform .12s;}
@media(hover:hover){.pref-dot:hover{background:var(--surface);}}
@media(hover:hover){.pref-dot:hover img{opacity:0.8;}}
.pref-dot.on img{filter:none;opacity:1;transform:scale(1.15);}
.pref-dot:disabled{cursor:not-allowed;}
@media(hover:hover){.pref-dot:disabled:hover{background:transparent;}}
.pref-dot:disabled img{opacity:0.22;}
/* 2rem breite Stufen passen auch auf 375px ohne horizontales Scrollen und sind
   als Berührungsziel angenehmer als eine schmalere Sonderregel fürs Handy. */

/* Ergebnis der Rezept-Prüfung */
.pc-member{border:1.5px solid var(--border);border-radius:var(--r-lg);padding:0.6rem 0.75rem;margin-bottom:0.6rem;background:var(--surface);}
.pc-head{display:flex;align-items:center;gap:0.5rem;}
.pc-avatar{font-size:1.2rem;flex-shrink:0;}
.pc-name{font-weight:700;font-size:0.88rem;flex:1;min-width:0;}
.pc-badge{font-size:0.62rem;font-weight:700;text-transform:uppercase;letter-spacing:0.04em;border-radius:99px;padding:0.1rem 0.4rem;flex-shrink:0;}
.pc-badge.achtung{color:var(--err-text);border:1px solid var(--err-border);}
.pc-badge.hinweis{color:var(--star);border:1px solid var(--star);}
.pc-badge.passt{color:var(--done-text);border:1px solid var(--done-border);}
.pc-badge.keine{color:var(--text-sub);border:1px solid var(--border);}
.pc-note-section{margin-top:0.55rem;}
.pc-note-section:first-of-type{margin-top:0.45rem;}
.pc-note-heading{font-size:0.74rem;font-weight:700;text-transform:none;letter-spacing:0;color:var(--text-sub);margin-bottom:0.25rem;}
.pc-notes{margin:0;padding-left:0;list-style:none;}
/* min-width:0 auf dem Text-Span ist der Grund, warum der Umbruch vorher
   willkürlich aussah: ohne eigenes Flex-Item darf der Text nicht schrumpfen
   und ragt/umbricht neben dem Icon unkontrolliert. */
.pc-notes li{display:flex;align-items:flex-start;gap:0.35rem;font-size:0.8rem;line-height:1.45;margin-bottom:0.3rem;color:var(--text-sub);}
.pc-note-text{flex:1;min-width:0;}
.pc-notes li.diet,.pc-notes li.intolerance,.pc-notes li.like,.pc-notes li.diet-match{color:var(--text);}
.pc-note-icon{flex-shrink:0;margin-top:0.15rem;display:flex;}
.pc-note-icon.warn{color:var(--star);}
.pc-note-icon.ok{color:var(--done-text);}
.pc-note-icon.muted{color:var(--text-sub);}
.pc-note-highlight{color:var(--rezept);font-weight:600;}
.pc-empty{font-size:0.8rem;color:var(--text-sub);margin:0.35rem 0 0;}
.pc-lead{font-size:0.8rem;color:var(--text-sub);margin-bottom:0.8rem;line-height:1.45;}
/* Personenauswahl: Haushalte aufklappbar, Mitglieder je Zeile ankreuzbar */
.pc-hh-group{margin-bottom:0.6rem;border:1.5px solid var(--border);border-radius:var(--r-lg);padding:0.15rem 0.75rem;background:var(--surface);}
.pc-hh-group summary{cursor:pointer;font-size:0.85rem;font-weight:700;padding:0.6rem 0;list-style:none;display:flex;align-items:center;gap:0.5rem;}
.pc-hh-group summary::-webkit-details-marker{display:none;}
.pc-pick-row{position:relative;display:flex;align-items:center;gap:0.55rem;padding:0.5rem 0;border-top:1px solid var(--border);cursor:pointer;}
/* Native Checkbox bleibt für Tastatur/Screenreader erhalten, ist aber
   unsichtbar — das eigene Kästchen daneben übernimmt die Optik. */
.pc-checkbox-input{position:absolute;opacity:0;width:1.3rem;height:1.3rem;margin:0;cursor:pointer;}
/* Gleiche Optik wie der Speichern-Haken beim Anlegen neuer Kategorien/Maß-
   einheiten (.catm-save-btn): gefüllt, abgerundetes Quadrat, Haken-Zeichen. */
.pc-checkbox-box{width:1.3rem;height:1.3rem;border-radius:var(--r-md);border:1.5px solid var(--border);flex-shrink:0;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:0.8rem;color:transparent;background:transparent;transition:all .12s;}
.pc-checkbox-input:checked~.pc-checkbox-box{background:var(--active-accent);border-color:var(--active-accent);color:var(--active-accent-text);}
@media(hover:hover){.pc-pick-row:hover .pc-checkbox-box{border-color:var(--active-accent);}}
.pc-back-btn{background:none;border:none;color:var(--rezept);font-size:0.8rem;font-weight:600;cursor:pointer;padding:0 0 0.7rem;}

/* ── Import prüfen ──────────────────────────────────────────── */
/* Gleiche Aufteilung wie der Rezept-Wizard: Liste scrollt, Buttons kleben
   unten — hier bewusst auf allen Breiten, nicht nur am Handy. */
#import-review-modal .modal-box,#import-found-modal .modal-box{display:flex;flex-direction:column;overflow-y:hidden;padding-bottom:0;}
#import-review-list,#import-found-body{flex:1;min-height:0;overflow-y:auto;}
#import-review-modal .wizard-footer,#import-found-modal .wizard-footer{position:static;flex-shrink:0;margin:0.8rem -1.5rem 0;}
.ir-row{display:flex;gap:0.5rem;align-items:flex-start;padding:0.45rem 0;border-bottom:1px solid var(--border);}
.ir-row:last-child{border-bottom:none;}
.ir-kind{width:7.2rem;flex-shrink:0;font-size:0.76rem;padding:0.35rem 1.5rem 0.35rem 0.5rem;background-position:right 0.45rem center;margin-top:0.05rem;}
.ir-body{flex:1;min-width:0;font-size:0.85rem;line-height:1.4;overflow-wrap:break-word;}
/* Zutaten-Zeile: dieselben Feldtypen wie im normalen Editor, nur ohne den
   Zeilenabstand, den .ing-row dort zu den Nachbarzeilen braucht. */
.ir-ing-row{margin-bottom:0.35rem!important;}
/* Menge/Einheit und Name teilen sich im Pruefschritt die Breite mit der
   Zeilenart-Auswahl und dem Loeschen-Knopf. Auf dem Handy blieb vom Namen nur
   ein Buchstabe uebrig, deshalb bekommt er hier immer eine eigene Zeile. */
/* Der Name steht in .ir-name-line, die die volle Zeile nimmt — der Hinweis-
   Knopf sitzt darin rechts neben dem Feld. */
/* Zweite Hinweisleiste: Einheiten, die der Import mitbringt, die es in der
   Mengenverwaltung aber noch nicht gibt. Optisch wie .ir-units, nur neutral
   statt in Akzentfarbe, damit die beiden Leisten sich nicht ins Gehege kommen. */
.ir-newunits{display:flex;align-items:center;gap:0.6rem;flex-wrap:wrap;background:var(--surface2);border:1px solid var(--border);border-radius:var(--r-lg);padding:0.55rem 0.7rem;}
.ir-newunits-text{flex:1;min-width:10rem;font-size:0.76rem;color:var(--text-sub);line-height:1.35;}
.ir-newunits-text b{color:var(--text);font-weight:600;}
.ir-newunits-actions{display:flex;gap:0.4rem;flex-shrink:0;}
.ir-newunits-btn{border:1.5px solid var(--border);background:transparent;color:var(--text);border-radius:var(--r-md);padding:0.3rem 0.65rem;font-size:0.74rem;font-weight:600;cursor:pointer;}
.ir-newunits-btn.primary{border-color:var(--rezept);color:var(--rezept);}
.ir-newunits-btn:disabled{opacity:0.5;cursor:default;}
/* Bei Zutaten liefert die .ing-row darueber den Abstand; nach einem Schritt-
   Textfeld gibt es keinen, deshalb hier explizit — sonst klebt das ⓘ-Feld
   direkt am Schritttext. */
.ir-note-wrap{display:flex;align-items:flex-start;gap:0.35rem;margin-top:0.35rem;}
.ir-ing-row + .ir-note-wrap{margin-top:0;}
/* Hinweis-Knopf je Zeile, gleiche Optik wie im Editor. */
/* Der Knopf sitzt am Ende der Zutatenzeile bzw. neben "Teilen" — nicht in der
   rechten Spalte neben dem Papierkorb, die kostet Breite in jeder Zeile. */
.ir-name-line{display:flex;align-items:center;gap:0.3rem;flex:1 1 100%;min-width:0;}
.ir-name-line .ing-name{flex:1;min-width:0;}
.ir-note-btn{background:none;border:none;color:var(--text-sub);cursor:pointer;width:1.6rem;height:1.6rem;border-radius:var(--r-md);flex-shrink:0;display:flex;align-items:center;justify-content:center;padding:0;opacity:0.6;transition:opacity .15s,color .15s;}
@media(hover:hover){.ir-note-btn:hover{opacity:1;}}
.ir-note-btn.active{opacity:1;color:var(--rezept);}
.ir-note-icon{flex-shrink:0;font-size:0.85rem;line-height:1.6;color:var(--text-sub);opacity:0.8;}
.ir-ing-note{width:100%;background:var(--surface2);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.4rem 0.6rem;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.78rem;font-style:italic;outline:none;resize:none;overflow:hidden;line-height:1.4;}
.ir-ing-note:focus{border-color:var(--rezept);}
.ir-flag{display:inline-block;font-size:0.62rem;font-weight:700;text-transform:uppercase;letter-spacing:0.04em;color:var(--star);border:1px solid var(--star);border-radius:99px;padding:0.05rem 0.3rem;margin:0.3rem 0.35rem 0 0;vertical-align:1px;}
.ir-empty{font-size:0.82rem;color:var(--text-sub);padding:1.2rem 0;text-align:center;}
/* Umrechnen-Schalter im Import-Pruefschritt. Erscheint nur, wenn US-Einheiten
   erkannt wurden; umbricht auf schmalen Displays in zwei Zeilen. */
/* Beide Hinweisleisten sitzen ueber der Liste. Sie ruecken eng zusammen und
   teilen sich einen Abstand nach unten, damit das Rezept nicht unnoetig weit
   nach unten geschoben wird. */
.ir-units,.ir-newunits{margin-bottom:0.4rem;}
.ir-units + #import-review-newunits .ir-newunits,#import-review-newunits:last-of-type .ir-newunits{margin-bottom:0.9rem;}
#import-review-units:not(:empty) + #import-review-newunits:empty .ir-units{margin-bottom:0.9rem;}
.ir-units{display:flex;align-items:center;gap:0.6rem;flex-wrap:wrap;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);padding:0.55rem 0.7rem;}
.ir-units-text{flex:1;min-width:11rem;font-size:0.76rem;color:var(--text-sub);line-height:1.35;}
.ir-units-text b{color:var(--text);font-weight:600;}
/* Nach dem Umrechnen: schmaler, einzeilig, ohne Erklaerung. */
.ir-units.compact{padding:0.3rem 0.6rem;}
.ir-units.compact .ir-units-text{font-size:0.73rem;min-width:8rem;}
.ir-units.compact .ir-units-btn{padding:0.2rem 0.55rem;font-size:0.72rem;}
.ir-units-btn{flex-shrink:0;border:1.5px solid var(--active-accent);background:transparent;color:var(--active-accent);border-radius:var(--r-md);padding:0.32rem 0.72rem;font-size:0.76rem;font-weight:600;cursor:pointer;transition:all .15s;}
@media(hover:hover){.ir-units-btn:hover{opacity:0.85;}}
.ir-units-btn.active{background:var(--active-accent);color:var(--active-accent-text);}
.ir-units-btn:disabled{opacity:0.55;cursor:default;}
/* Scheitert die Uebersetzung, bleibt der Grund in der Leiste stehen — dort,
   wo der Knopf sitzt, den man gerade gedrueckt hat. */
.ir-units-err{display:block;margin-top:0.2rem;color:var(--err-text);}
/* Optionaler Quellenlink im Pruefschritt (vor allem Foto-Import): entweder
   ein schlichter Text-Knopf zum Aufklappen oder — sobald offen bzw. schon
   befuellt — ein Eingabefeld mit dem Link-Icon davor. Bewusst dezenter als
   die Schalter darueber (kein Rahmen um den Knopf): das ist ein Angebot, das
   die meisten Importe gar nicht brauchen, kein weiterer Regler. */
.ir-source-toggle{display:flex;align-items:center;gap:0.4rem;background:none;border:none;color:var(--text-sub);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.78rem;padding:0.3rem 0;cursor:pointer;margin-bottom:0.5rem;}
@media(hover:hover){.ir-source-toggle:hover{color:var(--rezept);}}
.ir-source-field{display:flex;align-items:center;gap:0.5rem;color:var(--text-sub);margin-bottom:0.6rem;}
.ir-source-field input{flex:1;min-width:0;background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.4rem 0.65rem;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.8rem;outline:none;}
.ir-source-field input:focus{border-color:var(--rezept);}
.ir-photo-note{display:flex;align-items:center;gap:0.55rem;color:var(--text-sub);font-size:0.78rem;background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-lg);padding:0.4rem;margin-bottom:0.6rem;}
.ir-photo-note img{width:2.4rem;height:2.4rem;object-fit:cover;border-radius:var(--r-xs);flex-shrink:0;}
.import-hint{font-size:0.74rem;color:var(--text-sub);margin-top:0.25rem;line-height:1.35;}

/* ── Kontingent und Premium-Hinweis im Import ──────────────────
   Solange noch Importe uebrig sind, steht hier nur eine ruhige Zeile: die
   Zahl ist eine Auskunft, keine Mahnung. Ist das Kontingent aufgebraucht,
   verschwindet die Zeile — dann traegt der Vorhang ueber den Wegen dieselbe
   Zahl, nur laut, und zweimal braucht sie niemand. */
.kontingent-zeile{
  display:flex;align-items:center;gap:0.4rem;flex-wrap:wrap;
  font-size:0.78rem;color:var(--text-sub);margin:-0.4rem 0 0.9rem;
}
.kontingent-zeile b{color:var(--text);font-weight:700;}
/* Fuenf Striche, die uebrigen gefuellt — dieselbe Zahl nochmal, nur ohne
   Lesen. Bewusst winzig: die Zeile bleibt eine Auskunft, keine Mahnung. */
.kontingent-bar{display:flex;gap:2.5px;flex-shrink:0;}
.kontingent-bar i{width:9px;height:5px;border-radius:99px;background:var(--border);}
.kontingent-bar i.an{background:var(--rezept);}
.kontingent-mehr{
  margin-left:auto;background:none;border:none;padding:0;cursor:pointer;
  color:var(--rezept);font-family:inherit;font-size:0.78rem;font-weight:600;
  display:inline-flex;align-items:center;gap:0.2rem;
}
/* Auf dem Handy passt die Zeile nicht in eine Reihe. Rechtsbuendig sah der
   Umbruch dann aus wie ein verrutschtes Element — links angeschlossen liest
   er sich als Fortsetzung derselben Zeile. */
@media(max-width:430px){.kontingent-mehr{margin-left:0;}}
/* ── Vorhang ueber den drei Import-Wegen ───────────────────────
   Gesperrt heisst hier: der ganze Bereich liegt hinter einem Schleier, mit
   EINER Nachricht in der Mitte statt drei Schildchen an drei Karten. Der
   Inhalt bleibt bewusst erkennbar — man soll sehen, was einen erwartet,
   statt vor einer grauen Flaeche zu stehen. Die Stufe liegt zwischen den
   beiden Entwuerfen A (fast blind) und B (heller Schleier): genug Durchsicht,
   dass die drei Wege lesbar bleiben, genug Deckung, dass die Schrift darauf
   noch traegt.
   Die Sperre selbst haengt NICHT hieran — die Felder tragen disabled und die
   Grenze zieht der Server. Das hier ist, was man davon sieht. */
#import-wege{position:relative;}
#import-wege.wege-gesperrt{border:1.5px solid var(--rezept);border-radius:var(--r-lg);padding:0.7rem;overflow:hidden;}
.wege-gesperrt .import-way,.wege-gesperrt .import-or{
  filter:grayscale(0.75);opacity:0.37;pointer-events:none;user-select:none;
}
.wege-vorhang{
  position:absolute;inset:0;z-index:2;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:0.15rem;text-align:center;padding:1rem;
  background:color-mix(in srgb,var(--surface) 76%,transparent);
  backdrop-filter:blur(1px);
}
.wege-vorhang-schloss{color:var(--rezept);line-height:0;margin-bottom:0.35rem;}
.wege-vorhang-kopf{font-family:'Literata',Georgia,serif;font-size:1.02rem;font-weight:600;line-height:1.3;color:var(--text);}
.wege-vorhang-sub{font-size:0.78rem;color:var(--text-sub);margin:0.15rem 0 0.9rem;line-height:1.4;}
.wege-vorhang .btn-primary{width:min(100%,15rem);margin-top:0;}

/* Der Werbeblock steht am Ende der drei Wege, nicht davor: erst sieht man,
   was gesperrt ist, dann was es aufhebt. */
.premium-angebot{
  border:1.5px solid var(--rezept);border-radius:var(--r-md);
  padding:0.85rem;margin-top:1rem;text-align:center;
}
.premium-angebot-kopf{font-family:'Literata',Georgia,serif;font-size:1rem;font-weight:600;color:var(--text);margin-bottom:0.25rem;}
.premium-angebot p{font-size:0.78rem;color:var(--text-sub);line-height:1.45;margin:0 0 0.7rem;}
.premium-angebot .btn-primary{margin-top:0;}
.premium-fussnote{font-size:0.74rem;color:var(--text-sub);text-align:center;margin:0.7rem 0 0;line-height:1.4;}

/* ── Premium-Bildschirm ────────────────────────────────────────
   Erst was dazukommt, dann was es kostet. Deshalb stehen die Tarifkarten
   unter der Vorteilsliste und nicht als Preisschild ueber allem. Die beiden
   Fassungen (Haushalt / Import) unterscheiden sich nur im Text. */
.premium-lead{font-size:0.85rem;color:var(--text-sub);line-height:1.5;margin:0 0 1.1rem;}
.premium-vorteile{list-style:none;margin:0 0 1.4rem;padding:0;display:flex;flex-direction:column;gap:0.85rem;}
.premium-vorteil{display:flex;gap:0.7rem;align-items:flex-start;}
.premium-vorteil-icon{flex-shrink:0;color:var(--rezept);margin-top:0.1rem;line-height:0;}
.premium-vorteil strong{display:block;font-size:0.86rem;font-weight:700;color:var(--text);margin-bottom:0.1rem;}
.premium-vorteil span{display:block;font-size:0.78rem;color:var(--text-sub);line-height:1.4;}
/* Die Sparmarke haengt oben aus der Karte heraus — deshalb Platz darueber,
   sonst schneidet der Rand der Liste sie ab. */
.premium-tarife{display:flex;gap:0.5rem;margin-top:0.8rem;}
.premium-tarif{
  position:relative;flex:1;text-align:left;cursor:pointer;
  border:1.5px solid var(--border);border-radius:var(--r-md);
  background:var(--field);color:var(--text);padding:0.7rem 0.75rem;
  font-family:'Instrument Sans',system-ui,sans-serif;
  transition:border-color .15s,background .15s;
}
.premium-tarif.active{border-color:var(--rezept);background:var(--surface2);}
.premium-tarif-name{font-size:0.68rem;font-weight:700;letter-spacing:0.06em;text-transform:uppercase;color:var(--text-sub);}
.premium-tarif-preis{font-family:'Literata',Georgia,serif;font-size:1.2rem;font-weight:600;line-height:1.25;margin-top:0.15rem;}
.premium-tarif-sub{font-size:0.72rem;color:var(--text-sub);}
.premium-tarif-spar{
  position:absolute;top:-0.55rem;right:0.5rem;
  background:var(--rezept);color:var(--primary-text);border-radius:99px;
  padding:0.1rem 0.45rem;font-size:0.6rem;font-weight:700;
  letter-spacing:0.04em;text-transform:uppercase;
}
.premium-hinweis{font-size:0.74rem;color:var(--text-sub);text-align:center;line-height:1.4;margin:0.9rem 0 0;}
.premium-restore{
  display:block;margin:0.6rem auto 0;background:none;border:none;padding:0.2rem;
  cursor:pointer;color:var(--text-sub);font-family:inherit;font-size:0.76rem;text-decoration:underline;
}
@media(hover:hover){
  .premium-tarif:hover{border-color:var(--rezept);}
  .premium-restore:hover{color:var(--text);}
}

/* ── Dev-Schalter im Profil ────────────────────────────────────
   Bewusst als klar abgesetzter Kasten mit gestricheltem Rahmen: Er gehoert
   nicht zum Produkt und soll auch nicht danach aussehen. Sichtbar nur auf
   dem Entwicklungsrechner und im eigenen WLAN (premium.js/istDev). */
/* "Premium"-Merker auf der Kachel "Neuen Haushalt erstellen". Die Kachel
   bleibt bedienbar — sie fuehrt zum Angebot statt ins Leere. */
.hh-choice-btn{position:relative;}
.hh-premium-badge{
  position:absolute;top:6px;right:6px;
  background:var(--rezept);color:var(--primary-text);
  border-radius:99px;padding:0.08rem 0.4rem;
  font-size:0.6rem;font-weight:700;letter-spacing:0.04em;text-transform:uppercase;
}

.pf-abo{border:1.5px dashed var(--border);border-radius:var(--r-md);padding:0.7rem 0.8rem;margin-top:1.2rem;}
.pf-abo-kopf{font-size:0.68rem;font-weight:700;letter-spacing:0.08em;text-transform:uppercase;color:var(--text-sub);margin-bottom:0.5rem;}
.pf-abo-info{font-size:0.74rem;color:var(--text-sub);line-height:1.45;margin:0 0 0.6rem;}
.pf-abo-schalter{display:flex;gap:0.4rem;}
.pf-abo-btn{
  flex:1;padding:0.4rem 0.5rem;border-radius:var(--r-xs);cursor:pointer;
  border:1.5px solid var(--border);background:var(--field);color:var(--text-sub);
  font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.8rem;font-weight:600;
}
.pf-abo-btn.active{border-color:var(--active-accent);background:var(--active-accent);color:var(--active-accent-text);}
.pf-abo-note{font-size:0.72rem;color:var(--text-sub);line-height:1.4;margin:0.5rem 0 0;}
.pf-abo-note button{
  background:none;border:none;padding:0;cursor:pointer;
  color:var(--rezept);font-family:inherit;font-size:inherit;font-weight:600;text-decoration:underline;
}
/* Abgeschalteter Import-Weg: sichtbar, aber erkennbar nicht benutzbar. */
/* Abgeschalteter Import-Weg. Nur blasser reichte nicht — man musste den Text
   lesen, um zu merken, dass hier nichts geht. Jetzt gestrichelter Rahmen,
   zurueckgenommener Grund und ein Schild an der Ueberschrift. Bewusst in
   Grautoenen: hier ist nichts kaputt, es ist nur gerade zu. */
/* Doppelte Klasse, weil .import-way weiter unten steht und bei gleicher
   Spezifitaet sonst gewinnt. */
.import-way.import-way-off{border-style:dashed;background:none;}
.import-way-off .import-way-icon{filter:grayscale(1);opacity:0.5;}
.import-way-off .import-way-titles strong{color:var(--text-sub);}
.import-way-off button{cursor:default;opacity:0.6;border-style:dashed;}
.import-way-badge{display:inline-block;margin-left:0.4rem;vertical-align:0.08em;background:var(--border);color:var(--text-sub);border-radius:99px;padding:0.1rem 0.45rem;font-size:0.64rem;font-weight:700;letter-spacing:0.04em;text-transform:uppercase;}

/* ── Karte "Rezept gefunden" ─────────────────────────────────────────────
   Beim Link-Import gibt es nichts zuzuordnen, nur zu entscheiden. Die Karte
   beantwortet zwei Fragen auf einen Blick: kam das richtige Rezept, und soll
   uebersetzt/umgerechnet werden. */
.if-cover{width:100%;aspect-ratio:16/9;overflow:hidden;border-radius:var(--r-lg);background:var(--surface2);margin-bottom:0.7rem;}
.if-cover img{width:100%;height:100%;object-fit:cover;display:block;}
.if-title{font-size:1.05rem;font-weight:700;line-height:1.25;}
.if-meta{font-size:0.8rem;color:var(--text-sub);margin-top:0.2rem;}
.if-switches{margin-top:0.9rem;display:flex;flex-direction:column;gap:0.5rem;}
/* Schalterzeile: die ganze Zeile ist der Knopf, nicht nur der Knubbel — auf
   dem Handy trifft man sonst daneben. */
.if-switch{display:flex;align-items:center;gap:0.7rem;width:100%;text-align:left;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);padding:0.6rem 0.7rem;cursor:pointer;}
.if-switch.on{border-color:var(--active-accent);}
.if-switch:disabled{opacity:0.6;cursor:default;}
.if-switch-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:0.1rem;}
.if-switch-label{font-size:0.85rem;font-weight:600;color:var(--text);}
.if-switch-sub{font-size:0.73rem;color:var(--text-sub);}
.if-switch-err{font-size:0.73rem;color:var(--err-text);}
.if-knob{flex-shrink:0;width:2.2rem;height:1.25rem;border-radius:99px;background:var(--border);position:relative;transition:background .15s;}
.if-knob::after{content:"";position:absolute;top:0.15rem;left:0.15rem;width:0.95rem;height:0.95rem;border-radius:50%;background:var(--bg);transition:transform .15s;}
.if-switch.on .if-knob{background:var(--active-accent);}
.if-switch.on .if-knob::after{transform:translateX(0.95rem);}
/* Der Weg in den Pruefschritt ist ein Ausweg, kein Hauptweg — deshalb als
   Textlink ueber den Knoepfen statt als dritter Knopf daneben. */
.if-check{display:block;width:100%;background:none;border:none;color:var(--text-sub);font-size:0.78rem;text-decoration:underline;cursor:pointer;padding:0 0 0.55rem;}

/* ── Link-Import fehlgeschlagen ──────────────────────────────────────────
   Der Grund stand vorher als graue Kleinschrift unter beiden Import-Wegen
   und wurde uebersehen. */
.ie-box{border:1px solid var(--err-text);border-radius:var(--r-lg);padding:0.7rem 0.8rem;margin-top:0.7rem;}
.ie-head{display:flex;align-items:flex-start;gap:0.5rem;font-size:0.85rem;font-weight:600;color:var(--text);line-height:1.35;}
.ie-icon{flex-shrink:0;width:1.15rem;height:1.15rem;border-radius:50%;background:var(--err-text);color:var(--bg);font-size:0.78rem;font-weight:700;display:flex;align-items:center;justify-content:center;}
.ie-text{font-size:0.78rem;color:var(--text-sub);line-height:1.45;margin:0.45rem 0 0;}
.ie-tip{font-size:0.74rem;color:var(--text-sub);line-height:1.4;margin:0.45rem 0 0;}
.ie-actions{display:flex;flex-wrap:wrap;gap:0.4rem;margin-top:0.6rem;}
.ie-btn{flex:1;min-width:9rem;border:1.5px solid var(--border);background:transparent;color:var(--text);border-radius:var(--r-md);padding:0.45rem 0.7rem;font-size:0.8rem;font-weight:600;cursor:pointer;}
.ie-btn.primary{border-color:var(--active-accent);color:var(--active-accent);}
/* Import-Einstieg: Link und Datei als zwei gleichrangige Wege, getrennt durch
   ein "oder". Vorher standen sie als zwei Felder untereinander und der zweite
   las sich wie eine Fortsetzung des ersten. */
/* Rahmen ohne Flaeche: die Kante fasst Titelzeile, Feld und Knopf zu einer
   Gruppe zusammen, der Untergrund bleibt aber die Modalflaeche. Bewusst OHNE
   eigenen Flaechenton — damit bleibt das vertiefte Eingabefeld die einzige
   abgesetzte Flaeche im Fenster und behaelt die ganze Aufmerksamkeit. */
.import-way{display:flex;flex-direction:column;gap:0.45rem;border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.7rem;}
.import-way-head{display:flex;align-items:center;gap:0.55rem;}

/* Foto-Ausrichten vor der Erkennung. Rahmen wie ein Feld (--field), Bild
   sitzt mit etwas Luft darin und dreht sich per CSS-transform — die echte
   Drehung passiert erst beim Bestaetigen auf einem Canvas. */
.rotate-frame{background:var(--field);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.6rem;display:flex;align-items:center;justify-content:center;min-height:12rem;margin-bottom:0.9rem;}
#rotate-preview{max-width:100%;display:block;border-radius:var(--r-xs);}
#rotate-turn{width:auto;margin:0 auto;display:flex;align-items:center;justify-content:center;}
/* gap statt Einzelabstaende — und der Reset raeumt die mitgebrachten Abstaende
   der Kinder ab (die Knoepfe bringen margin-top mit, der Fehlerkasten auch). */
.import-way-body{display:flex;flex-direction:column;gap:0.5rem;}
.import-way-body>*{margin-top:0;margin-bottom:0;}
/* Eingabefelder vertieft: --surface waere hier dieselbe Farbe wie die
   Modalflaeche, auf der die Karte liegt — das Feld verschwand darin.
   Das Code-Feld gehoert dazu: es ist derselbe Vorgang (etwas uebernehmen) und
   sass als einziges noch auf der Modalflaeche. */
#f-import-url,#f-import-notes,#f-redeem-code{background:var(--bg);}
/* Icons statt Emojis — die rendern je nach Geraet in fremder Optik und
   fielen neben den durchgehend gezeichneten Symbolen der App auf. Farbe wie
   bei .entry-choice-icon, damit der Einstieg davor gleich aussieht. */
.import-way-icon{flex-shrink:0;display:flex;align-items:center;color:var(--rezept);}
.import-way-titles{display:flex;flex-direction:column;gap:0.1rem;min-width:0;}
.import-way-titles strong{font-size:0.92rem;font-weight:600;color:var(--text);}
.import-way-titles>span{font-size:0.74rem;color:var(--text-sub);line-height:1.35;}
/* Enger als die .entry-lead im Einstiegsbildschirm: dort traegt die Frage eine
   ganze Seite, hier gehoert sie sichtbar zur Ueberschrift UND zu den Karten
   darunter. Negativer Abstand nach oben wie bei .step-indicator, weil das h2
   seinen margin-bottom fuer alle Wizard-Schritte mitbringt. */
/* KEIN negativer Abstand nach oben: die Zeile ist das erste Kind ihres
   Containers, ein negativer Wert zog sie ueber dessen Oberkante hinaus und
   ein scrollender Vorfahr schnitt die erste Textzeile oben ab. Den Abstand
   macht stattdessen die Ueberschrift kleiner, siehe .import-active unten.
   line-height ausdruecklich, weil geerbt "normal" galt und je nach Schrift
   unterschiedlich ausfaellt. */
.import-lead{margin-bottom:0.5rem;line-height:1.45;}
/* Nur im Import-Schritt: das h2 bringt seinen Abstand fuer alle
   Wizard-Schritte mit, hier gehoert die Frage naeher an die Ueberschrift.
   Klasse setzt showRecipeScreen() in recipes.js. */
#recipe-modal.import-active h2{margin-bottom:0.5rem;}
/* Der Abstand darf wieder kleiner sein, seit der Rahmen die Gruppierung
   traegt — mit 1.1rem war der Bildschirm nur noch scrollend zu sehen. */
.import-or{display:flex;align-items:center;gap:0.6rem;margin:0.65rem 0;color:var(--text-sub);font-size:0.78rem;text-transform:none;letter-spacing:0;}
.import-or::before,.import-or::after{content:'';flex:1;height:1px;background:var(--border);}
/* Ohne Plaettchen: die Linien links und rechts uebernehmen die Trennung
   ohnehin, das Polster und der Rahmen kosteten nur Hoehe. Die Farbe bleibt
   zurueckhaltend — in der Markenfarbe zog das Wort mehr Aufmerksamkeit auf
   sich als die Wege, die es trennt. Der seitliche Abstand bleibt, sonst
   kleben die Linien am Wort. */
.import-or span{padding:0 0.15rem;}
/* Notizen-Feld: etwas kleiner gesetzt als die uebrigen Eingaben, weil hier
   ein ganzer Zettel hineingehoert. Startet flach und waechst per
   autoGrowTextarea mit dem Inhalt — leerer Vorrat kostet nur Platz, den die
   dritte Karte braucht. Die Obergrenze verhindert, dass ein langer Zettel das
   Feld ueber den ganzen Bildschirm zieht; darin scrollt es dann. */
/* resize:none wie bei den anderen mitwachsenden Feldern (Schritte,
   Pruefschritt): der native Anfasser waere hier sogar irrefuehrend, weil
   autoGrowTextarea die Hoehe bei jeder Eingabe neu setzt und eine von Hand
   gezogene damit beim naechsten Tastendruck verwirft. */
#f-import-notes{font-size:0.9rem;line-height:1.45;resize:none;min-height:2.9rem;max-height:14rem;overflow-y:auto;}
/* Platzhalter als eigenes Element (siehe index.html): deckungsgleich ueber
   dem Feld, deshalb dieselben Werte fuer Polster, Schriftgroesse und
   Zeilenhoehe. pointer-events:none, damit ein Tipp durch ihn hindurch im Feld
   landet — sonst waere das Feld genau dort nicht antippbar, wo der Hinweis
   steht. */
.notes-field{position:relative;display:flex;}
.notes-ph{position:absolute;inset:0;padding:0.6rem 0.8rem;font-size:0.9rem;line-height:1.45;color:var(--text-sub);opacity:0.7;pointer-events:none;}
.notes-field textarea:not(:placeholder-shown)+.notes-ph{display:none;}
.ir-edit{width:100%;background:var(--surface2);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.4rem 0.55rem;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.85rem;line-height:1.4;outline:none;resize:none;overflow:hidden;display:block;}
.ir-edit:focus{border-color:var(--rezept);}
.ir-split{display:inline-block;background:none;border:1px solid var(--border);border-radius:var(--r-md);color:var(--text-sub);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.7rem;padding:0.18rem 0.5rem;margin-top:0.35rem;cursor:pointer;}
@media(hover:hover){.ir-split:hover{color:var(--rezept);border-color:var(--rezept);}}
.ir-del{background:none;border:none;color:var(--text-sub);cursor:pointer;width:2.2rem;height:2.2rem;border-radius:var(--r-md);flex-shrink:0;display:flex;align-items:center;justify-content:center;margin-top:0.1rem;}
@media(hover:hover){.ir-del:hover{color:var(--err-text);}}
/* Auf schmalen Geräten das Auswahlfeld verschlanken, damit der Rezepttext
   noch lesbar breit bleibt. */
/* Schmale Displays: die Zeilenart-Auswahl und der Loeschen-Knopf geben Breite
   an den Zutatennamen ab — der ist beim Pruefen wichtiger als ein
   ausgeschriebenes "Zutat". */
@media(max-width:420px){
  .ir-kind{width:5.4rem;font-size:0.7rem;padding-right:1.2rem;background-position:right 0.3rem center;}
  .ir-del{width:1.9rem;}
  .ir-row{gap:0.35rem;}
  /* Menge/Einheit nimmt die volle Zeilenbreite wie der Name darunter — die
     Einheit hat sonst keinen Platz fuer ausgeschriebene Namen wie
     "Messerspitze". Die Menge behaelt ihre feste Breite, die Einheit bekommt
     den Rest. */
  .ir-ing-row .ing-amount-unit{flex-basis:100%;}
  .ir-ing-row .ing-amount-unit .ing-unit{flex:1;width:auto;}
}

/* ── Detail ─────────────────────────────────────────────────── */
.detail-info-line{font-size:0.82rem;color:var(--text-sub);margin-bottom:0.4rem;}
#detail-source a,#import-source-link{color:var(--rezept);}
/* .btn-sec bringt nur oben Abstand mit — ohne eigenes Bottom-Margin klebt der
   "Portionen"-Abschnitt (oder bei Recipes ohne Bild: die Rezept-Quelle-Zeile)
   direkt am "Wer isst mit?"-Button darüber. */
#detail-prefs-btn{margin-bottom:0.9rem;}
.print-only-line{display:none;}
/* Die Quelle stand frueher als halbtransparente Marke auf dem Titelbild. Je
   nach Bildausschnitt war sie dort kaum lesbar — jetzt wieder Textzeile
   (#detail-source), aber ueber dem Bild statt darunter. */
/* Kategorien-Zeile im Detail: knapp nach oben, etwas Luft nach unten — vorher
   klebte bei geteilten Rezepten der „Kategorie zuordnen"-Knopf an der
   Bewertung. */
#detail-cats{margin:0.1rem 0 0.7rem;display:flex;flex-wrap:wrap;align-items:center;gap:0.3rem;}
#detail-cats:empty{margin:0;}
#detail-cats .cat-pill{margin:0;}
/* Bewertung eine Zeile unter dem Titel: alle 5 Sterne + Anzahl. */
#detail-title{margin-bottom:0.4rem;}
.detail-rating-row{display:flex;align-items:center;gap:0.4rem;margin-bottom:0.6rem;}
.detail-rating-row .detail-star-row{display:inline-flex;gap:0.1rem;color:var(--star);}
.detail-rating-row .detail-star-row .star-wrap{width:17px;height:17px;}
.detail-rating-row .rating-count{color:var(--text-sub);font-size:0.82rem;}
.detail-rating-row .rating-none{color:var(--text-sub);font-size:0.82rem;}
.detail-rating-row .rater-avatar{margin-left:0.08rem;font-size:0.9rem;}
/* Zeiten: Gesamtzeit fett als Kopfzeile, darunter 2 Spalten. Erste Spalte nur
   so breit wie noetig, zweite bekommt den Rest — sonst bricht die 3-stellige
   Temperatur um. Die Werte selbst nie umbrechen. */
.detail-times{margin-bottom:0.9rem;}
.detail-time-total{display:inline-flex;align-items:center;gap:0.4rem;font-size:0.9rem;font-weight:700;color:var(--text);margin-bottom:0.35rem;}
.detail-time-total svg{flex-shrink:0;color:var(--active-accent);}
.detail-time-grid{display:grid;grid-template-columns:auto 1fr;gap:0.3rem 0.9rem;}
.detail-time-line{display:inline-flex;align-items:center;gap:0.4rem;font-size:0.82rem;color:var(--text-sub);white-space:nowrap;}
/* War urspruenglich ueberall neutral (--text-sub), nur bei Basic (siehe
   Regel weiter unten) auf Wunsch gruen. Faelschlich erst global auf
   --active-accent gestellt — bei allen anderen Themes ist das identisch mit
   --rezept (also eine Farbe statt Neutral-Grau), das faerbte z.B. bei Ocean
   die Zeiten-Icons unbeabsichtigt blau ein. */
.detail-time-line svg{flex-shrink:0;color:var(--text-sub);}
[data-theme="light"] .detail-time-line svg,[data-theme="dark-neutral"] .detail-time-line svg{color:var(--active-accent);}
.detail-difficulty-line{margin-top:0.5rem;font-size:0.82rem;color:var(--text-sub);}
/* Die Naehrwerte sind eine eigene Auskunft, keine weitere Zeitangabe — mit
   dem knappen Abstand der Zeilen darueber klebten sie an den Zeiten und
   lasen sich wie eine davon. */
.detail-nutri-line{margin-top:1.1rem;}
.detail-nutri-basis{opacity:0.75;}
/* Vorbereitungs-/Zubereitungszeit sind als Labels zu lang fuer die
   zweispaltige Paarung und bekommen deshalb ihre eigene volle Zeile. */
.detail-time-full{grid-column:1 / -1;}
.detail-toprow{display:flex;align-items:center;justify-content:space-between;gap:0.6rem;}
.detail-toprow .detail-info-line{margin-bottom:0.4rem;}
/* overflow:hidden kappt den hochskalierten Bildrand, siehe .detail-cover-track img. */
.detail-cover-wrap{position:relative;margin:0 -1.5rem 0.8rem;overflow:hidden;}
/* Viele Rezeptfotos tragen das Wasserzeichen der Quellseite eingebrannt
   ("einfachbacken.de" & Co.), fast immer unten. In der Vorschau stand es
   dadurch je nach Bildformat halb angeschnitten am Rand.
   Zwei Stellschrauben sorgen dafuer, dass unten IMMER ein Streifen wegfaellt:
   feste Hoehe + object-position oberhalb der Mitte kappt hohe Bilder unten —
   das allein reicht aber nicht, denn ein flaches Bild skaliert cover nach der
   Hoehe und schneidet dann seitlich statt unten. Deshalb zusaetzlich ein
   leichtes Hochskalieren mit Ursprung an der Oberkante: die unteren ~10 %
   laufen aus dem Rahmen und werden vom overflow des Wraps gekappt.
   Die Quelle selbst steht als Textzeile ueber dem Bild, und wer das ganze
   Foto sehen will, tippt es an — die Lightbox zeigt es ungeschnitten. */
#detail-cover-badge{bottom:12px;left:12px;}

/* TEST: Titelbild ganz nach oben, ueber Rezeptname/Bewertung. Der Kasten wird
   dafuer zur Spalte und die Bildgruppe (#detail-print-right, auf dem Schirm
   nur das Cover — der QR darin ist print-only) per order vor den Textblock
   gezogen. Nur wenn es ueberhaupt ein Titelbild gibt (.has-cover setzt
   openDetail): dann negativer Aussenabstand an die drei Modalkanten und
   Hoehe rund ein Viertel groesser (12rem -> 15rem). Der Druck-Block weiter
   unten setzt sein eigenes Grid und bleibt unberuehrt. */
@media screen{
  #detail-modal .modal-box{display:flex;flex-direction:column;}
  /* Der Kasten hat feste Hoehe (100dvh auf dem Handy) und scrollt selbst —
     die Flex-Kinder duerfen daher NICHT schrumpfen, sonst quetscht der
     Browser sie auf die Bildschirmhoehe zusammen (die Fotoleiste fiel so auf
     3 px). */
  #detail-modal .modal-box > *{flex-shrink:0;}
  #detail-modal.has-cover #detail-print-right{order:-1;}
  #detail-modal.has-cover .detail-cover-wrap{margin:-1.5rem -1.5rem 0.9rem;}
  #detail-modal.has-cover .detail-cover-track{height:15rem;}
  /* Das X ist in der Detailansicht immer eine Scheibe (sonst war es mal ein
     kräftiger Knopf auf dem Foto, mal ein blasses graues Zeichen auf der
     Fläche). Über dem Foto dunkel, sonst dezent in Flächenfarbe. */
  /* z-index: der randlose Titelbild-Streifen steht im DOM nach dem X und
     wuerde es sonst uebermalen (X verschwindet auf Rezepten mit Foto). */
  #detail-modal .modal-close{width:1.9rem;height:1.9rem;border-radius:50%;display:flex;align-items:center;justify-content:center;top:0.7rem;right:0.7rem;z-index:6;background:var(--surface2);border:1px solid var(--border);color:var(--text-sub);}
  #detail-modal.has-cover .modal-close{background:#0000006b;border-color:transparent;color:#fff;}
}
.detail-step-row{display:flex;gap:0.6rem;align-items:flex-start;margin-bottom:1rem;cursor:pointer;}
.detail-step-row:last-child{margin-bottom:0;}
.detail-step-num{font-family:'Instrument Sans',system-ui,sans-serif;font-size:calc(0.7rem * var(--detail-zoom, 1));font-weight:600;color:var(--active-accent-text);background:var(--active-accent);flex-shrink:0;width:calc(1.3rem * var(--detail-zoom, 1));height:calc(1.3rem * var(--detail-zoom, 1));border-radius:50%;display:flex;align-items:center;justify-content:center;font-variant-numeric:tabular-nums;}
.detail-step-body{flex:1;min-width:0;}
.detail-step-text{font-size:calc(0.86rem * var(--detail-zoom, 1));line-height:1.4;white-space:pre-wrap;}
/* Hinweis in eigener Zeile unter dem Schritt, mit etwas mehr Abstand nach
   oben als der normale Zeilenabstand innerhalb des Schritttexts. */
.detail-step-note{color:var(--text-sub);font-size:calc(0.78rem * var(--detail-zoom, 1));font-style:italic;margin-top:0.5rem;}
.detail-step-row.done .detail-step-text{opacity:0.5;text-decoration:line-through;}
.detail-step-row.done .detail-step-note{opacity:0.5;text-decoration:line-through;}
/* Im Editor zugeordnete Fotos, klein unter dem jeweiligen Schritt. */
.detail-step-photos{display:flex;flex-wrap:wrap;gap:0.4rem;margin-top:0.5rem;}
.detail-step-photos img{width:calc(3.6rem * var(--detail-zoom, 1));height:calc(3.6rem * var(--detail-zoom, 1));object-fit:cover;border-radius:var(--r-md);cursor:zoom-in;}
/* Zwischenueberschrift zwischen Schritten: dieselbe Optik wie die
   Zwischenueberschrift bei den Zutaten (.ing-section-item) — Literata,
   Markenfarbe. Nur die Abstaende passen zum groesseren Zeilenabstand der
   Schritte. */
.step-section-item{font-family:'Literata',Georgia,serif;font-weight:600;font-size:calc(0.96rem * var(--detail-zoom, 1));color:var(--rezept);letter-spacing:-0.002em;margin:0.9rem 0 0.7rem;}
.step-section-item:first-child{margin-top:0;}
#detail-ingredients{display:grid;grid-template-columns:auto 1fr;column-gap:0.7rem;row-gap:0.35rem;align-items:baseline;font-size:calc(0.86rem * var(--detail-zoom, 1));list-style:none;padding-left:0;}
#detail-ingredients li{list-style:none;}
.ing-detail-row{display:contents;}
.ing-detail-amt{font-weight:700;color:var(--text);white-space:nowrap;text-align:right;}
.ing-detail-name{color:var(--text);}
.ing-step-badge{display:inline-flex;align-items:center;justify-content:center;width:1.1rem;height:1.1rem;border-radius:50%;background:var(--surface);border:1px solid var(--border);color:var(--text-sub);font-size:0.6rem;font-family:'Instrument Sans',system-ui,sans-serif;margin-left:0.4rem;vertical-align:middle;font-variant-numeric:tabular-nums;}
.ing-detail-row.done .ing-detail-amt,.ing-detail-row.done .ing-detail-name{text-decoration:line-through;color:var(--text-sub);opacity:0.6;}
.ing-section-item{grid-column:1/-1;font-family:'Literata',Georgia,serif;font-weight:600;font-size:calc(0.96rem * var(--detail-zoom, 1));color:var(--rezept);margin-top:0.5rem;letter-spacing:-0.002em;}
.ing-section-item:first-child{margin-top:0;}
.detail-section-label{display:flex;align-items:center;gap:0.6rem;font-size:0.86rem;font-weight:600;color:var(--text);letter-spacing:-0.005em;text-transform:none;margin:1.4rem 0 0.55rem;}
/* Die Linie fuellt den Rest der Zeile. Bei .detail-section-label-row sitzt
   rechts noch ein Knopf — dort wandert sie zwischen Titel und Knopf. */
.detail-section-label::after{content:"";flex:1;height:1px;background:var(--border);}
.detail-section-label-row{display:flex;align-items:center;gap:0.6rem;}
.detail-section-toggle{width:1.7rem;height:1.7rem;flex-shrink:0;border-radius:var(--r-md);border:1.5px solid var(--border);background:var(--surface);color:var(--text-sub);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;transition:all .15s;}
/* Ohne diese Regel bleibt der Knopf trotz gesetztem hidden-Attribut sichtbar:
   das display:none fuer [hidden] kommt aus dem Browser-Stylesheet und verliert
   gegen JEDE Autor-Regel mit display — hier gegen das display:flex darueber.
   Der Attribut-Selektor ist spezifischer und gewinnt. */
.detail-section-toggle[hidden]{display:none;}
@media(hover:hover){.detail-section-toggle:hover{border-color:var(--active-accent);color:var(--active-accent);}}
.detail-section-toggle.active{border-color:var(--active-accent);background:var(--active-accent);color:var(--active-accent-text);}
/* Zutaten-Chips unter dem Schritt: gleiche Zuordnung (i.step) wie die
   Nummer-Badges in der Zutatenliste, nur hier direkt am Schritt statt oben
   in der Liste — spart bei langen Rezepten das Hoch- und Runterscrollen. */
.detail-step-ings{display:flex;flex-wrap:wrap;gap:0.35rem;margin-top:0.5rem;}
.detail-step-ing-chip{font-size:calc(0.74rem * var(--detail-zoom, 1));background:var(--surface);border:1.5px solid var(--border);border-radius:99px;padding:0.15rem 0.5rem;color:var(--text-sub);white-space:nowrap;}
.detail-step-ing-chip b{color:var(--text);font-weight:700;}
.detail-step-row.done .detail-step-ing-chip{opacity:0.5;text-decoration:line-through;}
/* Zutaten/Zubereitung-Überschriften wachsen mit der Schriftgrößen-Lupe mit
   (Portionen bewusst ausgenommen — die Zeile hat eigene Stepper-Steuerung). */
#detail-ingredients-label,#detail-steps-label{font-size:calc(0.86rem * var(--detail-zoom, 1));}
/* Rahmen in der vollen Primaerfarbe, aber ohne Sockel/Schatten: der Kasten
   wird auf- und zugeklappt, gedrueckt wird er nicht — nur was einsinken kann,
   traegt einen Sockel. */
#detail-verlauf-label{margin:1.4rem 0 0;border:1.5px solid var(--primary);border-radius:var(--r-lg);background:var(--surface);box-shadow:none;padding:0.7rem 0.85rem;}
#detail-verlauf-label summary{display:flex;align-items:center;justify-content:space-between;gap:0.6rem;font-family:'Literata',Georgia,serif;font-size:0.86rem;font-weight:600;color:var(--text);letter-spacing:-0.005em;text-transform:none;cursor:pointer;list-style:none;padding:0;}
#detail-verlauf-label summary::-webkit-details-marker{display:none;}
#detail-verlauf-label summary::after{content:'';color:var(--active-accent);transition:transform .15s;display:inline-block;width:14px;height:14px;flex-shrink:0;background:currentColor;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.31' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 6 6 6-6 6'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.31' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 6 6 6-6 6'/%3E%3C/svg%3E") center/contain no-repeat;transition:transform .15s;}
#detail-verlauf-label[open] summary::after{transform:rotate(90deg);}

/* ── Verlauf ────────────────────────────────────────────────── */
.history-entry{background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-lg);padding:0.6rem 0.8rem;margin-bottom:0.6rem;}
.hist-head{display:flex;align-items:center;gap:0.5rem;margin-bottom:0.3rem;}
.hist-date{font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.76rem;font-weight:700;color:var(--text);flex:1;font-variant-numeric:tabular-nums;}
.card-edit{background:none;border:none;color:var(--text-sub);cursor:pointer;font-size:0.85rem;padding:0.15rem 0.35rem;border-radius:var(--r-md);flex-shrink:0;}
@media(hover:hover){.card-edit:hover{color:var(--rezept);}}
.icon-del{color:var(--err-text);}
@media(hover:hover){.card-edit.icon-del:hover,.catm-del.icon-del:hover{color:var(--err-border);}}
.hist-note{font-size:0.84rem;color:var(--text);line-height:1.5;margin-bottom:0.3rem;white-space:pre-wrap;}
.hist-ratings{display:flex;gap:0.6rem;flex-wrap:wrap;margin-bottom:0.3rem;font-size:0.9rem;color:var(--star);}
.changelog-line{font-size:0.76rem;color:var(--text-sub);margin-bottom:0.15rem;}
.changelog-line s{opacity:0.7;}
.hist-images{display:flex;gap:0.4rem;flex-wrap:wrap;margin-top:0.4rem;}
.hist-images img{width:52px;height:52px;object-fit:cover;border-radius:var(--r-xs);border:1px solid var(--border);cursor:pointer;}
details.field summary{cursor:pointer;font-size:0.82rem;color:var(--text-sub);font-weight:600;padding:0.2rem 0;}
@media(hover:hover){details.field summary:hover{color:var(--rezept);}}

/* ── Farb-Picker ────────────────────────────────────────────── */
.rt-color-wrap{position:relative;}
.rt-color-trigger{width:2rem;height:2rem;border-radius:var(--r-md);border:1.5px solid var(--border);cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center;background:var(--surface);}
.rt-color-trigger .swatch{width:1.15rem;height:1.15rem;border-radius:var(--r-xs);border:1px solid #0003;}
/* Standard: rechtsbündig zum Trigger öffnen, damit die Palette im Modal bleibt
   und keinen horizontalen Überlauf/Scrollbalken erzeugt. */
.rt-palette{position:absolute;bottom:calc(100% + 0.4rem);right:0;left:auto;transform:none;background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.5rem;display:none;z-index:20;box-shadow:0 6px 20px #0006;}
.rt-palette.open{display:block;}
.rt-palette.align-left{left:0;right:auto;transform:none;}
.rt-palette.align-right{left:auto;right:0;transform:none;}
.rt-palette.open-below{bottom:auto;top:calc(100% + 0.4rem);}
.rt-palette-row{display:flex;gap:0.28rem;margin-bottom:0.28rem;}
.rt-palette-row:last-child{margin-bottom:0;}
.rt-swatch{width:1.5rem;height:1.5rem;border-radius:var(--r-xs);border:1.5px solid #0003;cursor:pointer;padding:0;}
@media(hover:hover){.rt-swatch:hover{transform:scale(1.12);}}
.rt-swatch.bw{border:1.5px solid var(--border);}

/* ── Kategorien / Mengen verwalten ──────────────────────────── */
.catm-row{display:flex;align-items:center;justify-content:space-between;padding:0.45rem 0.2rem;border-bottom:1px solid var(--border);font-size:0.85rem;}
.catm-row:last-child{border-bottom:none;}
.catm-del{background:none;border:none;color:var(--text-sub);cursor:pointer;font-size:0.85rem;padding:0.2rem 0.4rem;}
@media(hover:hover){.catm-del:hover{color:var(--err-text);}}
.catm-new{display:flex;gap:0.5rem;align-items:stretch;margin-top:0.8rem;flex-wrap:wrap;}
.catm-new input{flex:1;min-width:8rem;background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.6rem 0.8rem;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.9rem;outline:none;transition:border-color .2s;}
.catm-new input:focus{border-color:var(--rezept);}
.catm-new .rt-color-trigger{height:100%;width:2.4rem;}
.catm-new .cat-add-btn{flex-shrink:0;}
/* Quadratisch und gleich gross — im Bearbeiten-Modus kommt der Abbrechen-
   Button dazu, ein breiter Textbutton hat die Zeile dort umbrechen lassen. */
#catm-submit-btn,#unitm-submit-btn,#catm-cancel-btn,#unitm-cancel-btn{width:2.4rem;padding:0;align-items:center;justify-content:center;font-size:1.1rem;}
/* Haken-Glyph gleich gross wie bei der Mitesser-Auswahl (.pc-checkbox-box,
   0.8rem) statt der groesseren 1.1rem vom ✕-Abbrechen-Button nebenan — sonst
   wirkten die beiden Haken in der App unterschiedlich gross. line-height:1
   nimmt der Schriftart den ungleichen Zeilenraum uebers/unters Zeichen, der
   das ✓ sonst trotz justify-content:center optisch nach oben verschob. */
#catm-submit-btn,#unitm-submit-btn{font-size:0.8rem;line-height:1;}
/* Speichern-Haken: gefuellt (Farben umgedreht ggue. dem gestrichelten ＋). */
.catm-save-btn{display:flex;border:none;border-radius:var(--r-md);background:var(--active-accent);color:var(--active-accent-text);font-weight:700;}
@media(hover:hover){.catm-save-btn:hover{filter:brightness(1.08);}}
/* Zuordnen-Bereich bei fremden Rezepten: Chips brauchen etwas Luft nach unten,
   sonst kleben sie bei Umbruch aneinander. */
#detail-cat-picker{gap:0.4rem 0.4rem;row-gap:0.45rem;padding:0.5rem 0;border-top:1px solid var(--border);}
#detail-cat-picker .cat-chip{margin:0;}

/* ── Haushalt / Profil ──────────────────────────────────────── */
/* Abstand für gestapelte Eingabefelder in diesen Modals (Styling kommt vom
   globalen Input-Regelsatz oben). */
#household-modal input, #household-edit-modal input, #share-modal input{margin-bottom:0.6rem;}
#profile-modal .btn-primary{margin-top:0.4rem;}

#household-list .household-item{background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-lg);padding:0.7rem 0.85rem;margin-bottom:0.7rem;}
.hh-item-head{display:flex;align-items:center;gap:0.5rem;font-weight:700;font-size:0.95rem;margin-bottom:0.15rem;}
.hh-item-code{font-size:0.76rem;color:var(--text-sub);font-family:'Instrument Sans',system-ui,sans-serif;margin-bottom:0.5rem;}
.hh-item-code button{background:none;border:none;color:var(--rezept);cursor:pointer;font-size:0.72rem;padding:0.1rem 0.3rem;}
.pending-request{display:flex;align-items:center;justify-content:space-between;gap:0.6rem;padding:0.4rem 0;font-size:0.85rem;}
.pending-request button{padding:0.35rem 0.7rem;font-size:0.8rem;flex-shrink:0;border-radius:var(--r-xs);border:none;background:var(--primary);color:var(--primary-text);font-weight:600;}
#household-message{font-size:0.82rem;color:var(--text-sub);margin-top:0.4rem;text-align:center;}

/* Mitgliederliste (ausklappbar) */
.hh-members{margin-top:0.4rem;}
.hh-members > summary{cursor:pointer;font-size:0.78rem;letter-spacing:0;text-transform:none;color:var(--text-sub);padding:0.25rem 0;}
.hh-member-row{display:flex;align-items:center;gap:0.5rem;padding:0.35rem 0;font-size:0.88rem;border-top:1px solid var(--border);}
.hh-member-row:first-of-type{border-top:none;}
.hh-member-av{font-size:1.15rem;line-height:1;}
.hh-member-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.hh-member-badge{font-size:0.68rem;color:var(--text-sub);background:var(--surface);border:1px solid var(--border);border-radius:99px;padding:0.05rem 0.4rem;flex-shrink:0;}
/* Pfeil (Text-Glyphe) und Entfernen-Kreuz (SVG) rendern unterschiedlich um
   die Grundlinie — die Glyphe sass tiefer, das SVG hoeher. Beide daher als
   gleich grosse, mittig ausrichtende Kaestchen, dann liegen sie auf einer
   Linie. */
.hh-member-remove,.hh-member-chevron{
  flex-shrink:0;width:1.5rem;height:1.5rem;
  display:inline-flex;align-items:center;justify-content:center;
}
.hh-member-remove{background:none;border:none;color:var(--err-text);cursor:pointer;padding:0;}
.hh-member-remove svg{display:block;}
/* Die Zeile fuehrt ins Profil — der Pfeil macht das sichtbar, ohne sie wie
   einen Knopf aussehen zu lassen. */
.hh-member-row[data-member-uid]{cursor:pointer;}
@media(hover:hover){.hh-member-row[data-member-uid]:hover{background:var(--surface);}}
.hh-member-chevron{color:var(--text-sub);font-size:1rem;line-height:1;}

/* ── Mitglieder-Profil ─────────────────────────────────────── */
.mp-head{display:flex;align-items:center;gap:0.7rem;margin-bottom:0.4rem;}
.mp-avatar{font-size:2rem;line-height:1;flex-shrink:0;}
.mp-head-text{min-width:0;}
.mp-sub{font-size:0.78rem;color:var(--text-sub);margin-top:0.1rem;}
.mp-section{margin-top:1rem;}
.mp-label{font-size:0.74rem;letter-spacing:0;text-transform:none;color:var(--text-sub);margin-bottom:0.35rem;}
/* Kurzbeschreibung: gibt den Ton vor, ersetzt aber nicht die Zeilen darunter.
   Serifenschrift, damit sie sich als "Stimme" von den Daten absetzt. */
.mp-sentence{font-family:'Literata',Georgia,serif;font-weight:500;font-size:0.92rem;line-height:1.55;color:var(--text);margin:0.8rem 0 0;}
/* Kompakter Steckbrief statt Ueberschrift-plus-Kachel je Angabe: gleiches
   "Label: Werte"-Muster wie bei den Vorlieben weiter unten. */
.mp-facts{margin-top:0.7rem;padding-bottom:0.2rem;}
.mp-fact{font-size:0.85rem;line-height:1.5;margin:0 0 0.2rem;color:var(--text);}
.mp-fact-label{color:var(--text-sub);}
.mp-fact.warn{color:var(--err-text);}
.mp-fact.warn .mp-fact-label{color:var(--err-text);opacity:0.85;}
.mp-section-title{font-size:0.85rem;color:var(--text-sub);margin-bottom:0.3rem;}
.mp-sub-label{font-size:0.75rem;color:var(--text-sub);margin:0.5rem 0 0.3rem;}
.mp-chips{display:flex;flex-wrap:wrap;gap:0.35rem;}
.mp-chip{font-size:0.8rem;padding:0.2rem 0.6rem;border-radius:var(--r-xl);background:var(--surface);border:1px solid var(--border);color:var(--text);}
.mp-chip.diet{background:var(--rezept);border-color:var(--rezept);color:#fff;}
/* Warnfarbe ausschliesslich hier — Unvertraeglichkeiten sind ein echtes
   Risiko, "mag keinen Brokkoli" ist es nicht. */
.mp-chip.warn{background:var(--err);border-color:var(--err);color:var(--err-text);}
.mp-chip.like{border-color:var(--done-text);color:var(--done-text);}
.mp-food-line{font-size:0.82rem;line-height:1.5;margin:0 0 0.3rem;color:var(--text);}
.mp-food-cat{color:var(--text-sub);}
.mp-empty{font-size:0.82rem;color:var(--text-sub);margin:0;}
.mp-details{margin-top:1rem;border-top:1px solid var(--border);border-bottom:1px solid var(--border);padding:0.6rem 0 0.7rem;}
.mp-details>summary{font-size:0.85rem;color:var(--text-sub);cursor:pointer;list-style:none;user-select:none;display:flex;align-items:center;gap:0.4rem;}
.mp-details>summary::-webkit-details-marker{display:none;}
.mp-count{margin-left:auto;font-size:0.75rem;color:var(--text-sub);}
.mp-fav-group{margin-bottom:0.5rem;}
/* Feste Dreier-Spalten statt Flex mit fester Kachelbreite: mehr als drei
   kann es nie geben, also darf die Reihe die volle Breite nutzen — vorher
   blieb rechts immer ein toter Rand stehen. */
.mp-fav-list{display:grid;grid-template-columns:repeat(3,1fr);gap:0.5rem;}
.mp-fav-card{border:1px solid var(--border);border-radius:var(--r-md);overflow:hidden;background:var(--surface);}
.mp-fav-img{position:relative;aspect-ratio:1;}
.mp-fav-img img{width:100%;height:100%;object-fit:cover;display:block;cursor:zoom-in;}
/* Ohne Foto steht die Platzziffer gross in der Kachel — leere graue Flaechen
   sahen nach "hier fehlt was" aus, die Ziffer traegt wenigstens Information. */
.mp-fav-img.placeholder{display:flex;align-items:center;justify-content:center;background:var(--surface);}
.mp-fav-rank-big{font-size:1.6rem;font-weight:700;line-height:1;color:var(--rezept);opacity:0.5;}
.mp-fav-rank{position:absolute;left:4px;bottom:4px;width:1.1rem;height:1.1rem;border-radius:50%;background:rgba(0,0,0,0.62);color:#fff;font-size:0.65rem;display:flex;align-items:center;justify-content:center;line-height:1;}
/* Marken- und Sortennamen sind oft ein langes Wort ("Rhabarberschorle") —
   ohne Umbruch wird es an der Kartenkante abgeschnitten. */
.mp-fav-text{display:block;font-size:0.72rem;padding:0.3rem 0.4rem;line-height:1.25;overflow-wrap:anywhere;hyphens:auto;}
/* Hinweis-Knopf auf der Kachel. Der Text selbst steht in der Sprechblase
   unter der Reihe — so bleiben alle Kacheln gleich hoch, egal wie lang die
   Erlaeuterung ist. */
.mp-fav-card{position:relative;}
.mp-fav-info{position:absolute;top:3px;right:3px;width:1.15rem;height:1.15rem;padding:0;border:none;border-radius:50%;background:rgba(0,0,0,0.55);color:#cfe0f8;display:flex;align-items:center;justify-content:center;cursor:pointer;}
.mp-fav-info svg{width:12px;height:12px;}
.mp-fav-info.active{background:var(--rezept);color:var(--primary-text);}
/* Schlichte Notizzeile statt Sprechblase — gleiche stille Optik wie die
   Zutaten-Hinweise (.mp-food-line), kein Kasten, kein Zeiger. Die Kachel
   selbst traegt den Bezug ueber den farbigen Rahmen. */
.mp-fav-notetext{font-size:0.78rem;line-height:1.5;color:var(--text-sub);font-style:italic;margin:0.6rem 0 0;}
.mp-fav-card.note-open{border-color:var(--rezept);}
/* Bewertungsstufe: Symbol plus fetter Text, damit sie sich klar von den
   Kategorie-Zeilen ("Obst: …") darunter absetzt. */
.mp-rating-head{display:flex;align-items:center;gap:0.35rem;font-size:0.82rem;font-weight:700;color:var(--text);margin:0.7rem 0 0.25rem;}
.mp-rating-head:first-of-type{margin-top:0.4rem;}
.mp-rating-head img{width:1rem;height:1rem;flex-shrink:0;}

/* ── Präferenzen: Abschnitte ───────────────────────────────── */
.prefs-section{padding-top:1rem;margin-top:1rem;border-top:1px solid var(--border);}
.prefs-section:first-child{padding-top:0;margin-top:0;border-top:none;}
.prefs-section-title{font-size:0.95rem;font-weight:700;color:var(--rezept);margin:0 0 0.15rem;}

/* ── Favoriten-Editor ──────────────────────────────────────── */
.fav-group{margin-bottom:0.9rem;}
.fav-group-label{font-size:0.75rem;color:var(--text-sub);margin-bottom:0.3rem;}
.fav-row{display:flex;align-items:center;gap:0.45rem;margin-bottom:0.35rem;}
/* Platzziffer dezent — beim Eintragen reicht der Hinweis, dass es eine
   Reihenfolge gibt; in der Profil-Ansicht wird sie dann deutlich gezeigt. */
.fav-rank{font-size:0.72rem;color:var(--text-sub);width:0.9rem;flex-shrink:0;text-align:right;}
.fav-text{flex:1;min-width:0;}
/* Noch leere Zeile gestrichelt — dasselbe Signal wie bei den Zutaten. */
.fav-row:not(.filled) .fav-text{border-style:dashed;}
.fav-thumb{position:relative;width:2.4rem;height:2.4rem;flex-shrink:0;border:1.5px dashed var(--border);border-radius:var(--r-md);background:transparent;color:var(--text-sub);cursor:pointer;font-size:0.95rem;display:flex;align-items:center;justify-content:center;padding:0;overflow:visible;}
.fav-thumb.has-img{border-style:solid;}
.fav-thumb img{width:100%;height:100%;object-fit:cover;border-radius:var(--r-xs);}
.fav-thumb.placeholder{opacity:0.4;cursor:default;}
.fav-thumb-x{position:absolute;top:-5px;right:-5px;width:1.05rem;height:1.05rem;border-radius:50%;background:var(--err);color:var(--err-text);font-size:0.6rem;display:flex;align-items:center;justify-content:center;line-height:1;}
.fav-remove{background:none;border:none;color:var(--err-text);cursor:pointer;font-size:0.85rem;flex-shrink:0;padding:0.1rem 0.3rem;}
/* Hinweis-Knopf und -Feld wie bei den Zutaten (.ing-note-*). */
.fav-note-btn{background:none;border:none;color:var(--text-sub);cursor:pointer;flex-shrink:0;padding:0.2rem 0.2rem;display:flex;align-items:center;opacity:0.6;transition:opacity .15s,color .15s;}
@media(hover:hover){.fav-note-btn:hover{opacity:1;color:var(--rezept);}}
.fav-note-btn.active{opacity:1;color:var(--rezept);}
.fav-row{flex-wrap:wrap;}
.fav-note-input{flex-basis:100%;width:100%;order:9;margin-left:1.35rem;font-size:0.8rem;}

/* Haushalts-Icon-Auswahl (8 pro Zeile, kompakt wie beim Profil) */
.hh-icon-picker{display:flex;flex-wrap:wrap;gap:0.4rem;margin:0.4rem 0 0.2rem;}
.hh-icon-opt{width:2.6rem;height:2.6rem;flex:0 0 auto;font-size:1.15rem;display:flex;align-items:center;justify-content:center;padding:0;border-radius:50%;border:2px solid transparent;background:var(--surface);cursor:pointer;line-height:1;}
.hh-icon-opt.selected{border-color:var(--active-accent);background:var(--surface);}
.hh-item-actions{display:flex;gap:0.5rem;margin-top:0.6rem;}
.hh-item-actions button{flex:1;padding:0.5rem;border-radius:var(--r-md);font-size:0.82rem;font-weight:600;cursor:pointer;}
.hh-btn-leave{background:transparent;border:1.5px solid var(--border);color:var(--text-sub);}
/* Einladung teilen: direkt unter dem Code, weil beides zusammengehoert. */
/* Code und Weitergeben nebeneinander: beides sind Wege, jemanden reinzuholen.
   Auf schmalen Handys bricht die zweite Spalte darunter, statt beides zu
   quetschen — der Code muss lesbar bleiben. */
.hh-invite-row{display:flex;flex-wrap:wrap;gap:0.6rem;margin-bottom:0.6rem;}
.hh-invite-col{flex:1 1 11rem;min-width:0;display:flex;flex-direction:column;}
/* Die Box im Kasten fuellt die Spaltenhoehe, damit beide Spalten unten
   buendig abschliessen. */
.hh-invite-col .hh-code{margin-bottom:0;flex:1;}
/* Rolle: Hauptaktion (Style 1, voll gefuellt) — Form, Farbe und Sockel kommen
   von .btn-primary. Hier nur noch Layout: Symbol + Text mittig, und der
   obere Abstand faellt weg, weil der Knopf in einer beschrifteten Spalte
   neben dem Einladungscode-Kaestchen sitzt. */
.hh-share-btn{display:flex;align-items:center;justify-content:center;gap:0.4rem;margin-top:0;}
@media(hover:hover){.hh-btn-leave:hover{border-color:var(--err-border);color:var(--err-text);}}
.hh-btn-delete{background:transparent;border:1.5px solid var(--err-border);color:var(--err-text);}
@media(hover:hover){.hh-btn-delete:hover{background:var(--err);}}

/* Entweder-Oder: Haushalt hinzufügen */
.hh-pending-item{border-style:dashed;}
.hh-pending-note{font-size:0.82rem;color:var(--text-sub);padding:0.2rem 0 0.1rem;}
.hh-add-hint{font-size:0.82rem;color:var(--text-sub);margin:0.4rem 0 0.6rem;text-align:center;}
.hh-add-choice{display:flex;gap:0.6rem;margin-bottom:0.6rem;}
.hh-choice-btn{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;gap:0.35rem;padding:0.8rem 0.5rem;border-radius:var(--r-lg);border:1.5px solid var(--border);background:var(--surface);color:var(--text);font-weight:600;font-size:0.82rem;line-height:1.25;text-align:center;cursor:pointer;transition:all .15s;}
.hh-choice-btn .hh-choice-icon{font-size:1.4rem;line-height:1;display:flex;align-items:center;justify-content:center;}
.hh-choice-btn .hh-choice-icon svg{display:block;}
@media(hover:hover){.hh-choice-btn:hover{border-color:var(--active-accent);}}
.hh-choice-btn.active{border-color:var(--active-accent);background:var(--surface);color:var(--active-accent);}
.hh-choice-btn.dimmed{opacity:0.4;}
.hh-add-panel{margin-top:0.2rem;}
.hh-add-panel button.btn-primary{margin-top:0.2rem;}
.hh-add-max{text-align:center;font-size:0.82rem;color:var(--text-sub);padding:0.6rem;border:1px dashed var(--border);border-radius:var(--r-md);}

.share-hh-row{display:flex;align-items:center;justify-content:space-between;gap:0.6rem;padding:0.5rem 0;border-bottom:1px solid var(--border);font-size:0.88rem;}
.share-hh-row:last-child{border-bottom:none;}

/* Avatar-Button im Header */
button#hdr-avatar{font-size:1.4rem;line-height:1;background:none;border:none;padding:0;cursor:pointer;}

/* Haushalt: Kopf mit Bearbeiten-Icon */
.hh-item-head{display:flex;align-items:center;gap:0.5rem;font-weight:700;font-size:1rem;margin-bottom:0.4rem;}
.hh-item-head .hh-item-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.hh-edit-btn{background:none;border:none;color:var(--text-sub);cursor:pointer;padding:0.2rem;border-radius:var(--r-md);display:flex;align-items:center;flex-shrink:0;}
@media(hover:hover){.hh-edit-btn:hover{color:var(--rezept);background:var(--surface);}}

/* Haushalt: Einladungscode zum Kopieren */
.hh-code{display:flex;align-items:center;gap:0.6rem;background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.4rem 0.7rem;margin-bottom:0.6rem;cursor:pointer;transition:border-color .15s,background .15s;}
@media(hover:hover){.hh-code:hover{border-color:var(--rezept);}}
.hh-code:active{background:var(--surface);}
.hh-code-label{font-size:0.74rem;letter-spacing:0;text-transform:none;color:var(--text-sub);}
.hh-code-val{flex:1;font-family:'Instrument Sans',system-ui,sans-serif;font-size:1rem;font-weight:700;letter-spacing:0.12em;color:var(--text);}
.hh-code-copy{color:var(--text-sub);display:flex;align-items:center;flex-shrink:0;}
@media(hover:hover){.hh-code:hover .hh-code-copy{color:var(--rezept);}}

/* Teilen per Code: eigener Abschnitt unter der Haushalts-Freigabe im
   share-modal, gleiche Optik wie der Haushalts-Einladungscode (.hh-code). */
.share-section .theme-group-label{margin-bottom:0.5rem;}
/* Bewusst KEIN border-top hier (mehr Abstand statt Linie): die duenne
   Trennlinie zwischen den einzelnen Haushalt-Zeilen (.share-hh-row) sieht
   sonst identisch aus wie die Trennung zwischen den beiden ganzen
   Abschnitten — obwohl das zwei ganz unterschiedliche Ebenen sind. Der
   Abschnitts-Titel in Grossbuchstaben markiert den neuen Bereich schon klar
   genug. */
.share-code-section{margin-top:1.3rem;}
/* Antippen zum Kopieren statt eigenem "Code kopieren"-Button - gleiche
   Interaktion UND Layout wie .hh-code beim Haushalts-Einladungscode: Text
   linksbuendig (flex:1), Icon rechtsbuendig am Rand, nicht mittig. */
.share-code-box{display:flex;align-items:center;gap:0.6rem;background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-lg);padding:0.6rem 0.8rem;margin:0.6rem 0;cursor:pointer;transition:border-color .15s,background .15s;}
@media(hover:hover){.share-code-box:hover{border-color:var(--rezept);}}
.share-code-value{flex:1;font-family:'Instrument Sans',system-ui,sans-serif;font-size:1.3rem;font-weight:700;letter-spacing:0.15em;color:var(--text);}
.share-code-copy{color:var(--text-sub);display:flex;align-items:center;flex-shrink:0;}
@media(hover:hover){.share-code-box:hover .share-code-copy{color:var(--rezept);}}

/* Code einloesen: Vorschau-Karte, die nach Eingabe eines gueltigen Codes
   unter dem Eingabefeld erscheint, bevor tatsaechlich importiert wird.
   Gestrichelter Rand wie bei einem leeren Schritt/einer leeren Zutat — hier
   als Signal "noch nicht importiert, nur Vorschau". Kaum margin-top: die
   leere #redeem-code-msg darueber (margin-top .7rem + min-height 1rem)
   liefert davor schon genug Abstand, ein eigener Top-Abstand haeufte sich
   sonst oben drauf. margin-bottom dagegen gezielt, weil .btn-primary
   darunter (inline-block) nicht mit dieser Box kollabiert, sondern sich
   addiert — sonst klebte "Importieren" fast an der Karte. */
.redeem-preview{margin:0.1rem 0 0.7rem;padding:0.7rem;background:var(--surface);border:1.5px dashed var(--border);border-radius:var(--r-lg);}
.redeem-preview img{width:100%;aspect-ratio:1.6;object-fit:cover;border-radius:var(--r-md);margin-bottom:0.55rem;display:block;background:var(--bg);}
.redeem-preview-title{font-family:'Literata',Georgia,serif;font-weight:600;font-size:1.05rem;font-weight:500;color:var(--text);margin-bottom:0.2rem;}
.redeem-preview-meta{font-size:0.78rem;color:var(--text-sub);}
/* "Code einloesen" oeffnet jetzt ueber dem Einstiegsbildschirm (der bleibt
   offen), damit der Zurueck-Knopf im Fuss wie beim Import zur Auswahl
   zurueckfuehrt. Auf dem Handy die Box als Spalte, Fuss unten angedockt. */
@media(max-width:600px){
  #redeem-code-modal .modal-box{display:flex;flex-direction:column;}
  #redeem-code-modal .wizard-footer{margin-top:auto;}
}

/* Toast (Kopiert-Meldung) */
#app-toast{position:fixed;left:50%;bottom:2rem;transform:translateX(-50%) translateY(1rem);background:var(--surface);border:1.5px solid var(--rezept);color:var(--text);font-size:0.85rem;font-weight:600;padding:0.6rem 1.1rem;border-radius:99px;box-shadow:0 6px 20px #0007;opacity:0;pointer-events:none;transition:opacity .2s,transform .2s;z-index:400;white-space:nowrap;max-width:calc(100vw - 1.5rem);overflow:hidden;text-overflow:ellipsis;}
#app-toast.show{opacity:1;transform:translateX(-50%) translateY(0);}

/* Haushalt-Editor: Name + aktuelles Icon nebeneinander */
.hh-name-row{display:flex;gap:0.5rem;align-items:stretch;}
.hh-name-row input{flex:1;min-width:0;margin-bottom:0!important;}
.hh-icon-current{width:2.55rem;flex-shrink:0;align-self:stretch;display:flex;align-items:center;justify-content:center;font-size:1.15rem;background:var(--btn-face2);border:1.5px solid var(--btn-edge2);border-radius:50%;}

/* Profil-Modal */
.pf-field{margin-bottom:1.1rem;}
.pf-field > label{display:block;font-size:0.78rem;font-weight:600;letter-spacing:0;text-transform:none;color:var(--text);margin-bottom:0.45rem;}
.pf-note{font-size:0.78rem;color:var(--text-sub);margin:0 0 0.9rem;}
/* Wie ein Eingabefeld gestaltet, aber ohne Interaktion — signalisiert "hier
   steht ein Wert", ohne einen Tipp-Cursor oder Rahmen-Fokus zu versprechen. */
.pf-static-value{background:var(--field);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.6rem 0.8rem;color:var(--text-sub);font-size:0.9rem;overflow-wrap:anywhere;}
/* Badge + direkte Text-Buttons fuer "Was ist neu?"/Feedback statt eines
   Umwegs ueber ein eigenes Zwischen-Fenster (og-modal, entfernt). Bewusst
   ohne Icons (sparte die Container-Query-Umschaltung auf Icon-only, die auf
   manchen Geraeten nicht griff und die Zeile ueber den Bildschirmrand
   hinauslaufen liess) — reiner Text ist schon kompakt genug fuer eine
   Zeile. flex-wrap bleibt als Sicherheitsnetz: reicht der Platz trotzdem
   nicht (z.B. sehr altes/schmales Geraet), bricht es sauber um statt
   seitlich abzuschneiden. */
.pf-og-row{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:0.5rem;margin-bottom:1rem;}
.pf-og-label{display:inline-flex;align-items:center;gap:0.35rem;font-size:0.74rem;font-weight:600;color:var(--star);background:var(--surface);border:1.5px solid var(--star);border-radius:99px;padding:0.28rem 0.7rem;white-space:nowrap;}
.pf-og-actions{display:flex;flex-wrap:wrap;flex-shrink:0;gap:0.4rem;}
.pf-og-action-btn{display:inline-flex;align-items:center;height:2rem;padding:0 0.65rem;border-radius:var(--r-md);border:1.5px solid var(--border);background:var(--border);color:var(--rezept);cursor:pointer;font-size:0.76rem;font-weight:600;transition:opacity .15s;}
@media(hover:hover){.pf-og-action-btn:hover{opacity:0.8;}}

.fb-kind-row{display:flex;gap:0.5rem;}
/* Als einziger Icon-Knopf der App stand der hier auf display:block: das SVG
   sass inline auf der Textgrundlinie und hing dadurch tiefer als die Schrift,
   der Abstand kam aus einem Leerzeichen im Markup. Jetzt wie ueberall sonst
   (.status-chip, .import-way-head) ueber flex zentriert, mit echtem gap. */
.fb-kind{
  flex:1;display:inline-flex;align-items:center;justify-content:center;gap:0.4rem;
  padding:0.55rem 0.5rem;border:1.5px solid var(--border);border-radius:var(--r-md);
  background:var(--surface);color:var(--text-sub);
  font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.82rem;font-weight:600;
  cursor:pointer;transition:border-color .15s,color .15s;
}
.fb-kind svg{flex-shrink:0;}
.fb-kind.active{border-color:var(--active-accent);color:var(--active-accent);}
#feedback-modal select{width:100%;background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.6rem 0.8rem;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.9rem;outline:none;}
#feedback-modal select:disabled{opacity:0.5;}
#feedback-modal textarea{width:100%;background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.6rem 0.8rem;color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.9rem;outline:none;resize:vertical;}

/* ── Release Notes ──────────────────────────────────────── */
.cl-empty{font-size:0.8rem;color:var(--text-sub);}
.cl-day{border:1.5px solid var(--border);border-radius:var(--r-lg);margin-bottom:0.5rem;background:var(--surface);}
.cl-day summary{display:flex;flex-direction:column;gap:0.3rem;padding:0.6rem 0.75rem;cursor:pointer;font-size:0.82rem;list-style:none;transition:background .12s;border-radius:var(--r-sm);}
.cl-day summary::-webkit-details-marker{display:none;}
@media(hover:hover){.cl-day summary:hover{background:var(--surface);}}
.cl-summary-head{display:flex;align-items:center;gap:0.5rem;width:100%;}
/* Zeichen-Tausch statt Rotation — robust in allen Browsern. */
.cl-chevron{flex-shrink:0;color:var(--rezept);font-weight:700;font-size:0.95rem;line-height:1;}
.cl-date{font-weight:700;color:var(--text);}
/* KEIN margin-left:auto: das hat mit dem gleichen auto am Chevron um den
   freien Platz gestritten, dadurch trieb die Zahl irgendwo in die Mitte.
   Die Zahl steht direkt hinter dem Datum, den Rest schiebt der Chevron. */
.cl-count{font-size:0.7rem;color:var(--text-sub);background:var(--surface2);border:1px solid var(--border);border-radius:99px;padding:0.1rem 0.45rem;flex-shrink:0;}
/* Zweite Zeile der Kopfzeile: der Titel des Tages. Er bleibt beim Aufklappen
   stehen und ist dort die Ueberschrift ueber den Gruppen — deshalb wird er im
   Body nicht wiederholt. Aufgeklappt darf er ueber mehr als zwei Zeilen
   laufen, eingeklappt bleibt die Vorschau begrenzt. Tage ohne Titel zeigen
   ersatzweise alle Punkte als Fliesstext. */
.cl-summary-text{color:var(--text-sub);font-size:0.76rem;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.cl-day[open]>summary .cl-summary-text{-webkit-line-clamp:none;color:var(--text);font-weight:700;}
.cl-body{padding:0 0.75rem 0.6rem;}
.cl-group{margin-top:0.4rem;}
.cl-tag{display:inline-block;font-size:0.65rem;font-weight:700;text-transform:uppercase;letter-spacing:0.04em;border-radius:99px;padding:0.1rem 0.35rem;}
.cl-tag-new{color:var(--done-text);border:1px solid var(--done-text);}
.cl-tag-improved{color:var(--text-sub);border:1px solid var(--text-sub);}
.cl-tag-fix{color:var(--rezept);border:1px solid var(--rezept);}
.cl-body ul{margin:0.35rem 0 0;padding-left:1.1rem;}
.cl-body li{font-size:0.79rem;color:var(--text-sub);line-height:1.45;margin-bottom:0.25rem;}
/* Abzeichen fuer Punkte, die nur ein System betrafen — gefuellt, hinter dem
   Text. Die Schriftfarbe ist --primary-text und nicht fest weiss: in den hellen
   Themes IST das weiss, im dunklen Theme ist --rezept aber ein helles Blau, auf
   dem weisse Schrift nur rund 2:1 Kontrast haette und damit kaum lesbar waere.
   --primary-text ist genau dafuer da und wird auch von .btn-primary benutzt. */
.cl-plattform{display:inline-block;font-size:0.6rem;font-weight:700;letter-spacing:0.03em;color:var(--primary-text);background:var(--rezept);border-radius:99px;padding:0.05rem 0.35rem;margin-left:0.35rem;vertical-align:1px;white-space:nowrap;}
/* Protokoll-Haekchen im Melde-Dialog — gleiche Optik wie die uebrigen
   eigenen Kaestchen in der App. */
.fb-protokoll{position:relative;display:flex;align-items:flex-start;gap:0.55rem;margin:0.9rem 0 0.2rem;font-size:0.82rem;cursor:pointer;}
.fb-protokoll input{position:absolute;opacity:0;width:1.2rem;height:1.2rem;margin:0;cursor:pointer;}
.fb-protokoll-box{width:1.2rem;height:1.2rem;border-radius:var(--r-lg);border:1.5px solid var(--border);flex-shrink:0;margin-top:0.05rem;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:0.72rem;color:transparent;transition:all .12s;}
.fb-protokoll input:checked~.fb-protokoll-box{background:var(--rezept);border-color:var(--rezept);color:var(--primary-text);}
@media(hover:hover){.fb-protokoll:hover .fb-protokoll-box{border-color:var(--rezept);}}
.fb-protokoll small{display:block;color:var(--text-sub);font-size:0.72rem;margin-top:0.1rem;line-height:1.35;}
#profile-modal .btn-primary{margin-top:0;}
.pf-logout-wrap{text-align:center;margin-top:1rem;padding-top:0.8rem;border-top:1px solid var(--border);}
.pf-logout-link{background:none;border:none;color:var(--text-sub);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.78rem;cursor:pointer;padding:0.3rem 0.6rem;opacity:0.7;}
@media(hover:hover){.pf-logout-link:hover{color:var(--err-text);opacity:1;}}
/* Profil-Emojis etwas kompakter, damit die Auswahl bündig mit dem Namensfeld abschließt */
#profile-modal .avatar-picker{gap:0.25rem;}
#profile-modal .avatar-opt{font-size:1.05rem;padding:0.15rem;}

/* Avatar-Auswahl im Profil: das Avatar-Icon selbst ist der Auslöser (Stift
   als Badge in der Ecke signalisiert "bearbeitbar"), sitzt in der Namenszeile
   für den Zusammenhang. Volle Auswahl klappt erst per Klick darunter auf. */
.pf-name-row{display:flex;gap:0.5rem;align-items:center;}
.pf-name-row input{flex:1;min-width:0;margin-bottom:0!important;}
.pf-avatar-btn{position:relative;width:2.6rem;height:2.6rem;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:1.5rem;background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-md);cursor:pointer;padding:0;}
@media(hover:hover){.pf-avatar-btn:hover{border-color:var(--rezept);}}
/* Das Stift-Plaettchen ist raus. Es war 9 px gross und damit unter jeder
   Erkennbarkeitsgrenze — man sah einen Farbpunkt. Groesser ging nicht: der
   Kreis hat innen 14 px, und ein Plaettchen, das einen lesbaren Stift traegt,
   waere fast halb so gross wie der Avatar und wuerde das Emoji erschlagen.
   Braucht es auch nicht: der Knopf sitzt neben dem Namensfeld, hat dessen
   Flaeche (--field) und dessen Rahmen — er sieht aus wie ein Bedienelement,
   weil er eins ist. Dazu der Rahmen in der Aktionsfarbe beim Zeigen. */
.pf-avatar-groups{margin-top:-0.6rem;margin-bottom:1.1rem;}

/* Theme-Auswahl — die Farbpunkte sind bewusst fest kodiert (nicht via CSS-Variablen),
   damit jeder Punkt immer die Farbe SEINES Themes zeigt, egal welches gerade aktiv ist. */
.theme-groups{display:flex;flex-direction:column;gap:0.9rem;}
/* Basic (die beiden Grundthemes) als eigene, prominentere Zeile ganz oben —
   sonst gehen sie optisch in der Liste der Farbvarianten unter, obwohl sie
   die einzigen mit der zweiten Markenfarbe sind. */
.theme-basic-row{display:grid;grid-template-columns:1fr 1fr;gap:0.5rem;}
.theme-basic-row .theme-swatch{padding:0.75rem 0.85rem;font-size:0.82rem;}
.theme-section-divider{display:flex;align-items:center;gap:0.6rem;font-size:0.78rem;font-weight:600;letter-spacing:0;text-transform:none;color:var(--text-sub);margin:1.1rem 0 0.5rem;}
.theme-section-divider::before,.theme-section-divider::after{content:'';flex:1;height:1px;background:var(--border);}
.theme-group-label{font-size:0.75rem;font-weight:600;letter-spacing:0;text-transform:none;color:var(--text-sub);margin:0 0 0.4rem;}
.theme-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:0.5rem;}
.theme-swatch{display:grid;grid-template-columns:18px 1fr;align-items:center;gap:0.4rem;padding:0.5rem 0.6rem;border-radius:var(--r-lg);border:2px solid var(--border);background:var(--surface);color:var(--text);font-family:'Instrument Sans',system-ui,sans-serif;font-size:0.76rem;font-weight:600;cursor:pointer;transition:all .15s;text-align:left;}
@media(hover:hover){.theme-swatch:hover{box-shadow:0 0 0 1.5px var(--rezept);}}
.theme-swatch.active{box-shadow:0 0 0 2px var(--active-accent);}
.swatch-dot{display:inline-block;width:18px;height:18px;border-radius:50%;flex-shrink:0;border:1.5px solid;}
#pf-theme-cur-dot{vertical-align:-4px;margin-right:0.5rem;}

/* ── Erstnutzer-Tutorial ────────────────────────────────────── */
.tutorial-overlay{display:none;position:fixed;inset:0;z-index:250;}
.tutorial-overlay.open{display:block;}
/* Der riesige box-shadow dimmt alles ausserhalb des Rahmens ab — kein SVG-Mask
   noetig, funktioniert bei jeder Zielgroesse/-position gleich. */
.tutorial-highlight{position:fixed;border:2px solid var(--rezept);border-radius:var(--r-md);box-shadow:0 0 0 4000px rgba(0,0,0,.6);pointer-events:none;}
.tutorial-card{position:fixed;width:240px;max-width:calc(100vw - 1.6rem);background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-md);padding:0.9rem 1rem;box-shadow:0 8px 28px #0008;}
.tutorial-step-count{font-size:0.78rem;color:var(--text-sub);margin:0 0 0.3rem;font-weight:700;letter-spacing:0;text-transform:none;}
.tutorial-text{font-size:0.86rem;line-height:1.4;margin:0 0 0.8rem;}
.tutorial-actions{display:flex;justify-content:space-between;align-items:center;gap:0.6rem;}
.tutorial-actions .btn-link-sec{margin:0;padding:0.4rem 0.2rem;}
.tutorial-actions .btn-primary{width:auto;margin:0;padding:0.5rem 1rem;}

/* ── Lightbox ───────────────────────────────────────────────── */
#lightbox{display:none;position:fixed;inset:0;background:#000d;z-index:300;align-items:center;justify-content:center;padding:1rem;cursor:zoom-out;}
#lightbox.open{display:flex;}
#lightbox-inner{position:relative;max-width:100%;max-height:100%;line-height:0;}
#lightbox-inner img{display:block;max-width:100%;max-height:calc(100vh - 2rem);border-radius:var(--r-sm);}
#lightbox-badge{bottom:14px;left:14px;}
#lightbox-badge .card-badge{font-size:0.82rem;padding:0.3rem 0.6rem;border-radius:var(--r-sm);}
#lightbox-badge .card-badge-emoji{font-size:0.9rem;}

@page{margin:1.2cm;}
@media print{
  body *{visibility:hidden;}
  #detail-modal.open,#detail-modal.open *{visibility:visible;}
  /* position:absolute holt das Modal an den Seitenanfang, unabhaengig davon
     wo es im DOM zwischen den unsichtbaren Geschwistern steckt. Ohne die
     Ueberschreibung von bottom/height/overflow bleibt aber die Hoehe der
     .modal-overlay-Basisregel (inset:0 + overflow-y:auto) aktiv — dadurch
     wurde alles unterhalb einer Bildschirmseite abgeschnitten statt auf
     Seite 2 umzubrechen. */
  #detail-modal.open{position:absolute;top:0;left:0;right:0;bottom:auto;width:100%;height:auto;overflow:visible;background:#fff;padding:0;display:block;}
  #detail-modal.open .modal-box{border:none;box-shadow:none;max-width:100%;max-height:none;overflow:visible;color:#000;margin:0;padding:0.4rem;background:#fff;}
  #detail-modal.open .modal-close,#detail-modal.open #detail-add-history,#detail-modal.open #detail-edit-btn,#detail-modal.open #detail-print-btn,#detail-modal.open #detail-share-btn,#detail-modal.open #detail-verlauf-label,#detail-modal.open #detail-servings-label,#detail-modal.open .servings-stepper,#detail-modal.open #detail-del-btn,#detail-modal.open #detail-zoom-row,#detail-modal.open #detail-prefs-btn,#detail-modal.open #detail-source,#detail-modal.open #detail-marks,#detail-modal.open #detail-cat-picker,#detail-modal.open .cat-add-btn,#detail-modal.open #detail-step-ing-toggle{display:none!important;}
  .print-only-line{display:block;}
  /* Kopfbereich wie in der App (Headline, Bewertungen, Angelegt von,
     Kategorie, Zeiten, Schwierigkeitsgrad, Portionen) links in einem
     eigenen Wrapper, Titelbild + QR-Code der Quelle rechts in einem
     zweiten. Die Bildspalte spannt bewusst genau 2 Zeilen (Kopfbereich +
     Zutaten), damit Zutaten direkt neben/unter dem Bild in der freien
     linken Spalte weiterlaufen statt erst unterhalb des Bildes zu beginnen
     — anders als der fruehere, hier mal verworfene Ansatz mit mehreren
     einzeln GERATENEN Zeilen-Spans (das erzeugte bei zu hoch geschaetzten
     Spans eine leere zweite Seite): hier spannt nur EIN Element ueber
     GENAU 2 auto-groesse Zeilen, die Zeilenhoehe bleibt also weiterhin exakt
     am tatsaechlichen Inhalt (Kopf+Zutaten bzw. Bild, je nachdem was hoeher
     ist) statt an einer geratenen festen Groesse. Zubereitung bleibt danach
     als dritte Zeile ueber die volle Breite. */
  #detail-modal.open .modal-box{display:grid;grid-template-columns:1fr 1fr;column-gap:1.5rem;align-items:start;}
  #detail-modal.open #detail-print-left{grid-column:1;}
  #detail-modal.open #detail-print-right{grid-column:2;grid-row:span 2;}
  #detail-modal.open #detail-preptime{display:block!important;}
  #detail-modal.open .detail-cover-wrap{margin-bottom:0.5rem;}
  /* Im Ausdruck nur das Titelbild (erste Kachel), ganz statt Ausschnitt —
     dort stoert ein Wasserzeichen nicht, und Papier hat Platz. Kein
     Wisch-Streifen, keine Punkte. */
  #detail-modal.open .detail-cover-track{display:block;overflow:visible;height:auto;}
  #detail-modal.open .detail-cover-track>.cover-slide:not(:first-child){display:none;}
  #detail-modal.open .detail-cover-track img{height:auto;max-height:12rem;object-position:center;transform:none;}
  #detail-modal.open .detail-cover-dots{display:none;}
  #detail-modal.open #detail-ingredients-label,
  #detail-modal.open #detail-ingredients{grid-column:1;}
  #detail-modal.open #detail-steps-label,
  #detail-modal.open #detail-steps{grid-column:1/-1;}
  /* Ueberschriften (Zutaten/Zubereitung) in derselben Akzentfarbe wie der
     Rezeptname, statt im normalen Fliesstext-Schwarz. */
  #detail-modal.open .detail-section-label{color:var(--rezept);}
  /* Sonst ueberall echtes Schwarz statt der Theme-Grautoene (--text/--text-sub
     bleiben sonst auch im Ausdruck theme-abhaengig eingefaerbt, wirkt dann
     wie ein blasses Grau statt sattem Schwarz). */
  #detail-modal.open .detail-info-line,
  #detail-modal.open .ing-detail-amt,
  #detail-modal.open .ing-detail-name,
  #detail-modal.open .detail-step-text,
  #detail-modal.open #detail-preptime{color:#000;}
  /* Kein Titelbild -> .detail-cover-wrap bleibt leer (Kind-Elemente sind
     display:none) und faellt auf ~0 Hoehe zusammen, der QR-Code landet
     dadurch von selbst ganz oben in der rechten Spalte. */
  #detail-modal.open #detail-print-qr{text-align:right;}
  #detail-modal.open .print-qr-label{font-size:0.7rem;font-weight:600;color:#000;margin:0 0 0.3rem;}
  #detail-modal.open #detail-print-qr svg{width:96px;height:96px;}
  /* Nachkocher-Foto-Badge ("Foto von XYZ") ist auf dem Bildschirm ein
     halbtransparenter Overlay-Pill oben auf dem Bild — im Ausdruck stattdessen
     eine normale Textzeile darunter, linksbuendig. */
  #detail-modal.open #detail-cover-badge{position:static;pointer-events:auto;margin-top:0.3rem;max-width:100%;}
  #detail-modal.open .ing-detail-row,#detail-modal.open .detail-step-row{break-inside:avoid;}
}

/* ── Touch-Geräte: Eingabefelder mindestens 16px ─────────────
   iOS/Safari zoomt beim Antippen automatisch hinein, sobald das fokussierte
   Feld kleiner als 16px ist — und zoomt danach nicht von selbst zurück. Das
   ist kein Einstellungsfehler, sondern fest verdrahtetes Verhalten; der
   einzige verlässliche Gegenzug ist, die Felder auf 16px zu setzen. Bewusst
   nur auf Touch-Geräten, damit das Layout am Rechner unverändert bleibt.

   Die Alternative (maximum-scale im Viewport) würde auf Android das Zoomen
   per Fingergeste ganz unterbinden — für Sehbeeinträchtigte ein echter
   Rückschritt.

   Mit !important und ohne Aufzählung einzelner Felder: mehrere bestehende
   Regeln sind spezifischer (z.B. #auth-view input, .ing-note-input,
   #feedback-modal textarea). Eine Liste müsste bei jedem neuen Feld gepflegt
   werden und bräche still, wenn man es vergisst. Hier gilt ausnahmslos:
   auf Touch nie unter 16px. */
@media (pointer: coarse) {
  input, textarea, select {
    font-size: 16px !important;
  }
  /* Der Ersatz-Platzhalter des Notizenfelds ist ein <div>, kein Feld — er
     muss die 16px hier mitnehmen, sonst wirkt die Vorschau kleiner als der
     Text, den man dann tippt. */
  .notes-ph { font-size: 16px; }
}


/* ── Rezeptkopf: Fakten statt Marken ─────────────────────────
   Kategorie-Chips und Zeitangaben sahen sich vorher zu aehnlich — beide
   klein, beide Pille, beide getoente Flaeche. Die Chips bleiben Pillen, die
   Fakten werden nackter Text mit Symbol. Die Trennung laeuft ueber die Form,
   die Reihenfolge im Kopf bleibt unveraendert. */
.detail-fakten{display:flex;flex-wrap:wrap;align-items:center;gap:0.15rem 0.5rem;margin-bottom:0.3rem;font-size:0.84rem;color:var(--text);}
.detail-fakt,.detail-zeit-btn{display:inline-flex;align-items:center;gap:0.35rem;white-space:nowrap;}
.detail-fakt svg,.detail-zeit-btn svg{color:var(--text-sub);flex-shrink:0;}
.detail-fakt b,.detail-zeit-btn b{font-weight:700;font-variant-numeric:tabular-nums;}
.detail-fakt-tr{color:var(--border);}
.detail-zeit-btn{background:none;border:none;padding:0;font-size:inherit;color:inherit;cursor:pointer;}
.detail-zeit-btn em{font-style:normal;color:var(--active-accent);font-size:0.74rem;transition:transform .15s;}
.detail-zeit-btn.offen em{transform:rotate(180deg);}
/* Eingerueckt und mit Kante: die Einzelzeiten gehoeren sichtbar zur
   Gesamtzeit darueber und stehen nicht gleichrangig daneben. */
.detail-zeit-auf{display:grid;grid-template-columns:auto 1fr;gap:0.3rem 0.9rem;width:max-content;max-width:100%;margin:0.5rem 0 0.2rem;padding-left:0.75rem;border-left:2px solid var(--border);}

/* ── Bearbeiten / Teilen / Drucken ───────────────────────────
   Als drei blasse Vollbreite-Knoepfe untereinander waren sie kaum als
   Knoepfe zu erkennen. Nebeneinander mit Flaeche, Rahmen und Symbol ueber
   der Beschriftung brauchen sie ausserdem nur ein Drittel der Hoehe. */
.detail-actions{display:grid;grid-template-columns:repeat(3,1fr);gap:0.5rem;margin-top:1.2rem;}
.detail-action{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:0.45rem;padding:0.8rem 0.35rem;border:1.5px solid var(--border);border-radius:var(--r-lg);background:var(--surface);color:var(--text);font-size:0.74rem;font-weight:600;line-height:1.2;text-align:center;cursor:pointer;box-shadow:var(--card-shadow,none);transition:border-color .15s;}
.detail-action svg{color:var(--primary);flex-shrink:0;}
@media(hover:hover){.detail-action:hover{border-color:var(--primary);}}

/* "Wer isst mit?" ging in Grau in Grau unter — es ist der Einstieg ins
   Haushalts-Feature und damit alles andere als nebensaechlich. */
.btn-sec-stark{background:color-mix(in srgb,var(--active-accent) 12%,transparent);border:1.5px solid var(--active-accent);color:var(--active-accent);font-weight:700;margin-top:1.5rem;}
@media(hover:hover){.btn-sec-stark:hover{border-color:var(--active-accent);color:var(--active-accent);}}

/* Eine display-Regel im Stylesheet schlaegt das hidden-Attribut. Einmal
   zentral abgesichert, damit ein aufklappbarer Block nicht offen startet. */
[hidden]{display:none!important;}

/* Avatarflaeche exakt so hoch wie das Namensfeld daneben — 2,6rem gegen die
   errechnete Feldhoehe war sichtbar zu gross, und ein Kreis nimmt jede
   Abweichung sofort mit. */
.pf-name-row input{height:2.55rem;}
.pf-avatar-btn{width:2.55rem;height:2.55rem;border-radius:50%;font-size:1.05rem;background:var(--field);}
/* Avatar im Kopfbereich steht frei, ohne Kreis darum. */
#hdr-avatar{background:none;border:none;padding:0;}

/* Optionale Angaben: ein ruhiger Aufklapper in der Akzentfarbe mit
   Plus-Kreis. Als graue Zeile mit Dreieck sah er aus wie ein Feld, das man
   noch ausfuellen muss — optional heisst aber: darf man ignorieren. */
.more-times>summary{position:relative;display:inline-flex;align-items:center;gap:0.45rem;color:var(--active-accent);font-weight:600;font-size:0.84rem;}
.more-times>summary::before{content:'';display:inline-flex;width:1.2rem;height:1.2rem;border:1.5px solid currentColor;border-radius:50%;background-image:none;-webkit-mask:none;mask:none;position:relative;}
.more-times>summary::after{content:'';position:absolute;left:0;top:50%;width:1.2rem;height:1.2rem;margin-top:-0.6rem;background-position:center;background-size:10px 10px;background:currentColor;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.24' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 5v14M5 12h14'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.24' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 5v14M5 12h14'/%3E%3C/svg%3E") center/10px no-repeat;}
.more-times[open]>summary::after{background-size:10px 10px;background:currentColor;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.24' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.24' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3C/svg%3E") center/10px no-repeat;}
/* Hinweise sind keine Warnungen — getoente Flaeche statt Signalkante. */
.more-times-hint{background:var(--surface2);border-radius:var(--r-md);padding:0.55rem 0.7rem;margin:0.5rem 0 0.2rem;line-height:1.45;}

/* ── Filter, Sortierpanel und Kacheln ────────────────────────
   Volle Pillenform war fuer die gefuellten Chips zu rund — sie schwammen
   neben den weich gerundeten Kacheln und Feldern. Ein sanftes Rechteck haelt
   dieselbe Formfamilie, ohne zu blubbern. */
.cat-chip,.cat-add-btn{border-radius:var(--r-sm);}
.cat-chip.active{border-color:transparent;}

/* Das ausgeklappte Sortierpanel trug noch die alte Optik: harter Rahmen,
   kleine Radien, Zeilen ohne Flaeche. Jetzt dieselbe Sprache wie Karten und
   Modals — weiche Ecken, Schatten statt Rahmen, aktive Zeile mit Flaeche. */
.sort-panel{border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--card-shadow,none);padding:0.45rem;}
.sort-row{border-radius:var(--r-sm);padding:0.5rem 0.6rem;}
@media(hover:hover){.sort-row:hover{background:var(--surface2);}}
.sort-row.active{background:color-mix(in srgb,var(--active-accent) 12%,transparent);}
.sort-panel-hint{padding:0.45rem 0.6rem 0.15rem;}

/* Die Dashboard-Kacheln bleiben bewusst auf dem Live-Stand: randlos, ohne
   abgerundete Ecken, ohne eigene Rahmenlinie, Raster eng. Schriften und
   Farben laufen ueber die globalen Tokens mit. */

/* Gewaehlte Kategorie: der Farbpunkt liegt auf gleichfarbiger Flaeche und ist
   dort ohnehin nicht zu sehen — uebrig blieb ein leeres Loch. Ganz weglassen
   geht nicht, dann schrumpft der Chip um 14 px und die Zeile springt (siehe
   Kommentar an renderFilter). Also steht im selben Kaestchen jetzt ein Haken.
   currentColor: die Schriftfarbe waehlt catTextColor() bereits kontrastreich
   zur Kategoriefarbe, der Haken erbt das mit. Ohne mask-Unterstuetzung bleibt
   es beim bisherigen leeren Platz — kein Bruch, nur kein Haken. */
.cat-dot-leer{visibility:visible;background:transparent!important;position:relative;}
.cat-dot-leer::after{content:"";position:absolute;inset:-2px;background:currentColor;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5l5.5 5.5L20 7'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5l5.5 5.5L20 7'/%3E%3C/svg%3E") center/contain no-repeat;}
@supports not ((mask:none) or (-webkit-mask:none)){
  .cat-dot-leer{visibility:hidden;}
}

/* Kategorie-Chips wieder als Pille. "Zu rund" bezog sich auf etwas anderes;
   als Rechteck standen sie zwischen den runden Feldern und Reitern fremd da. */
.cat-chip,.cat-add-btn{border-radius:99px;padding:0.32rem 0.75rem;}

/* Grundton-Umschalter im Theme-Bereich — dieselbe Pillenform wie die
   Herkunft-Reiter im Dashboard, damit "eins von zwei waehlen" ueberall
   gleich aussieht. */
.mode-seg{display:flex;gap:0.25rem;background:var(--surface2);border:1px solid var(--border);padding:0.2rem;border-radius:99px;margin:0 0 0.7rem;}
.mode-seg button{flex:1;border:none;background:transparent;border-radius:99px;padding:0.36rem;font-size:0.82rem;color:var(--text-sub);cursor:pointer;transition:background .15s,color .15s;}
.mode-seg button.on{background:var(--raise);color:var(--text);font-weight:600;box-shadow:var(--card-shadow,none);}
.theme-groups{gap:0.55rem;}

/* Portions- und Schriftgroessen-Regler stehen nebeneinander und sind
   Bedienelemente mit runden Knoepfen darin — als Pille lesen sie sich als
   ein Stueck, wie Suche und Sortieren darueber. */
.servings-stepper,.detail-zoom-row{border-radius:99px;}
.servings-stepper button,.detail-zoom-row button{border-radius:50%;}

/* Aufklapper: ein Zeichen fuer alle. */
.pref-group>summary::before,.pc-hh-group>summary::before,.mp-details>summary::before,.cl-chevron::before,
.pref-group[open]>summary::before,.pc-hh-group[open]>summary::before,.mp-details[open]>summary::before,.cl-day[open]>summary .cl-chevron::before{content:'';}
.pref-group>summary,.pc-hh-group>summary,.mp-details>summary,.hh-members>summary{display:flex;align-items:center;gap:0.5rem;list-style:none;}
.pref-group>summary::-webkit-details-marker,.pc-hh-group>summary::-webkit-details-marker,.mp-details>summary::-webkit-details-marker,.hh-members>summary::-webkit-details-marker{display:none;}
.pref-group>summary::after,.pc-hh-group>summary::after,.mp-details>summary::after,.hh-members>summary::after,.cl-chevron::after{
  content:'';margin-left:auto;color:var(--active-accent);transition:transform .15s;display:inline-block;width:13px;height:13px;flex-shrink:0;background:currentColor;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.49' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 6 6 6-6 6'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.49' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 6 6 6-6 6'/%3E%3C/svg%3E") center/contain no-repeat;}
.pref-group[open]>summary::after,.pc-hh-group[open]>summary::after,.mp-details[open]>summary::after,.hh-members[open]>summary::after,.cl-day[open]>summary .cl-chevron::after{transform:rotate(90deg);}

/* Changelog-Tage: Chevron rechts wie in allen anderen Aufklappern. Er sitzt
   im Markup vor dem Datum, deshalb per order ans Zeilenende geschoben statt
   das Markup zu aendern. */
.cl-chevron{order:9;margin-left:auto;color:var(--active-accent);font-weight:400;font-size:1.15rem;}

/* Sekundaerknopf braucht die Kante. Nur getoente Flaeche funktioniert auf
   dem Seitenhintergrund, im Modal liegt --surface2 aber dicht an der
   Modalflaeche — "Code erzeugen" sah dort aus wie ein Absatz, nicht wie ein
   Knopf. Flaeche UND Rahmen: dann traegt in jedem Umfeld mindestens eins. */
.btn-sec{background:var(--surface2);border:1.5px solid var(--border);}
@media(hover:hover){.btn-sec:hover{border-color:var(--rezept);color:var(--rezept);}}

/* Nachtrag: .btn-sec-stark muss nach .btn-sec stehen, sonst gewinnt der
   neutrale Rahmen von oben. */
.btn-sec.btn-sec-stark{background:color-mix(in srgb,var(--active-accent) 12%,transparent);border:1.5px solid var(--active-accent);color:var(--active-accent);font-weight:700;margin-top:1.5rem;}
@media(hover:hover){.btn-sec.btn-sec-stark:hover{border-color:var(--active-accent);color:var(--active-accent);}}

/* Abschnittstitel und Zwischenueberschriften auf dieselbe Groesse. Vorher
   war "Zutaten" (0,86rem) KLEINER als die Zwischenueberschrift "Feuchte
   Zutaten" (0,96rem) darunter — eine Unterordnung, die auf dem Kopf stand.
   Der Unterschied laeuft jetzt ueber die Farbe: Abschnitt in Textfarbe,
   Zwischenueberschrift in der Markenfarbe. */
#detail-ingredients-label,#detail-steps-label{font-size:calc(0.96rem * var(--detail-zoom, 1));}
/* Bei "Portionen" haengt kein gegliederter Inhalt darunter, sondern direkt
   der Regler — die Linie lief dort ins Leere. */
#detail-servings-label::after{display:none;}

/* Sortier-Knopf: echte Pille statt Klumpen. Feste Breite 3.4rem bei
   gestreckter Hoehe ergab 54x44 px — zu breit fuer einen Kreis, zu schmal
   fuer eine Pille. Jetzt richtet sich die Breite nach dem Inhalt (der
   wechselt ja: "ABC", Kalender, Stern) und die Polsterung macht sie
   eindeutig laenglich. */
.sort-btn{width:auto;min-width:0;padding:0 1.05rem;gap:0.35rem;}

/* Sortier-Richtung: dieselbe Zeichnung wie alle anderen Symbole, fuer
   "aufsteigend" einfach gedreht statt eines zweiten Schriftzeichens. */
.sort-btn .sort-dir{display:inline-flex;align-items:center;line-height:0;transition:transform .15s;}
.sort-btn .sort-dir-auf{transform:rotate(180deg);}

/* Lange Woerter im Kacheltitel trennen. "Zitronenpfefferpasta" ist EIN Wort
   und breiter als die Kachel — ohne Trennregel laeuft es aus dem Kasten und
   die Zeilenbegrenzung schneidet mitten im Wort ab, ohne Auslassungspunkte.
   hyphens:auto trennt nach deutschen Regeln (html lang="de" ist gesetzt),
   overflow-wrap faengt ab, was die Silbentrennung nicht kann (URLs, Ziffern-
   ketten). Beides zusammen, weil hyphens allein bei unbekannten Woertern
   nichts tut. */
.recipe-card-title{hyphens:auto;overflow-wrap:break-word;}
/* Dieselbe Behandlung fuer Rezepttitel und Zutatennamen im Rezept — dort
   stand bisher nur overflow-wrap, das trennt ohne Bindestrich. */
#detail-title,.d-title{hyphens:auto;}
#detail-ingredients li,.ing-name{overflow-wrap:break-word;hyphens:auto;}

/* Verlauf: Luft beim Aufklappen. Zwischen Ueberschrift und Knopf lagen
   5 px — der Knopf klebte an der Zeile darueber und an der Kastenkante.
   Der Knopf traegt hier ausserdem den betonten Sekundaerstil statt der
   gefuellten Primaerfarbe: einen Verlauf klappt man zum Nachlesen auf,
   das Anlegen ist die Nebenhandlung. */
#detail-verlauf-label{padding:0.85rem 1rem 1rem;}
#detail-verlauf-label[open] summary{padding-bottom:0.85rem;margin-bottom:0.85rem;border-bottom:1px solid var(--border);}
#detail-verlauf-label #detail-add-history{margin:0 0 0.9rem;}

/* Leerzustand "Mit mir geteilt": kurze Erklaerung plus Knopf statt eines
   wortlosen Leerraums — der Reiter ist jetzt immer sichtbar, auch fuer wer
   noch keinen Haushalt hat, deshalb muss der leere Zustand selbst erklaeren
   statt einfach zu verschwinden. */
#filter-empty-hint p{margin:0 0 0.3rem;}
#filter-empty-hint p:last-child{margin-bottom:0;}
.empty-hint-sub{font-size:0.78rem;opacity:0.85;}
.empty-hint-btn{max-width:280px;margin:0.9rem auto 0;}

/* ── Formsprache „Sockel" ──────────────────────────────────────
   Knoepfe sind Koerper mit einer Seitenwand: eine harte, unverwischte
   Flaeche unter dem Knopf. Kontur und Sockel tragen GENAU dieselbe Farbe —
   es ist ja auch dieselbe Sache, einmal ringsum und einmal darunter.
   Beim Druecken faehrt der Knopf um die Sockelhoehe nach unten und der
   Sockel verschwindet; die Aussenkante bleibt dabei stehen, es springt also
   nichts im Layout.

   Vier Tokens tragen das, je Theme ableitbar:
     --btn-face  / --btn-edge   fuer den rein grauen Knopf (Abbrechen)
     --btn-face2 / --btn-edge2  fuer die Gruppe mit farbigem Symbol
                                (Teilen-Code, Kacheln, Kopf-Symbolknoepfe)
   Im Hellen ist die Kante ein fester Anteil ihrer eigenen Flaeche (55 %);
   bei den blassen Flaechen wird der Farbton wieder eingemischt, sonst waere
   sie fast grau. Im Dunklen geht diese Rechnung nicht auf — man kann nicht
   gleichzeitig eine dunkle Flaeche, eine farbige Kante UND eine Kante
   dunkler als die Flaeche haben. Dort tragen die Knoepfe deshalb hellere,
   deckende Flaechen. */
[data-theme="light"],[data-theme="ocean"],[data-theme="peach"],
[data-theme="forest"],[data-theme="lavender"],[data-theme="berry"]{
  --btn-face:var(--surface2);
  --btn-edge:color-mix(in srgb,var(--surface2) 55%,#000);
  --btn-face2:var(--surface);
  --btn-edge2:color-mix(in srgb,var(--primary) 45%,color-mix(in srgb,var(--surface) 55%,#000));
}
[data-theme="dark"],[data-theme="dark-neutral"],[data-theme="dark-peach"],
[data-theme="dark-forest"],[data-theme="dark-lavender"],[data-theme="dark-berry"]{
  /* Im Dunklen dieselbe Flaeche wie die Gruppe darunter: eine eigene,
     noch dunklere Stufe liess "Abbrechen" neben "Zurueck" oder einem
     Symbolknopf wie ein ausgegrauter Knopf aussehen statt wie eine
     gleichwertige Nebenaktion. Im Hellen bleibt die Staffelung, dort
     traegt --btn-edge2 bewusst einen Farbstich, der einem Abbrechen
     nicht zusteht. */
  --btn-face:var(--btn-face2);
  --btn-edge:var(--btn-edge2);
  --btn-face2:var(--raise);
  --btn-edge2:color-mix(in srgb,var(--raise) 72%,#000);
}
/* Basic dunkel: hier stehen die von Hand eingestellten Werte. Sie sind
   bewusst neutralgrau statt warm — abweichend von --raise dieses Themes. */
[data-theme="dark"],[data-theme="dark-neutral"]{
  --btn-face2:#3a3a3a; --btn-edge2:#2c2c2c;
  --btn-face:var(--btn-face2); --btn-edge:var(--btn-edge2);
}

/* Kontur und Sockel aus einer Farbe, Platz fuer den Sockel im Fluss
   reserviert (sonst waere der Knopf hoeher als sein Kasten). */
.btn-primary,.btn-sec,.btn-sec-stark,.btn-accent,.btn-del,
.detail-action,.hh-choice-btn,.hdr-icon-btn{
  border:1.5px solid var(--kante);
  box-shadow:0 var(--sockel-h,3px) 0 var(--kante);
  margin-bottom:var(--sockel-h,3px);
  transition:transform .07s ease-out,box-shadow .07s ease-out;
}
/* (Die Druck-Regel steht bewusst ganz am Ende des Blattes, nach dem
   Hover-Block — sonst gewinnt Hover bei gleicher Spezifitaet.) */
/* Nicht bedienbar heisst: kein Sockel. Was nicht einsinken kann, darf auch
   nicht so aussehen, als koennte es. */
.btn-primary:disabled,.btn-sec:disabled,.btn-accent:disabled,.btn-del:disabled,
.detail-action:disabled,.hdr-icon-btn:disabled{box-shadow:none;transform:none;}

/* Voll gefaerbte Rollen: die Flaeche IST die Identitaetsfarbe, die Kante
   ihre dunkle Fassung. */
.btn-primary{--kante:color-mix(in srgb,var(--primary) 55%,#000);}
.btn-sec-stark{--kante:color-mix(in srgb,var(--active-accent) 55%,#000);}
.btn-del{--kante:color-mix(in srgb,var(--err-border) 55%,#000);}

/* Rein grau. */
.btn-sec{--kante:var(--btn-edge);background:var(--btn-face);--sockel-h:4px;}

/* Gruppe mit farbigem Symbol: graue Flaeche, eigene Kante. Ein Sockel unter
   einer durchsichtigen Flaeche waere ein Widerspruch — deshalb bekommt der
   frueher randlose .btn-accent hier eine deckende Flaeche. */
.btn-accent,.detail-action,.hh-choice-btn,.hdr-icon-btn{
  --kante:var(--btn-edge2);background:var(--btn-face2);--sockel-h:4px;
}

/* Eingelassenes bleibt flach: Felder und Zeilen sitzen auf --field, und
   --field ist im Dunklen die Mulde. Ein Sockel darunter waere ein
   Widerspruch in sich. Genauso Chips, Reiter und Textknoepfe — nur was man
   druecken kann, sinkt ein. */
.pf-prefs-btn,.cat-chip,.cat-add-btn,.lib-tab,.mode-seg button,
.btn-link-sec,.detail-del-btn,.star-btn,.pc-back-btn,.sort-btn{
  box-shadow:none;margin-bottom:0;
}

/* Der Tastatur-Fokusring laege sonst genau auf dem Sockel. */
/* (Der Fokus laeuft jetzt ueber die Tiefe statt ueber eine Umrandung —
   die Regel dazu steht am Ende des Blattes.) */

/* Die klebende Wizard-Fusszeile rechnet unten mit Safe-Area plus Polsterung;
   die Sockelhoehe kommt dazu, sonst klebt der Sockel auf der Kante. */
.wizard-footer{padding-bottom:calc(1.5rem + 4px + env(safe-area-inset-bottom,0px));}

/* Nachtrag: zwei Rollen brauchen mehr Spezifitaet bzw. eine deckende Flaeche.
   .btn-sec.btn-sec-stark (0,2,0) steht weiter oben und schlug die Kante aus
   dem Sockel-Block (0,1,0) — dadurch trugen Kontur und Sockel dort
   verschiedene Farben. Ausserdem sind beide Flaechen durchsichtig gewesen;
   ein Sockel unter etwas Durchsichtigem ist ein Widerspruch, deshalb werden
   die Toenungen hier mit dem Grundton gemischt statt mit transparent. */
.btn-sec.btn-sec-stark,.btn-sec-stark{
  background:color-mix(in srgb,var(--active-accent) 14%,var(--bg));
  border:1.5px solid var(--kante);
}
.btn-del{
  background:color-mix(in srgb,var(--err-border) 12%,var(--bg));
  border:1.5px solid var(--kante);
}
.btn-accent{
  background:var(--btn-face2);
  border:1.5px solid var(--kante);
}

/* Betonte Nebenaktion und Loeschen: hell getoent, dunkel gefuellt.
   Im Hellen funktioniert die Toenung, weil jede daraus gerechnete Kante
   dunkler ist. Im Dunklen bricht das: die Warnfarbe ist dort ein helles
   Lachs, und 55 % davon liegen immer noch UEBER einer dunklen Toenung — der
   Sockel wurde heller als sein Knopf. Deshalb tragen beide Rollen im
   Dunkelmodus die volle Identitaetsfarbe mit dunkler Schrift; dann stimmt
   die Richtung wieder. Das ist derselbe Weg wie bei .btn-primary. */
[data-theme="light"],[data-theme="ocean"],[data-theme="peach"],
[data-theme="forest"],[data-theme="lavender"],[data-theme="berry"]{
  /* "Wer isst mit?" ist auch im Hellen voll gefuellt (Style 1), damit die
     Rolle in beiden Grundtoenen gleich aussieht. Vorher war sie hier nur
     getoent — derselbe Knopf wirkte hell wie eine Nebenaktion und dunkel wie
     eine Hauptaktion. */
  --btn-stark-face:var(--active-accent);
  --btn-stark-edge:color-mix(in srgb,var(--active-accent) 55%,#000);
  --btn-stark-text:var(--active-accent-text);
  --btn-del-face:color-mix(in srgb,var(--err-text) 20%,var(--bg));
  --btn-del-edge:color-mix(in srgb,var(--err-text) 45%,color-mix(in srgb,var(--err-text) 14%,#000));
  --btn-del-text:var(--err-text);
}
[data-theme="dark"],[data-theme="dark-neutral"],[data-theme="dark-peach"],
[data-theme="dark-forest"],[data-theme="dark-lavender"],[data-theme="dark-berry"]{
  --btn-stark-face:var(--active-accent);
  --btn-stark-edge:color-mix(in srgb,var(--active-accent) 55%,#000);
  --btn-stark-text:var(--active-accent-text);
  --btn-del-face:var(--err-text);
  --btn-del-edge:color-mix(in srgb,var(--err-text) 55%,#000);
  --btn-del-text:var(--bg);
}
.btn-sec.btn-sec-stark,.btn-sec-stark{
  background:var(--btn-stark-face);border:1.5px solid var(--btn-stark-edge);
  color:var(--btn-stark-text);--kante:var(--btn-stark-edge);
}
.btn-del{
  background:var(--btn-del-face);border:1.5px solid var(--btn-del-edge);
  color:var(--btn-del-text);--kante:var(--btn-del-edge);
}

/* Hover: der Knopf sinkt auf die HALBE Sockelhoehe ein — eine Vorstufe des
   Drucks, kein eigener Effekt. Die bisherigen Hover wechselten Rahmen- und
   Schriftfarbe; das las sich als Zustandswechsel ("ausgewaehlt") statt als
   "hier ist der Finger", und bei den Kacheln sprang dadurch die Farbe.
   Jetzt bleibt die Farbe unangetastet, nur die Tiefe aendert sich.
   Nur unter (hover:hover): auf dem Handy gibt es keinen echten Hover, dort
   bliebe der Zustand sonst nach dem Tippen kleben. */
@media(hover:hover){
  .btn-primary:hover,.btn-sec:hover,.btn-sec-stark:hover,.btn-accent:hover,
  .btn-del:hover,.detail-action:hover,.hh-choice-btn:hover,.hdr-icon-btn:hover{
    transform:translateY(1px);
    box-shadow:0 calc(var(--sockel-h,3px) - 1px) 0 var(--kante);
  }
  /* Die Farbwechsel der alten Hover zuruecknehmen — die Tiefe traegt jetzt
     die Rueckmeldung. Farbe bleibt der Zustandsanzeige vorbehalten. */
  .btn-sec:hover,.btn-sec.btn-sec-stark:hover,.btn-sec-stark:hover{
    border-color:var(--kante);color:inherit;
  }
  .btn-sec:hover{color:var(--text-sub);}
  .btn-sec.btn-sec-stark:hover,.btn-sec-stark:hover{color:var(--btn-stark-text);}
  .btn-accent:hover{background:var(--btn-face2);color:var(--rezept);border-color:var(--kante);}
  .btn-del:hover{background:var(--btn-del-face);color:var(--btn-del-text);border-color:var(--kante);}
  .detail-action:hover,.hh-choice-btn:hover{border-color:var(--kante);}
  .btn-primary:hover{opacity:1;}
  /* Nicht bedienbare Knoepfe heben sich beim Ueberfahren nicht. */
  .btn-primary:disabled:hover,.btn-sec:disabled:hover,.btn-accent:disabled:hover,
  .btn-del:disabled:hover,.detail-action:disabled:hover,.hdr-icon-btn:disabled:hover{
    transform:none;box-shadow:none;
  }
}

/* Gedrueckt MUSS nach dem Hover stehen: beide haben dieselbe Spezifitaet
   (z.B. .btn-primary:hover und .btn-primary:active sind je 0,2,0), also
   gewinnt die spaetere Regel. Solange der Hover-Block hinter :active stand,
   zeigte ein Klick weiter den Hover-Zustand — Drücken und Überfahren sahen
   deshalb identisch aus.
   Die Stufen bei 4 px Sockel: ruhend 4, Hover 2, gedrueckt 1. Der Sockel
   verschwindet also NICHT ganz — ein Rest bleibt stehen, damit der Knopf
   gedrueckt aussieht und nicht abgesetzt. */
.btn-primary:active,.btn-sec:active,.btn-sec-stark:active,.btn-sec.btn-sec-stark:active,
.btn-accent:active,.btn-del:active,.detail-action:active,.hh-choice-btn:active,
.hdr-icon-btn:active{
  transform:translateY(2px);
  box-shadow:0 calc(var(--sockel-h,3px) - 2px) 0 var(--kante);
}
@media(hover:hover){
  .btn-primary:active,.btn-sec:active,.btn-sec-stark:active,.btn-sec.btn-sec-stark:active,
  .btn-accent:active,.btn-del:active,.detail-action:active,.hh-choice-btn:active,
  .hdr-icon-btn:active{
    transform:translateY(2px);
    box-shadow:0 calc(var(--sockel-h,3px) - 2px) 0 var(--kante);
  }
}

/* Einheitlich 4 px Sockel fuer alle Rollen. Mit 3 px ergaben die Stufen
   4/2/1 bei den grauen, aber 3/1,5/1 bei den farbigen — das halbe Pixel
   beim Hover verwischt je nach Bildschirm und die beiden Gruppen sanken
   verschieden tief. Jetzt ueberall dieselbe Leiter. */
.btn-primary,.btn-sec-stark,.btn-sec.btn-sec-stark,.btn-del{--sockel-h:4px;}

/* ── Portionen und Schriftgroesse: Knoepfe statt Wanne ─────────
   Bisher lagen − und + IN einer gemeinsamen Flaeche mit Rahmen; die Wanne
   war das auffaelligste Element, die eigentlichen Bedienelemente darin
   flach und randlos. Jetzt umgekehrt: keine Traegerflaeche mehr, sondern
   zwei eigenstaendige Knoepfe in der Sockel-Form links und rechts vom Wert.
   Farben wie beim Sortier-Knopf neben der Suche (Akzentflaeche, Schrift in
   --active-accent-text, also dem Grundton — hell auf Dunkel, dunkel auf
   Hell). Dadurch sehen die drei runden Bedienelemente der Seite gleich aus. */
.servings-stepper,.detail-zoom-row{
  background:none;border:none;padding:0;gap:0.5rem;border-radius:0;
}
.servings-stepper button,.detail-zoom-row button{
  --kante:color-mix(in srgb,var(--active-accent) 55%,#000);
  --sockel-h:4px;
  width:2.1rem;height:2.1rem;flex-shrink:0;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--active-accent);color:var(--active-accent-text);
  border:1.5px solid var(--kante);
  box-shadow:0 var(--sockel-h) 0 var(--kante);
  margin-bottom:var(--sockel-h);
  transition:transform .07s ease-out,box-shadow .07s ease-out;
}
/* Der Wert dazwischen traegt die Markenfarbe — er ist die Aussage, die
   Knoepfe sind nur das Werkzeug. */
.servings-stepper input{color:var(--rezept);font-weight:700;}
.detail-zoom-icon{color:var(--rezept);display:flex;align-items:center;}
/* Nicht bedienbar: kein Sockel, damit nichts nach Druecken aussieht, was
   nicht gedrueckt werden kann. */
.servings-stepper button:disabled,.detail-zoom-row button:disabled{
  box-shadow:none;transform:none;margin-bottom:var(--sockel-h);opacity:0.35;
}
@media(hover:hover){
  .servings-stepper button:hover,.detail-zoom-row button:hover{
    background:var(--active-accent);color:var(--active-accent-text);
    transform:translateY(1px);box-shadow:0 calc(var(--sockel-h) - 1px) 0 var(--kante);
  }
  .servings-stepper button:disabled:hover,.detail-zoom-row button:disabled:hover{
    transform:none;box-shadow:none;
  }
}
.servings-stepper button:active,.detail-zoom-row button:active{
  transform:translateY(2px);box-shadow:0 calc(var(--sockel-h) - 2px) 0 var(--kante);
}

/* Der Zutaten-je-Schritt-Umschalter gehoert zur selben Familie: ein rundes
   Bedienelement in der Akzentfarbe. Er hat aber ZWEI Zustaende, und die
   Unterscheidung darf nicht ueber die Tiefe laufen (die traegt bereits
   Hover und Druck). Deshalb: aus = getoente Flaeche mit Akzentkante,
   an = voll gefuellt. Der Sockel bleibt in beiden Zustaenden gleich. */
.detail-section-toggle{
  --kante:color-mix(in srgb,var(--active-accent) 55%,#000);
  --sockel-h:4px;
  width:2.1rem;height:2.1rem;border-radius:50%;
  background:color-mix(in srgb,var(--active-accent) 16%,var(--bg));
  color:var(--active-accent);
  border:1.5px solid var(--kante);
  box-shadow:0 var(--sockel-h) 0 var(--kante);
  margin-bottom:var(--sockel-h);
  transition:transform .07s ease-out,box-shadow .07s ease-out,background .15s;
}
.detail-section-toggle.active{
  background:var(--active-accent);color:var(--active-accent-text);border-color:var(--kante);
}
@media(hover:hover){
  .detail-section-toggle:hover{
    border-color:var(--kante);color:var(--active-accent);
    transform:translateY(1px);box-shadow:0 calc(var(--sockel-h) - 1px) 0 var(--kante);
  }
  .detail-section-toggle.active:hover{color:var(--active-accent-text);}
}
.detail-section-toggle:active{
  transform:translateY(2px);box-shadow:0 calc(var(--sockel-h) - 2px) 0 var(--kante);
}
/* Die Zeile traegt den Knopf jetzt mittig zur Ueberschrift, trotz des
   reservierten Sockelplatzes darunter. */
.detail-section-label-row{align-items:center;}

/* Korrektur: nicht die gefuellte Akzentflaeche des Sortier-Knopfes, sondern
   die Optik des SUCHFELDS daneben — dunkle Feldflaeche mit Rahmen, Farbe
   nur im Symbol. Das haelt die Zeile ruhig: Portionen und Schriftgroesse
   sind Einstellungen, keine Hauptaktionen, und drei gefuellte Akzentkreise
   haben mit dem Sortier-Knopf um dieselbe Aufmerksamkeit konkurriert.
   Der Sockel bleibt, damit sie als Knoepfe lesbar sind. */
.servings-stepper button,.detail-zoom-row button,.detail-section-toggle{
  --kante:var(--btn-edge2);
  background:var(--btn-face2);
  color:var(--rezept);
  border:1.5px solid var(--kante);
}
/* Angeschaltet bleibt der Umschalter gefuellt — sonst waere der Zustand
   nicht mehr ablesbar. */
.detail-section-toggle.active{
  background:var(--active-accent);color:var(--active-accent-text);
  --kante:color-mix(in srgb,var(--active-accent) 55%,#000);
}
@media(hover:hover){
  .servings-stepper button:hover,.detail-zoom-row button:hover{
    background:var(--btn-face2);color:var(--rezept);
  }
  .detail-section-toggle:hover{color:var(--rezept);}
  .detail-section-toggle.active:hover{color:var(--active-accent-text);}
}

/* Nachtrag zu den runden Bedienelementen.

   1) Ausgegraut behaelt den Sockel. Ein Knopf ohne Sockel liest sich als
      andere Sorte Element, nicht als "gerade nicht verfuegbar" — die
      Deckkraft sagt das schon. Er sinkt nur nicht mehr ein.

   2) Die alte Hover-Regel .detail-zoom-row button:hover:not(:disabled)
      (0,3,1) schlug meine (0,2,1) und faerbte die Flaeche auf --surface um.
      Weil die Maus nach einem Klick auf dem Knopf stehen bleibt, sah das
      aus wie "Farbe aendert sich nach dem Druecken". Farbe bleibt jetzt
      unangetastet — die Tiefe traegt die Rueckmeldung. */
.servings-stepper button:disabled,.detail-zoom-row button:disabled,
.btn-primary:disabled,.btn-sec:disabled,.btn-accent:disabled,.btn-del:disabled,
.detail-action:disabled,.hdr-icon-btn:disabled{
  box-shadow:0 var(--sockel-h,4px) 0 var(--kante);
  transform:none;
}
.servings-stepper button:disabled,.detail-zoom-row button:disabled{opacity:0.35;}
.detail-zoom-row button:hover:not(:disabled),
.servings-stepper button:hover:not(:disabled){
  background:var(--btn-face2);color:var(--rezept);
}
@media(hover:hover){
  .detail-zoom-row button:hover:not(:disabled),
  .servings-stepper button:hover:not(:disabled){
    transform:translateY(1px);box-shadow:0 calc(var(--sockel-h) - 1px) 0 var(--kante);
  }
  .detail-zoom-row button:disabled:hover,.servings-stepper button:disabled:hover{
    transform:none;box-shadow:0 var(--sockel-h) 0 var(--kante);
  }
}
.detail-zoom-row button:active:not(:disabled),
.servings-stepper button:active:not(:disabled){
  transform:translateY(2px);box-shadow:0 calc(var(--sockel-h) - 2px) 0 var(--kante);
}

/* Knoepfe naeher an den Wert. Die 0,5 rem Luecke stammte aus der Zeit, als
   die Knoepfe in einer gemeinsamen Wanne sassen und Abstand zu deren Rand
   brauchten — ohne Wanne trieb sie das Trio unnoetig auseinander.
   Die Portionszahl bekommt ausserdem eine schmalere feste Breite: 3,2 rem
   waren fuer ein- bis zweistellige Werte zu viel Leerraum. */
.servings-stepper,.detail-zoom-row{gap:0.25rem;}
.servings-stepper input{width:2.4rem;}
.detail-zoom-icon{padding:0 0.1rem;}

/* Der reservierte Sockelplatz ERSETZT vorhandene Abstaende, statt sie zu
   ergaenzen — dadurch schrumpfte die Luft unter Knoepfen, die schon einen
   eigenen Abstand hatten. Gemessen: unter "Eintrag & Bewertung" blieben von
   0,6 rem nur 5,6 px uebrig, weil der Sockel 4 px davon fuellt.
   Diese drei bekommen die Sockelhoehe deshalb obendrauf. Knoepfe ohne
   eigenen Abstand unten sind nicht betroffen: dort traegt der naechste
   Block seinen margin-top. */
#detail-add-history{margin-bottom:calc(0.6rem + var(--sockel-h,4px))!important;}
#catm-sort-btn,#unitm-sort-btn{margin-bottom:calc(0.6rem + var(--sockel-h,4px))!important;}
#detail-verlauf-label #detail-add-history{margin:0 0 calc(0.9rem + var(--sockel-h,4px));}

/* Der Zutaten-je-Schritt-Umschalter ans Zeilenende. Die Ueberschriftszeile
   ist ein Flexkasten aus <span>, <button> und der Linie (::after mit
   flex:1). Im Markup steht der Knopf VOR der Linie und klebte dadurch an
   "Zubereitung". Per order hinter die Linie geschoben statt das Markup zu
   aendern — dasselbe Vorgehen wie beim Changelog-Chevron. */
.detail-section-label-row>button{order:9;}

/* Bewertungssterne sind die AUSNAHME von "nur Linie": gefuellt = bewertet.
   Ein Rating-Stern ohne Fuellung kann keinen Wert zeigen — beim Umstellen
   auf Icons hatte ich sie auf fill:none gesetzt, dadurch sahen bewertete
   und unbewertete Sterne gleich aus. Ungesetzt bleibt der Umriss, gesetzt
   wird gefuellt.
   Die Teilfuellung fuer 0,5-Schritte laeuft unveraendert ueber .star-wrap:
   ein gefuellter Stern liegt absolut ueber dem leeren und wird per width in
   Prozent beschnitten (overflow:hidden), nicht gestaucht — deshalb traegt
   das SVG dort seine feste Pixelbreite. */
.star-btn{color:var(--star-empty,var(--border));font-size:0;line-height:0;}
.star-btn svg{display:block;fill:none;}
.star-btn.filled{color:var(--star);}
.star-btn.filled svg{fill:currentColor;}
/* In der Verlaufsliste dasselbe: voll = gefuellt, leer = Umriss. */
.hist-ratings svg{display:inline-block;vertical-align:-1px;}

/* Avatare im Verlauf — vor dem Datum (wer den Eintrag angelegt hat) und
   vor den Sternen (wer bewertet hat). Er steht nur bei geteilten
   Rezepten da — bei einem privaten sind alle Eintraege vom selben Menschen,
   dann waere er nur Rauschen. Der Abstand lag vorher als Textleerzeichen im
   Template; zwischen einem Emoji und einem Inline-SVG traegt das kaum, weil
   das SVG seine eigene Zeilenbox mitbringt. Jetzt ein echter Abstand. */
.hist-avatar{margin-right:0.3rem;}

/* Teilfuellung der Sterne, korrigiert.
   Der Fehler: .star-wrap ist in der Rezept-Ansicht 17 px breit, das SVG
   darin trug aber seine feste Attributbreite von 15 px. .star-fg schneidet
   bei 50 % der HUELLE ab, also bei 8,5 px — die Mitte des 15-px-Sterns
   liegt aber bei 7,5 px. Ein halber Stern war dadurch 1 px zu voll, und der
   leere Stern dahinter sass ausserdem nicht buendig in seiner Huelle.

   Loesung ueber eine Groessen-Variable: beide SVGs sind immer exakt so breit
   wie die Huelle, dann liegt die Sternmitte garantiert bei 50 %.
   WICHTIG: hier steht bewusst var(--sw) und nicht width:100% — 100 % waere
   bei .star-fg die BESCHNITTENE Breite, das SVG wuerde gestaucht statt
   abgeschnitten und aus einem halben Stern ein schmaler ganzer. */
.star-wrap{--sw:15px;width:var(--sw);height:var(--sw);}
.star-wrap svg{width:var(--sw);height:var(--sw);display:block;}
.detail-rating-row .detail-star-row .star-wrap{--sw:17px;}
.recipe-card-sub .star-compact{--sw:13px;}
.recipe-card-sub .star-compact svg{width:var(--sw);height:var(--sw);}

/* Der Sortier-Knopf war als einziger flach — ich hatte ihn ausgenommen, weil
   align-self:stretch ihn auf Suchfeld-Hoehe zieht und ein Sockel ihn 4 px
   ueberstehen liesse. Loest sich von selbst: mit margin-bottom schrumpft der
   gestreckte Knopf um genau diese 4 px, der Sockel fuellt sie, und die
   Aussenkante liegt wieder buendig mit dem Suchfeld. */
.sort-btn{
  --sockel-h:4px;
  --kante:color-mix(in srgb,var(--active-accent) 55%,#000);
  border:1.5px solid var(--kante);
  box-shadow:0 var(--sockel-h) 0 var(--kante);
  margin-bottom:var(--sockel-h);
  transition:transform .07s ease-out,box-shadow .07s ease-out;
}
@media(hover:hover){
  .sort-btn:hover{transform:translateY(1px);box-shadow:0 calc(var(--sockel-h) - 1px) 0 var(--kante);}
}
.sort-btn:active{transform:translateY(2px);box-shadow:0 calc(var(--sockel-h) - 2px) 0 var(--kante);}

/* Speichern und Abbrechen beim Anlegen von Kategorien/Mengen: runde Knoepfe
   in derselben Optik wie die Kopf-Symbolknoepfe. Sie standen als 2,4-rem-
   Rechtecke da und waren die letzten Bedienelemente in der alten Form. */
#catm-submit-btn,#unitm-submit-btn,#catm-cancel-btn,#unitm-cancel-btn{
  --sockel-h:4px;
  --kante:var(--btn-edge2);
  width:2.3rem;height:2.3rem;flex:0 0 auto;border-radius:50%;padding:0;
  display:flex;align-items:center;justify-content:center;
  background:var(--btn-face2);color:var(--rezept);
  border:1.5px solid var(--kante);
  box-shadow:0 var(--sockel-h) 0 var(--kante);
  margin-bottom:var(--sockel-h);
  transition:transform .07s ease-out,box-shadow .07s ease-out;
}
@media(hover:hover){
  #catm-submit-btn:hover,#unitm-submit-btn:hover,
  #catm-cancel-btn:hover,#unitm-cancel-btn:hover{
    background:var(--btn-face2);color:var(--rezept);
    transform:translateY(1px);box-shadow:0 calc(var(--sockel-h) - 1px) 0 var(--kante);
  }
}
#catm-submit-btn:active,#unitm-submit-btn:active,
#catm-cancel-btn:active,#unitm-cancel-btn:active{
  transform:translateY(2px);box-shadow:0 calc(var(--sockel-h) - 2px) 0 var(--kante);
}

/* Ausnahme: die beiden Speichern-Haken tragen die Primaerfarbe. Sie sind die
   Hauptaktion ihres Dialogs — mit der neutralen Kopf-Optik standen sie
   gleichwertig neben Abbrechen. Icon in --primary-text, also dem Grundton:
   schwarz auf Hell, weiss auf Dunkel. Die Kante wird wie bei allen
   gefuellten Rollen aus der eigenen Flaeche gerechnet. */
#catm-submit-btn,#unitm-submit-btn{
  --kante:color-mix(in srgb,var(--primary) 55%,#000);
  background:var(--primary);color:var(--primary-text);
  border:1.5px solid var(--kante);
}
@media(hover:hover){
  #catm-submit-btn:hover,#unitm-submit-btn:hover{
    background:var(--primary);color:var(--primary-text);
  }
}

/* Der Farbwaehler steht in derselben Zeile wie die beiden runden Knoepfe —
   als Rechteck war er dort der einzige Ausreisser. Rund, gleiche Groesse,
   gleicher Sockel; die Farbprobe darin wird zum vollen Kreis, damit die
   Farbe selbst die Flaeche traegt. */
.catm-new .rt-color-trigger,.unitm-new .rt-color-trigger{
  --sockel-h:4px;
  --kante:var(--btn-edge2);
  width:2.3rem;height:2.3rem;flex:0 0 auto;border-radius:50%;padding:0;
  background:var(--btn-face2);
  border:1.5px solid var(--kante);
  box-shadow:0 var(--sockel-h) 0 var(--kante);
  margin-bottom:var(--sockel-h);
  transition:transform .07s ease-out,box-shadow .07s ease-out;
}
.catm-new .rt-color-trigger .swatch,.unitm-new .rt-color-trigger .swatch{
  width:1.25rem;height:1.25rem;border-radius:50%;
}
@media(hover:hover){
  .catm-new .rt-color-trigger:hover,.unitm-new .rt-color-trigger:hover{
    transform:translateY(1px);box-shadow:0 calc(var(--sockel-h) - 1px) 0 var(--kante);
  }
}
.catm-new .rt-color-trigger:active,.unitm-new .rt-color-trigger:active{
  transform:translateY(2px);box-shadow:0 calc(var(--sockel-h) - 2px) 0 var(--kante);
}

/* Haken in Weiss statt im Grundton. Im Hellen ist das ohnehin dasselbe
   Bild (dunkle Primaerflaeche, helles Zeichen), im Dunklen dreht es den
   Haken von dunkel auf hell. */
#catm-submit-btn,#unitm-submit-btn{color:#fff;}
@media(hover:hover){
  #catm-submit-btn:hover,#unitm-submit-btn:hover{color:#fff;}
}

/* Der Farbwaehler ohne Sockel: er ist kein Knopf, der etwas ausloest,
   sondern eine Anzeige des aktuellen Werts, die ein Menue aufklappt.
   Rund und gleich gross wie die Knoepfe daneben bleibt er, damit die Zeile
   ruhig ist — nur die Tiefe entfaellt. Der reservierte Platz bleibt stehen,
   sonst saesse er hoeher als Speichern und Abbrechen. */
.catm-new .rt-color-trigger,.unitm-new .rt-color-trigger{
  box-shadow:none;
}
@media(hover:hover){
  .catm-new .rt-color-trigger:hover,.unitm-new .rt-color-trigger:hover{
    transform:none;box-shadow:none;
  }
}
.catm-new .rt-color-trigger:active,.unitm-new .rt-color-trigger:active{
  transform:none;box-shadow:none;
}

/* Style 3 (.btn-accent) traegt im Dunklen weisse Schrift, im Hellen die
   Markenfarbe — so steht es auch in der Studie, ich hatte es beim
   Uebertragen in die App nur nicht mitgenommen.
   Der Grund ist nicht Geschmack, sondern messbar: Terrakotta auf der grauen
   Knopfflaeche kommt im Dunkeln nur auf 3,79:1 und liegt damit unter der
   4,5:1-Grenze fuer Text. Die Farbidentitaet dieser Rolle steckt ohnehin in
   der Kante, die Schrift muss sie nicht auch noch tragen. */
/* (Die Schriftfarbe von Style 3 steht jetzt einheitlich am Ende des
   Blattes — sie ist in beiden Grundtoenen dieselbe wie bei Style 4.) */
@media(hover:hover){

}

/* Kein anderer Effekt als der Sockel — auch nicht beim Fokus.
   Bisher zog ein fokussierter Knopf eine Umrandung; beim Zutaten-Umschalter
   blieb sie nach dem Klick stehen, weil er den Fokus behaelt. Statt die
   Umrandung ersatzlos zu streichen (dann haetten Tastaturnutzer gar keinen
   Anhaltspunkt mehr) uebernimmt der Fokus dieselbe Sprache wie der Hover:
   der Knopf sinkt einen Schritt ein. Damit gibt es genau eine Rueckmeldung
   in diesem Design, und die ist die Tiefe.
   Ehrlich dazugesagt: Tiefe allein ist ein schwaecheres Signal als ein Ring.
   Wenn das fuer die Tastatur nicht reicht, waere der naechste Schritt eine
   Umrandung NUR bei :focus-visible und nur ausserhalb des Sockels. */
.btn-primary:focus,.btn-sec:focus,.btn-sec-stark:focus,.btn-accent:focus,
.btn-del:focus,.detail-action:focus,.hh-choice-btn:focus,.hdr-icon-btn:focus,
.sort-btn:focus,.detail-section-toggle:focus,
.servings-stepper button:focus,.detail-zoom-row button:focus,
#catm-submit-btn:focus,#unitm-submit-btn:focus,
#catm-cancel-btn:focus,#unitm-cancel-btn:focus{outline:none;}

.btn-primary:focus-visible,.btn-sec:focus-visible,.btn-sec-stark:focus-visible,
.btn-accent:focus-visible,.btn-del:focus-visible,.detail-action:focus-visible,
.hh-choice-btn:focus-visible,.hdr-icon-btn:focus-visible,.sort-btn:focus-visible,
.detail-section-toggle:focus-visible,
.servings-stepper button:focus-visible,.detail-zoom-row button:focus-visible,
#catm-submit-btn:focus-visible,#unitm-submit-btn:focus-visible,
#catm-cancel-btn:focus-visible,#unitm-cancel-btn:focus-visible{
  outline:none;
  transform:translateY(1px);
  box-shadow:0 calc(var(--sockel-h,4px) - 1px) 0 var(--kante);
}
/* Gedrueckt gewinnt weiterhin gegen Fokus und Hover — deshalb hier nochmal
   ans Ende, gleiche Spezifitaet, spaetere Regel. */
.btn-primary:active,.btn-sec:active,.btn-sec-stark:active,.btn-accent:active,
.btn-del:active,.detail-action:active,.hh-choice-btn:active,.hdr-icon-btn:active,
.sort-btn:active,.detail-section-toggle:active,
.servings-stepper button:active:not(:disabled),.detail-zoom-row button:active:not(:disabled),
#catm-submit-btn:active,#unitm-submit-btn:active,
#catm-cancel-btn:active,#unitm-cancel-btn:active{
  transform:translateY(2px);
  box-shadow:0 calc(var(--sockel-h,4px) - 2px) 0 var(--kante);
}

/* Gleitender Hintergrund der aktiven Herkunft-Reiter.
   Vorher trug der aktive Knopf seine Flaeche selbst — beim Wechsel sprang
   sie schlagartig um. Jetzt liegt die Flaeche als eigenes Stueck darunter
   und faehrt an die neue Stelle, passend zum Wischen der Kachelliste
   daneben. Die Knoepfe selbst sind transparent und liegen darueber.
   .sofort schaltet die Bewegung fuer den ersten Aufbau ab, sonst kaeme die
   Pille beim Oeffnen der App von links hereingefahren. */
.lib-tabs{position:relative;}
.lib-tab-pille{position:absolute;top:0;bottom:0;left:0;border-radius:99px;
  background:var(--raise);box-shadow:var(--card-shadow,none);pointer-events:none;
  transition:transform .28s cubic-bezier(.4,0,.2,1),width .28s cubic-bezier(.4,0,.2,1);}
.lib-tab-pille.sofort{transition:none;}
.lib-tab{position:relative;z-index:1;}
.lib-tab.active{background:none;box-shadow:none;}
@media(prefers-reduced-motion:reduce){
  .lib-tab-pille{transition:none;}
}

/* Seitliche Polsterung der Reiterleiste raus: sie liess links und rechts
   einen schmalen Streifen Wannenfarbe stehen, sobald der erste oder letzte
   Reiter aktiv war. Oben und unten bleibt sie — dort trennt sie die Pille
   sichtbar von der Wanne, seitlich schliesst sie jetzt buendig ab. */
.lib-tabs{padding:0.2rem 0;}

/* Der Farbwaehler nimmt die Hoehe des Eingabefelds daneben. Statt einer
   festen Zahl per align-self:stretch — dann stimmt es auch, wenn sich die
   Polsterung des Feldes mal aendert. Die Breite steht fest (2,55rem = die
   Hoehe, die das Feld mit seiner heutigen Polsterung hat), die Hoehe kommt
   aus der Zeile. aspect-ratio waere eleganter, hebelt aber align-self:stretch
   aus — der Waehler schrumpfte damit auf Inhaltsgroesse.
   margin-bottom faellt weg: er hat keinen Sockel, und der reservierte Platz
   haette ihn genau um diese 4 px kuerzer gemacht als das Feld. */
.catm-new .rt-color-trigger,.unitm-new .rt-color-trigger{
  align-self:stretch;height:auto;width:2.55rem;margin-bottom:0;
}

/* Nachtrag: der Farbwaehler-Knopf steckt in .rt-color-wrap (das braucht
   position:relative fuer die aufklappende Palette). Das Flex-Element der
   Zeile ist damit der WRAPPER, nicht der Knopf — mein align-self am Knopf
   lief deshalb ins Leere und er blieb auf Inhaltshoehe. Jetzt streckt sich
   der Wrapper, und der Knopf fuellt ihn aus. */
.catm-new .rt-color-wrap,.unitm-new .rt-color-wrap{
  align-self:stretch;display:flex;
}
.catm-new .rt-color-trigger,.unitm-new .rt-color-trigger{
  height:auto;align-self:stretch;
}

/* Die beiden Knoepfe in der Teilen-Liste trugen verschiedene Schriftgroessen:
   "Teilen" als .btn-primary 0,92rem, "Nicht mehr teilen" als .btn-del
   0,82rem — nebeneinander in derselben Zeile ein sichtbarer Sprung.
   Beide jetzt auf 0,8rem und Gewicht 600 — die Zeile ist ein Listeneintrag,
   kein Bildschirm mit Hauptaktion. Welcher Knopf was tut, sagt die Flaeche
   (gefuellt gegen grau), dafuer braucht es keinen Groessenunterschied. */
.share-hh-row button{font-size:0.8rem;font-weight:600;padding:0.3rem 0.65rem!important;}

/* Datumsfeld schmal, aber OHNE feste rem-Breite. Die feste Breite (frueher
   6,8rem) war am deutschen Format "30.08.2026" auf einem Rechner ausgemessen;
   bei US-Anzeige ("08/30/2026"), britischem Format oder groesserer
   Systemschrift schnitt Chrome die Jahreszahl ab und meldete es nicht als
   Ueberlauf. Jetzt bekommt die Eingabe genau ihre Inhaltsbreite
   (max-content) und der Rahmen links die Polsterung fuers Icon — das Feld
   waechst so mit jedem Anzeigeformat mit. */
.date-field{padding:0.6rem 0.8rem 0.6rem 2rem;}
.date-field>svg{left:0.75rem;}
.date-field input[type="date"]{width:max-content;min-width:0;padding:0;}
.date-field input[type="date"]::-webkit-inner-spin-button{display:none;}


/* Der Aufklapper "Zutatenmengen / Zeit anpassen" trug noch Chromes Standard-
   Dreieck — er war bei der Vereinheitlichung uebersehen worden, weil er als
   einziger ohne eigene Klasse auskommt (details.field). Jetzt derselbe
   drehende Chevron rechtsbuendig wie alle anderen. */
details.field>summary{display:flex;align-items:center;gap:0.5rem;list-style:none;}
details.field>summary::-webkit-details-marker{display:none;}
details.field>summary::after{
  content:'';margin-left:auto;color:var(--active-accent);transition:transform .15s;display:inline-block;width:13px;height:13px;flex-shrink:0;background:currentColor;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.49' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 6 6 6-6 6'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.49' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 6 6 6-6 6'/%3E%3C/svg%3E") center/contain no-repeat;}
details.field[open]>summary::after{transform:rotate(90deg);}

/* Style 3 traegt dieselbe Schrift wie Style 4 — in beiden Grundtoenen.
   Flaeche und Kante waren schon identisch (beide aus --btn-face2/--btn-edge2),
   nur die Schrift lief auseinander: im Hellen terrakotta, im Dunklen --text.
   Damit sah dieselbe Rolle je nach Grundton verschieden aus. Die
   Farbidentitaet steckt in der Kante, die Schrift muss sie nicht doppeln. */
.btn-accent{color:var(--text);}
@media(hover:hover){
  .btn-accent:hover{color:var(--text);}
}

/* "Wer isst mit?" ist jetzt auch im Hellen voll gefuellt — damit traegt die
   Schrift zum ersten Mal direkt auf der Akzentflaeche. Zwei helle Themes
   fallen dabei unter 4,5:1: Basic (4,40:1) und Peach (4,14:1). Peach war
   schon bei den Themefarben eine bewusste Ausnahme ("zu braun"), Basic ist
   neu betroffen.
   Statt die Themefarben anzufassen, wird nur DIESE Flaeche so weit
   abgedunkelt, dass sie die Grenze schafft — der Akzent bleibt ueberall
   sonst unveraendert (Sortier-Knopf, aktive Chips, Kacheln). */
[data-theme="light"],[data-theme="peach"]{
  --btn-stark-face:color-mix(in srgb,var(--active-accent) 88%,#000);
  --btn-stark-edge:color-mix(in srgb,var(--active-accent) 48%,#000);
}

/* ── Unklare Zutaten unter den Naehrwerten ─────────────────────
   Bewusst KEINE Warnfarbe: eine Sahne ohne Fettangabe ist keine Gefahr,
   sondern eine Ungenauigkeit — die Fehlerfarbe bleibt echten Problemen
   vorbehalten (wie bei den Praeferenz-Hinweisen). Deshalb ruhige Flaeche,
   Kante in der Markenfarbe, damit es trotzdem als Hinweis gelesen wird. */
.nutri-unklar{
  margin-top:0.8rem;padding:0.7rem 0.8rem;
  background:var(--surface2);border-left:3px solid var(--rezept);
  border-radius:0 var(--r-xs) var(--r-xs) 0;
}
.nutri-unklar-kopf{font-size:0.8rem;font-weight:700;color:var(--text);margin-bottom:0.45rem;line-height:1.35;}
.nutri-unklar ul{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:0.4rem;}
.nutri-unklar li{font-size:0.76rem;color:var(--text-sub);line-height:1.4;}
.nutri-unklar li b{color:var(--text);font-weight:600;}
/* Die betroffenen Zeilen in eigener Zeile: bei drei Zutaten hintereinander
   liest sich das sonst als Fliesstext und die Spanne geht darin unter. */
.nu-zutaten{display:block;font-size:0.72rem;opacity:0.8;margin-top:0.05rem;}
.nutri-unklar-fuss{font-size:0.72rem;color:var(--text-sub);line-height:1.4;margin:0.6rem 0 0;font-style:italic;}

/* ── Naehrwert-Schaetzung ──────────────────────────────────────
   Das Ergebnis steht bewusst nicht wie ein Messwert da: "ca.", die
   Bezugsgroesse gleich darunter, und die Aufschluesselung eine Ebene tiefer,
   damit man sie aufmachen KANN, aber nicht muss. Wer nachrechnet, findet in
   der Summe der Posten die Kopfzahl wieder. */
#nutri-schaetzen .btn-accent{margin-top:0.8rem;}
.nutri-ergebnis{
  margin-top:0.9rem;padding:0.8rem 0.85rem;
  background:var(--surface2);border:1.5px solid var(--border);border-radius:var(--r-md);
}
.nutri-zahl{font-family:'Literata',Georgia,serif;font-size:1.15rem;font-weight:600;color:var(--text);line-height:1.25;}
.nutri-bezug{font-size:0.75rem;color:var(--text-sub);margin-top:0.1rem;}
.nutri-posten{margin-top:0.7rem;}
.nutri-posten summary{
  font-size:0.76rem;font-weight:600;color:var(--rezept);cursor:pointer;
  list-style:none;padding:0.15rem 0;
}
.nutri-posten summary::-webkit-details-marker{display:none;}
.nutri-posten summary::before{content:'▸ ';font-size:0.9em;}
.nutri-posten[open] summary::before{content:'▾ ';}
.nutri-posten ul{margin:0.4rem 0 0;padding:0;list-style:none;display:flex;flex-direction:column;gap:0.2rem;}
.nutri-posten li{
  display:flex;justify-content:space-between;gap:0.8rem;
  font-size:0.76rem;color:var(--text-sub);
}
.nutri-posten li b{color:var(--text);font-weight:600;font-variant-numeric:tabular-nums;flex-shrink:0;}
.nutri-annahmen{margin-top:0.7rem;font-size:0.75rem;color:var(--text-sub);line-height:1.45;}
.nutri-annahmen b{display:block;color:var(--text);font-size:0.72rem;font-weight:700;
  letter-spacing:0.05em;text-transform:uppercase;margin-bottom:0.25rem;}
.nutri-annahmen ul{margin:0;padding-left:1rem;display:flex;flex-direction:column;gap:0.2rem;}
.nutri-warnung{font-size:0.72rem;color:var(--text-sub);line-height:1.4;margin:0.7rem 0 0;font-style:italic;}
.nutri-fehler{font-size:0.78rem;color:var(--err-text);line-height:1.4;margin:0.8rem 0 0;}

/* Die Reiterleiste der Naehrwert-Quelle ist schmaler als die im Dashboard —
   sie sitzt in einem Aufklappblock, nicht ueber der ganzen Seite. Alles
   andere (Pille, Farben, Bewegung) kommt von .lib-tabs/.lib-tab. */
/* padding hier bewusst "0.2rem 0" und nicht "0.2rem": .nutri-tabs steht im
   Blatt NACH der Korrektur an .lib-tabs (gleiche Spezifitaet, spaetere
   Regel) und hat deren seitliche Polsterung damit wieder eingefuehrt — links
   und rechts blieb ein schmaler Streifen Wannenfarbe stehen, weil die Pille
   ueber offsetLeft sitzt und die Polsterung mitzaehlt. Wer hier wieder einen
   Kurzwert einsetzt, holt sich den Streifen zurueck. */
.nutri-tabs{margin:0 0 0.7rem;padding:0.2rem 0;}
.nutri-tabs .lib-tab{padding:0.34rem 0.5rem;font-size:0.82rem;}
.nutri-spaeter{font-size:0.78rem;color:var(--text-sub);line-height:1.45;margin:0.8rem 0 0;}
