/* =====================================================================
   GEMEINSAME MENUE-KARTEN (Gastansicht UND Admin-Speisekarte)
   Kategorie-Raster/-Karten und Gerichte-Karten -- ausgelagert aus base.css,
   damit die Admin-Speisekarte (WYSIWYG) exakt dieselben Darstellungsregeln
   nutzt wie die Gastansicht und beide nicht auseinanderlaufen. Alle Farben,
   Radien, Schatten und Schriften kommen aus den Design-Tokens
   (tokens.css/themes.css); die Preset-spezifischen Strukturregeln stehen in
   themes.css (dort mit ".phone" begrenzt -- der Admin-Canvas traegt
   dieselbe Klasse).
   Reihenfolge in index.html: base.css -> menuCards.css -> themes.css.
   ===================================================================== */

/* ---------- Category grid ---------- */
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  gap: 16px;
  padding: 6px 24px 32px;
}

@media (max-width: 340px) {
  .grid { grid-template-columns: 1fr; gap: 14px; }
}

.cat-card {
  border-radius: var(--card-radius);
  background: var(--c-surface);
  border: var(--card-border);
  cursor: pointer;
  text-align: left;
  padding: 0;
  overflow: hidden;
  box-shadow: var(--card-shadow);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  transform: translateZ(0);
  -webkit-tap-highlight-color: transparent;
}

.cat-card:active { transform: scale(0.97); box-shadow: var(--sh-sm); }
@media (hover: hover) {
  .cat-card:hover { box-shadow: var(--card-shadow-hover); }
}

/* Kachel = eine durchgehende Bild-/Tint-Flaeche; Name/Anzahl/Chevron liegen
   als Overlay am unteren Rand darueber (bei Bild: mit Verlaufs-Scrim fuer
   Lesbarkeit; ohne Bild: auf einer schlichten, deckenden Flaeche). Dadurch
   ergibt sich die Kachelhoehe einzig aus dem Seitenverhaeltnis der
   Bild-/Tint-Flaeche -- automatisch gleich hohe Kacheln, ob mit oder ohne
   Bild, ohne separate min-height-Krücke. */
.cat-thumb {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 5;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32px;
  background: var(--tint);
  overflow: hidden;
}

/* Bildausschnitt (categories.image_transform, siehe logoRender.js:
   imageTransformStyle). Ohne gepflegte Werte (50%/50%/Zoom 1) identisch zur
   bisherigen Darstellung. object-position verschiebt den bei object-fit:cover
   ueberstehenden Teil (z.B. Querformat in hoher Kachel), scale+translate
   (gleiche lueckenlose Formel wie beim Logo, logo.css) den ueber den Zoom
   verfuegbaren Teil -- beide folgen denselben x/y-Werten, die Kachel bleibt
   dabei immer vollstaendig gefuellt. */
.cat-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--img-pos-x, 50%) var(--img-pos-y, 50%);
  display: block;
  transform:
    scale(var(--img-scale, 1))
    translate(
      calc((50% - var(--img-pos-x, 50%)) * (var(--img-scale, 1) - 1) / var(--img-scale, 1)),
      calc((50% - var(--img-pos-y, 50%)) * (var(--img-scale, 1) - 1) / var(--img-scale, 1))
    );
  transform-origin: center;
}

/* Huelle um Kategorie-Bild bzw. -Icon (guest.js). Im normalen Layout ohne
   eigene Box (display:contents = Layout wie zuvor); das Kompakt-Layout
   (themes.css) macht daraus das kleine Bildchen. */
.cat-icon { display: contents; }

/* Generischer Kategorie-Highlight (categories.highlight, z.B. Mittagsmenü/
   Tageskarte/Empfehlung/Special) -- rein visuelle Hervorhebung, kombinierbar
   mit visibility. Bewusst OHNE eingebauten Text ("Empfehlung"/"Hervorgehoben"
   o.ae.) -- der Kategoriename selbst bleibt der Inhalt, hier nur eine
   dezent-hochwertige visuelle Anmutung: ein feiner Akzent-Rahmen samt
   weichem Glanzsaum oben (statt einer harten zweifarbigen Umrandung) plus
   ein kleines, randloses Funkel-Symbol statt eines technisch wirkenden
   gefuellten Kreis-Badges. Nutzt ausschliesslich bestehende Theme-Token
   (--c-accent, --card-radius, --card-shadow-hover) -- passt sich dadurch
   automatisch an Modern/Elegant/Klassisch und die gewaehlte Akzentfarbe an,
   ohne eigenen Sonderfall je Preset.
   Admin (admin.css, .am-phone .cat-card.is-highlight) nimmt diese Wirkung
   bewusst wieder zurueck -- dort reicht eine schlichte Kennzeichnung, siehe
   dortiger Kommentar. */
.cat-card.is-highlight {
  position: relative;
  box-shadow: 0 0 0 1.5px var(--c-accent), var(--card-shadow-hover);
}
.cat-card.is-highlight::before {
  content: '';
  position: absolute;
  top: 0; left: 8%; right: 8%;
  height: 2.5px;
  border-radius: 0 0 2px 2px;
  background: linear-gradient(90deg, transparent, var(--c-accent), transparent);
  z-index: 5;
  pointer-events: none;
}
.cat-highlight-flag {
  position: absolute; left: 10px; top: 10px; z-index: 4;
  display: flex; align-items: center; justify-content: center;
  width: 27px; height: 27px;
  border-radius: 50%;
  font-size: 13px; line-height: 1;
  color: #fff;
  background: rgba(20,16,12,0.4);
  box-shadow: 0 0 0 1px rgba(255,255,255,0.25), 0 2px 8px rgba(0,0,0,0.3);
  backdrop-filter: blur(2px);
  text-shadow: 0 1px 2px rgba(0,0,0,0.5);
}

/* Dekoratives Botanik-Ornament (siehe guest.js: catHighlightOrnamentSVG) --
   nur sichtbar, wenn die Kachel tatsaechlich kein Foto zeigt (inkl. eines
   zur Laufzeit fehlgeschlagenen Bildes, siehe .no-image oben) UND im
   grossen Bild-Kachel-Layout (nicht im "Kompakt"-Listenlayout, siehe
   themes.css -- dort ist .cat-thumb nur eine schmale Zeile, in die ein
   Eckenornament nicht passt). Reine CSS/SVG-Grafik, keine externe Datei. */
.cat-highlight-ornament { display: none; }
/* MIT Foto: dieselbe Zweig-Sprache, aber dezenter als ohne Foto -- und trotzdem wahrnehmbar auch
   auf unruhigen Food-Fotos. Nur die beiden rechten Zweige ragen leicht vom Rand ins Bild (links
   oben sitzt die Marke, unten der Titel). Farbe: gedecktes Salbeigruen, leicht zur Akzentfarbe
   des Themes gezogen (statt fast unsichtbarem Weiss); Kontrast auf hellen wie dunklen Bildern
   durch einen feinen dunklen Saum (mehrere drop-shadows = Umriss) und etwas kraeftigere Linie/
   Blaetter. Das Foto bleibt Hauptinhalt: die Zweige sind duenn, klein und am Rand. */
.cat-card.is-highlight:not(.no-image) .cat-highlight-ornament {
  display: block;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  color: color-mix(in srgb, #A8C48C 78%, var(--c-accent));
  opacity: 0.85;
  filter: drop-shadow(0 0 0.5px rgba(0, 0, 0, 0.8)) drop-shadow(0 0 1.2px rgba(0, 0, 0, 0.55)) drop-shadow(0 1px 2.5px rgba(0, 0, 0, 0.35));
  pointer-events: none;
}
.cat-card.is-highlight:not(.no-image) .cat-highlight-ornament .chg-sprig-ml { display: none; }
.cat-card.is-highlight:not(.no-image) .cat-highlight-ornament path { stroke-width: 1.7; }
.cat-card.is-highlight:not(.no-image) .cat-highlight-ornament ellipse { opacity: 1; }
.cat-card.is-highlight:not(.no-image) .chg-sprig-tr,
.cat-card.is-highlight:not(.no-image) .chg-sprig-mr { transform-box: fill-box; transform-origin: 100% 50%; }
.cat-card.is-highlight:not(.no-image) .chg-sprig-tr { transform: scale(1); }
.cat-card.is-highlight:not(.no-image) .chg-sprig-mr { transform: scale(0.82); }
.cat-card.is-highlight.no-image .chg-sprig-mr { display: none; }
.cat-card.is-highlight.no-image .cat-highlight-ornament {
  display: block;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  color: var(--c-accent);
  opacity: 0.55;
  pointer-events: none;
}
/* Flaeche ohne Foto: warmer Akzent-Schimmer ueber der Tint-Farbe plus ein
   feiner Innenrahmen wie bei gedruckten Menuekarten -- zusammen mit dem
   Ornament ergibt das schon ohne Text eine erkennbar "besondere" Kachel.
   Rein aus Theme-Token abgeleitet (color-mix auf --c-accent). */
.cat-card.is-highlight.no-image .cat-thumb {
  background:
    linear-gradient(155deg, color-mix(in srgb, var(--c-accent) 20%, transparent), transparent 62%),
    var(--tint);
}
.cat-card.is-highlight.no-image .cat-thumb::after {
  content: '';
  position: absolute;
  inset: 7px;
  border: 1px solid color-mix(in srgb, var(--c-accent) 50%, transparent);
  border-radius: max(6px, calc(var(--card-radius) - 7px));
  z-index: 1;
  pointer-events: none;
}
.cat-highlight-ornament path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}
.cat-highlight-ornament ellipse { fill: currentColor; opacity: 0.8; }

/* Weicher, mehrstufiger Verlauf statt eines harten Zwei-Punkt-Gradienten:
   die oberen ~30% des Fotos bleiben praktisch unangetastet sichtbar, danach
   nimmt die Abdunklung sanft zu und erreicht erst im unteren Drittel (wo der
   Text liegt) genug Kontrast fuer helle wie unruhige Essensfotos -- auch bei
   mehrzeiligen Kategorienamen (z.B. "Spezialgerichte – Schmortopf aus dem
   Holzofen"), die weiter nach oben reichen als eine einzelne Textzeile. */
.cat-scrim {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 78%;
  background: linear-gradient(
    180deg,
    rgba(15, 12, 10, 0) 0%,
    rgba(15, 12, 10, 0.05) 30%,
    rgba(15, 12, 10, 0.4) 62%,
    rgba(15, 12, 10, 0.72) 85%,
    rgba(15, 12, 10, 0.8) 100%
  );
  pointer-events: none;
}
/* Ohne Bild (oder wenn ein Bild nicht laedt) hat die Flaeche keinen
   Foto-Untergrund, der abgedunkelt werden muesste. */
.cat-card.no-image .cat-scrim { display: none; }

.cat-overlay {
  position: absolute;
  z-index: 2;
  left: 0; right: 0; bottom: 0;
  padding: var(--sp-3) var(--sp-4);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-2);
}
/* Der Textblock darf schrumpfen, damit ein sehr langes Wort (breite Schrift,
   schmale Kachel) umbricht statt aus der Kachel zu ragen. */
.cat-overlay > div:first-child { min-width: 0; }
.cat-card.no-image .cat-overlay {
  background: var(--c-surface);
}

.cat-name {
  font-size: 15.5px;
  font-weight: 700;
  color: #FFFFFF;
  line-height: 1.3;
  word-break: normal;
  overflow-wrap: break-word;
  hyphens: none;
  text-shadow: 0 1px 3px rgba(0,0,0,0.55), 0 2px 10px rgba(0,0,0,0.35);
}
.cat-card.no-image .cat-name { color: var(--c-ink); text-shadow: none; }

.cat-count {
  display: block;
  font-size: var(--fs-meta);
  color: rgba(255,255,255,0.85);
  font-weight: 400;
  margin-top: 3px;
  text-shadow: 0 1px 4px rgba(0,0,0,0.5);
}
.cat-card.no-image .cat-count { color: var(--c-ink-soft); text-shadow: none; }

.cat-chevron {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  margin-bottom: 1px;
  color: rgba(255,255,255,0.9);
  filter: drop-shadow(0 1px 3px rgba(0,0,0,0.45));
}
.cat-card.no-image .cat-chevron { color: var(--c-ink-soft); filter: none; }
.cat-chevron svg { width: 100%; height: 100%; stroke: currentColor; fill: none; stroke-width: 2; }


/* --- Empfehlungs-/Highlight-Badge auf Gerichte-Karten (rein datengetrieben) --- */
.dish-highlight {
  font-size: 10.5px;
  font-weight: 700;
  color: var(--c-accent-2);
  margin-bottom: 2px;
}

/* Kategorie-/Unterkategorie-Herkunft eines Gerichts -- nur in restaurantweiten
   Ergebnislisten (z.B. "Was passt zu mir?") sichtbar, wo ein Gericht ohne
   diesen Hinweis nicht erkennbar einer Kategorie zuzuordnen waere. */
.dish-category-label {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--c-ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin-bottom: 3px;
}

/* --- Verfuegbarkeits-Status (optional, restaurant-gesteuert) --- */
.dish.is-soldout { opacity: 0.55; }
.dish.is-soldout .dish-thumb { filter: grayscale(0.4); }
.soldout-badge {
  font-size: 10px;
  font-weight: 700;
  color: var(--c-ink-soft);
  background: var(--c-line);
  border-radius: 5px;
  padding: 2px 7px;
  letter-spacing: 0.02em;
}


/* Unterkategorie-Reiter (Gastansicht; im Admin als sortierbare Reiter) */
.subtabs {
  display: flex;
  gap: 8px;
  padding: 18px 20px 6px;
  overflow-x: auto;
}

.subtabs button {
  flex-shrink: 0;
  padding: 8px 16px;
  border-radius: var(--tab-radius);
  border: none;
  background: var(--c-card);
  box-shadow: 0 2px 6px rgba(0,0,0,0.05);
  color: var(--c-tab-ink);
  font-size: 12.5px;
  font-family: var(--font-body);
  font-weight: 600;
  cursor: pointer;
}

.subtabs button.active {
  background: var(--c-accent);
  color: var(--c-on-accent);
  box-shadow: 0 6px 14px -4px var(--c-accent);
}

/* Scroll-Hinweise der Gast-Unterkategorie-Reiter (guest.js:
   updateSubtabsScrollHints). Native Scrollleiste ausgeblendet; stattdessen
   Verlauf + Chevron-Pfeil an der Seite, auf der noch weitere Reiter liegen.
   Passen alle Reiter in den sichtbaren Bereich, bleibt beides verborgen. */
.subtabs-wrap { position: relative; }
.subtabs-wrap .subtabs {
  scrollbar-width: none;
  -ms-overflow-style: none;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.subtabs-wrap .subtabs::-webkit-scrollbar { display: none; }
.subtabs-arrow {
  position: absolute;
  top: 18px; bottom: 6px;
  width: 44px;
  display: none;
  align-items: center;
  border: none;
  padding: 0 6px;
  cursor: pointer;
  color: var(--c-ink-soft);
  z-index: 3;
}
.subtabs-arrow svg { width: 20px; height: 20px; stroke: currentColor; fill: none; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.subtabs-arrow-left {
  left: 0;
  justify-content: flex-start;
  padding-left: 8px;
  background: linear-gradient(90deg, var(--c-bg) 35%, transparent);
}
.subtabs-arrow-right {
  right: 0;
  justify-content: flex-end;
  padding-right: 8px;
  background: linear-gradient(270deg, var(--c-bg) 35%, transparent);
}
.subtabs-wrap.can-left .subtabs-arrow-left,
.subtabs-wrap.can-right .subtabs-arrow-right { display: flex; }
.subtabs-arrow:hover { color: var(--c-accent); }
.subtabs-arrow:focus-visible { outline: 2px solid var(--c-accent); outline-offset: -2px; border-radius: 8px; }
[dir="rtl"] .subtabs-arrow svg { transform: scaleX(-1); }

.items { padding: 16px 24px 28px; display: flex; flex-direction: column; gap: 14px; }

.dish {
  display: flex;
  gap: 14px;
  padding: 14px;
  background: var(--c-card);
  border-radius: var(--dish-radius);
  box-shadow: var(--dish-shadow);
}

.dish-thumb {
  width: var(--dish-thumb);
  height: var(--dish-thumb);
  border-radius: var(--thumb-radius);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  background: var(--tint);
  overflow: hidden;
}

/* Foto-Ausschnitt (dishes.image_transform -> --img-scale/--img-pos-x/-y, siehe
   logoRender.js: imageTransformStyle) -- dieselbe lueckenlose Formel wie
   .cat-thumb img. Ohne Variablen: bisherige Darstellung (cover, Mitte, kein Zoom). */
.dish-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--img-pos-x, 50%) var(--img-pos-y, 50%);
  transform:
    scale(var(--img-scale, 1))
    translate(
      calc((50% - var(--img-pos-x, 50%)) * (var(--img-scale, 1) - 1) / var(--img-scale, 1)),
      calc((50% - var(--img-pos-y, 50%)) * (var(--img-scale, 1) - 1) / var(--img-scale, 1))
    );
  transform-origin: center;
}

.dish-body { flex: 1; min-width: 0; }

/* Grid statt Flex: der Preis bleibt dadurch immer in einer eigenen, festen
   Spalte rechts -- ein langer Gerichtname/Highlight-Tag in Spalte 1 wickelt
   nur innerhalb dieser Spalte um und kann den Preis nie in eine neue Zeile
   verdraengen (das passierte vorher bei flex-wrap, siehe Aufgabenstellung). */
.dish-top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto; /* minmax(0,..): ein sehr langes Wort (breite Schrift) darf umbrechen statt den Preis zu verdraengen */
  align-items: start;
  gap: 4px 10px;
}

.dish-name {
  font-family: var(--font-dish);
  font-size: 16px;
  line-height: 1.4;
  font-weight: 700;
  color: var(--c-ink);
  overflow-wrap: break-word;
}

.dish-price {
  font-family: var(--font-dish);
  font-size: 15px;
  font-weight: 700;
  color: var(--c-accent-2);
  white-space: nowrap;
  text-align: right;
  min-width: 58px;
}
/* Gericht ohne Preis: leere Spalte komplett entfernen statt einen leeren
   Block stehen zu lassen -- die Namensspalte (1fr) nimmt den Platz dann
   automatisch ein. */
.dish-price:empty { display: none; min-width: 0; }

.dish-desc {
  font-size: 14px;
  color: var(--c-text-body);
  line-height: 1.5;
  margin-top: 4px;
  overflow-wrap: break-word;
}
.dish-desc:empty { display: none; }

/* Feiner Akzentbalken links an JEDER Gerichtskarte (mit und ohne Bild, mit Tags,
   Varianten, Kennzeichnungen, langem Inhalt). URSACHE der frueher "fehlenden" Linie bei
   Suchtreffern: der Balken war nur fuer Karten OHNE Bild (.is-textonly) definiert -- ein
   Gericht mit Bild bekam ihn nie und fiel in Suche/Listen optisch aus der Reihe. Jetzt gilt
   er fuer alle Karten (nur Plus-Kacheln des Admins ausgenommen). In den Preset-/Layout-
   Varianten, die die Karte ohnehin ohne Flaeche zeigen (Elegant, Klassisch, Kompakt),
   entfaellt der Balken wie bisher. */
.dish:not(.am-add-dish) { position: relative; padding-left: 18px; }
.dish:not(.am-add-dish)::before {
  content: '';
  position: absolute;
  left: 0; top: 14px; bottom: 14px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--c-accent);
  opacity: 0.55;
}
[data-theme="elegant"] .phone .dish:not(.am-add-dish)::before,
[data-theme="classic"] .phone .dish:not(.am-add-dish)::before,
[data-dish-layout="compact"] .phone .dish:not(.am-add-dish)::before { display: none; }
[data-theme="elegant"] .phone .dish:not(.am-add-dish),
[data-theme="classic"] .phone .dish:not(.am-add-dish),
[data-dish-layout="compact"] .phone .dish:not(.am-add-dish) { padding-left: 0; }
.dish-emoji { font-size: 0.95em; }

/* Preisvarianten (dish.variants, siehe dishVariantsHTML in guest.js): eigener
   kompakter Block unter der Beschreibung, durch eine feine Linie von ihr
   getrennt -- Name links, Preis sauber rechtsbuendig in fester Spalte
   (tabellarische Ziffern), damit er nicht wie weiterer Fliesstext wirkt. */
.dish-variants {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin-top: 11px;
  padding-top: 10px;
  border-top: 1px solid var(--c-line);
}

/* Eine Variante: Name ........ Preis -- die Fuehrungslinie verbindet beides
   (ruhige Ausrichtung, auch bei kurzen Namen in breiten Karten), lange Namen
   brechen um statt den Preis zu verdraengen. */
.dish-variant-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 14px;
  line-height: 1.35;
}

.dish-variant-name {
  flex: 0 1 auto;
  min-width: 0;
  color: var(--c-ink);
  font-weight: 500;
  overflow-wrap: break-word;
}

/* Variantennummer (z. B. 33a) vor dem Namen: "33a · Name" */
.dish-variant-number {
  color: var(--c-ink-soft);
  font-weight: 600;
  font-variant-numeric: lining-nums tabular-nums;
  white-space: nowrap;
}
.dish-variant-number::after { content: "\00b7"; margin: 0 6px; font-weight: 400; }

.dish-variant-leader {
  flex: 1 1 12px;
  min-width: 10px;
  border-bottom: 1px dotted var(--c-ink-soft);
  transform: translateY(-0.28em);
  opacity: 0.4;
}

.dish-variant-price {
  flex: 0 0 auto;
  font-family: var(--font-dish);
  font-weight: 600;
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--c-accent-2);
  white-space: nowrap;
  text-align: right;
}

/* Tags am Gericht (guest.js: dishTagBadgesHTML): kleine Pillen mit Symbol, klar von den
   eckigen Allergen-/Zusatzstoff-Badges (Buchstabe+Zahl) unterscheidbar. Umbrechen
   bei Bedarf in weitere Zeilen und nie ueber die Kartenbreite hinaus. */
.dish-tags { display: flex; flex-wrap: wrap; gap: 4px 5px; margin-top: 8px; min-width: 0; }
/* Tags und Varianten sauber trennen: die feine Linie des Varianten-Blocks bleibt, bekommt
   nach den Tags aber etwas mehr Luft. Gibt es davor nichts (kein Text, keine Tags), entfaellt
   die Linie -- keine sinnlose Trennlinie direkt unter dem Titel. */
.dish-tags + .dish-variants { margin-top: 14px; padding-top: 12px; }
.dish-top + .dish-variants, .dish-desc:empty + .dish-variants { margin-top: 8px; padding-top: 0; border-top: 0; }
.dish-tag {
  display: inline-flex; align-items: center; gap: 4px; max-width: 100%;
  font-size: 10.5px; font-weight: 600; line-height: 1.3;
  padding: 2px 8px 2px 6px; border-radius: 999px;
  color: var(--c-accent-2);
  background: color-mix(in srgb, var(--c-accent) 11%, transparent);
  overflow-wrap: anywhere;
}
.dish-tag-icon { font-size: 11px; line-height: 1; flex: none; }

/* Unterste Zeile der Karte: Kennzeichnungen links (sekundaer), Merken-Button rechts.
   Ohne beides entfaellt die Zeile komplett (kein leerer Abstand). */
/* Zwei feste Spuren: Kennzeichnungen links (minmax(0,1fr) = nie breiter als der Rest),
   Aktionen (Merken-Button) rechts in eigener, reservierter Spur. Damit koennen auch viele
   Allergene/Zusatzstoffe/Tags nie bis in den Aktionsbereich laufen -- sie brechen um. */
.dish-bottom {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  column-gap: 10px;
  margin-top: 11px;
}
.dish-bottom > .allergens { grid-column: 1; }
.dish-bottom > .bookmark-btn { grid-column: 2; justify-self: end; }
/* Leere Zeile entfaellt -- aber NICHT, wenn sie die Admin-Werkzeuge (Verfuegbar/Mehr) traegt.
   URSACHE der "fehlenden" Aktionen im Admin: diese Regel kannte nur Allergene und den
   Merken-Button; eine Admin-Karte ohne Allergene/Zusatzstoffe verlor dadurch die GANZE Zeile
   samt Werkzeugen (unabhaengig von Bild, Tags, Varianten, Status). */
.dish-bottom:not(:has(.allergens span, .bookmark-btn, .am-dish-tools)) { display: none; }

/* Allergene ("A10") und Zusatzstoffe ("Z2") sind zwei eigene, rechtlich
   getrennte Kategorien mit je eigener Numerierung -- ZWEI unabhaengige
   Unterscheidungsmerkmale (Buchstabe im Text UND gefuellt/umrandet), nicht
   nur Farbe: ein "10" waere sonst nicht von einem Zusatzstoff "10"
   unterscheidbar, und Farbe allein waere fuer Farbsehschwaeche/Graustufen-
   Druck nicht zuverlaessig genug. Beide Gruppen stehen sichtbar getrennt
   nebeneinander (.badge-group), optisch leiser als Name und Preis. */
.allergens {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px 12px;
  flex: 1 1 auto;
  min-width: 0;
}
.badge-group { display: inline-flex; flex-wrap: wrap; gap: 4px; max-width: 100%; min-width: 0; }

.allergens span {
  font-size: 10.5px;
  line-height: 1.3;
  color: var(--c-text-meta);
  background: var(--c-line);
  border-radius: 5px;
  padding: 2px 6px;
}
.allergens .badge-group { background: transparent; padding: 0; border-radius: 0; font-size: inherit; }
.allergens span.allergen-badge {
  font-weight: 700;
}
.allergens span.additive-badge {
  background: transparent;
  border: 1px solid var(--c-border);
  color: var(--c-ink-soft);
  font-weight: 700;
}

/* Legende unter den Gerichten (guest.js: renderAllergenLegend): gleiche
   Schluessel-Chips wie auf den Karten, je Gruppe eine Ueberschrift; deutlich
   lesbarer als Fliesstext, aber leiser als Karten-Inhalt. */
.legend .legend-group { margin-top: 14px; }
.legend .legend-group:first-child { margin-top: 0; }
.legend .legend-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-ink-soft);
  margin-bottom: 7px;
}
.legend .legend-items {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 6px 16px;
}
.legend .legend-item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--c-text-body);
}
.legend .legend-key {
  flex: 0 0 auto;
  min-width: 30px;
  text-align: center;
  font-size: 10.5px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 5px;
  background: var(--c-line);
  color: var(--c-text-meta);
}
.legend .legend-key-z { background: transparent; border: 1px solid var(--c-border); color: var(--c-ink-soft); }
.legend .allergen-disclaimer {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--c-line);
  font-size: 12px;
  line-height: 1.55;
  color: var(--c-text-meta);
}
.legend .allergen-disclaimer.allergen-none { margin-top: 0; padding-top: 0; border-top: none; }


/* Artikelnummer vor dem Gerichtnamen -- nur wenn dishCardHTML mit
   options.showNumber aufgerufen wird (aktuell nur "Meine Auswahl"), siehe
   dortiger Kommentar. */
.dish-number {
  color: var(--c-ink-soft);
  font-weight: 600;
  margin-right: 2px;
}


.cat-card {
  animation: cardIn 0.5s cubic-bezier(.2,.8,.2,1) backwards;
}
.cat-card:nth-child(1) { animation-delay: 0.05s; }
.cat-card:nth-child(2) { animation-delay: 0.1s; }
.cat-card:nth-child(3) { animation-delay: 0.15s; }
.cat-card:nth-child(4) { animation-delay: 0.2s; }

@keyframes cardIn {
  from { opacity: 0; transform: translateY(18px) scale(0.95); }
  to { opacity: 1; transform: none; }
}

.dish {
  animation: cardIn 0.45s cubic-bezier(.2,.8,.2,1) backwards;
}
.dish:nth-child(1) { animation-delay: 0.04s; }
.dish:nth-child(2) { animation-delay: 0.09s; }
.dish:nth-child(3) { animation-delay: 0.14s; }
.dish:nth-child(4) { animation-delay: 0.19s; }
.dish:nth-child(5) { animation-delay: 0.24s; }

/* =====================================================================
   LANGE TITEL/BESCHREIBUNGEN: kein Ueberlauf, Preis bleibt in der Karte
   Ununterbrochene Zeichenketten (lange Woerter, URLs) brechen um
   (overflow-wrap:anywhere gilt auch fuer die Mindestbreite, anders als break-word),
   die Karte waechst nur in der Hoehe; Preis/Bilder/Badges behalten ihre Spalte.
   Normale, auch laengere Beschreibungen werden NICHT gekuerzt.
   ===================================================================== */
.dish, .dish-body, .dish-top > *, .dish-variants, .dish-variant-row, .cat-overlay > div { min-width: 0; }
.dish-name, .dish-desc, .dish-variant-name, .dish-highlight, .dish-category-label,
.cat-name, .cat-count, .item-header h2, .item-subtitle { overflow-wrap: anywhere; word-break: normal; }
.dish-price, .dish-variant-price { flex-shrink: 0; }
.dish-thumb { flex-shrink: 0; }
.dish { max-width: 100%; }
.items { min-width: 0; }
