:root {
  --color-bg-1: rgb(252, 250, 250);
  --color-bg-2: #eeeeec;
  --color-surface: #ffffff;
  --color-surface-alt: #f0f0ee;
  --color-ink: #2c2420;
  --color-text: #362c26;
  --color-text-muted: #8c7c70;
  --color-border: rgba(54, 44, 38, 0.1);

  --color-accent: rgb(236, 48, 19);
  --color-accent-dark: #c22710;
  --color-accent-soft: #fbe0da;
  --color-accent-ink: #ffffff;

  --color-sage: #55765d;
  --color-sage-soft: #e1ebe0;

  --color-plum: #7a4a8f;
  --color-plum-soft: #ece0ef;

  /* Nur fuer die Lokaltyp-Unterscheidung der Kartenpins (siehe .map-marker-pin
     unten) - Restaurants nutzen dafuer bewusst weiterhin --color-accent. */
  --color-venue-bar: #c17f17;
  --color-venue-cafe: #6b4423;

  --color-open: #3f7d5c;
  --color-open-bg: #e2f1e7;
  --color-closed: #b3453f;
  --color-closed-bg: #fbe6e2;
  --color-unclear: #8c7c70;
  --color-unclear-bg: #f1e9e1;

  --radius-sm: 10px;
  --radius: 16px;
  --radius-lg: 24px;

  --shadow-sm: 0 1px 2px rgba(44, 36, 32, 0.06), 0 1px 1px rgba(44, 36, 32, 0.04);
  --shadow: 0 12px 28px -14px rgba(44, 36, 32, 0.22), 0 2px 8px rgba(44, 36, 32, 0.05);
  --shadow-hover: 0 18px 38px -14px rgba(44, 36, 32, 0.28), 0 4px 12px rgba(44, 36, 32, 0.07);

  --font-display: "Archivo", "Segoe UI", -apple-system, Roboto, Helvetica, Arial, sans-serif;
  --font-body: "Archivo", "Segoe UI", -apple-system, Roboto, Helvetica, Arial, sans-serif;

  --bottom-nav-height: 4.25rem;
}

* {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--color-text);
  line-height: 1.45;
  background: var(--color-bg-1);
  min-height: 100vh;
  /* Platz fuer die fixe .bottom-nav, damit sie den unteren Seiteninhalt
     (letzte Karten, "Mehr laden", Community-Feed) nicht verdeckt. */
  padding-bottom: var(--bottom-nav-height);
  /* Ohne dies "kompensiert" der Browser (Scroll Anchoring) die Scroll-Position
     automatisch, sobald sich Inhalt oberhalb des sichtbaren Bereichs in der
     Groesse aendert - genau das passiert hier waehrend der 0.25s-Transition
     des einklappenden Headers und wirft die Seite dabei zurueck an den
     Scroll-Ausgangspunkt (besonders auffaellig, wenn insgesamt wenig
     Scroll-Spielraum vorhanden ist, z.B. in der Kartenansicht). */
  overflow-anchor: none;
}

.page-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--color-bg-1);
  transition: box-shadow 0.25s ease;
}

.page-header.is-scrolled {
  box-shadow: 0 10px 26px -18px rgba(44, 36, 32, 0.45);
}

.site-header {
  position: relative;
  padding: 3rem 1.5rem 1.25rem;
  text-align: center;
  transition: padding 0.25s ease;
}

.page-header.is-compact .site-header {
  padding: 0.9rem 1.5rem 0.75rem;
}

.auth-widget {
  position: absolute;
  top: 1.25rem;
  right: 1.5rem;
  display: flex;
  align-items: center;
  transition: top 0.25s ease;
  /* Ohne eigenen (nicht-auto) z-index bildet dieses position:absolute-Element
     selbst keinen eigenen Stacking-Context - der z-index:25 des darin
     verschachtelten .auth-user-details-Dropdowns wirkt dann inkonsistent
     gegenueber anderen positionierten Geschwister-Elementen im Header (z.B.
     dem Friend-Favorites-Button). Mit explizitem z-index hier ist die
     gesamte Auth-Widget-Gruppe zuverlaessig oberhalb der Schnellfilter. */
  z-index: 30;
}

.page-header.is-compact .auth-widget {
  top: 0.7rem;
}

.auth-btn {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.82rem;
  padding: 0.5rem 1.1rem;
  border-radius: 999px;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
}

.auth-btn:hover {
  background: var(--color-surface-alt);
}

/* Ausgeloggter Zustand: der Login-Button soll deutlich als eigene Aktion
   auffallen (nicht mit den neutralen Website/Maps-Buttons verwechselbar) -
   rot mit weissem Icon/Text, statt der neutralen .auth-btn-Optik. Der
   eingeloggte Zustand (.auth-user-toggle) bleibt bewusst unveraendert. */
#auth-login-btn {
  background: var(--color-closed);
  border-color: var(--color-closed);
  color: #fff;
}

#auth-login-btn:hover {
  background: var(--color-closed);
  opacity: 0.9;
}

.auth-icon {
  width: 1.05em;
  height: 1.05em;
  flex-shrink: 0;
}

/* Nur auf Mobile sichtbar (siehe Media Query weiter unten), sobald der
   Username geladen ist - ersetzt dort das Personen-Icon durch den ersten
   Buchstaben des Usernamens, damit auf einen Blick erkennbar ist, dass man
   eingeloggt ist. */
.auth-user-avatar-initial {
  display: none;
}

.auth-user-info {
  position: relative;
  display: flex;
  align-items: center;
}

/* Im eingeloggten Zustand auf Desktop nur den Usernamen zeigen, ohne
   vorangestelltes Icon - auf Mobile bleibt es (siehe Media Query unten)
   beim reinen Icon-Button, da dort ohnehin kein Platz fuer Text ist. */
.auth-user-toggle .auth-icon {
  display: none;
}

.auth-user-details {
  display: none;
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  /* Hoeher als .quick-filter-dropdown-panel (z-index: 20) - beide liegen im
     selben Stacking-Context von .page-header, das Profil-Menue soll dabei
     nicht vom Friend-Favorites-Dropdown ueberdeckt werden koennen. */
  z-index: 25;
  white-space: nowrap;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  min-width: 10rem;
  padding: 0.4rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-hover);
}

.auth-user-details.open {
  display: flex;
}

.auth-user-details-name {
  display: none;
}

.auth-user-name-label {
  font-weight: 400;
}

.auth-btn-text {
  display: inline-block;
  border: none;
  background: none;
  color: var(--color-text);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.82rem;
  text-align: left;
  padding: 0.5rem 0.6rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  text-decoration: none;
}

.auth-btn-text:hover {
  background: var(--color-surface-alt);
  color: var(--color-accent-dark);
}

@media (max-width: 860px) {
  .auth-widget {
    top: 0.85rem;
    right: 0.85rem;
  }

  /* Im eingeklappten (gescrollten) Header ist die Ueberschrift deutlich
     kleiner als der runde User-Button - top:50%/translateY zentriert den
     Button zuverlaessig auf der Headerhoehe, statt einen festen top-Wert
     zu erraten. Etwas mehr Bottom-Padding schafft dafuer Platz zu den
     Schnellfiltern darunter. */
  .page-header.is-compact .auth-widget {
    top: 50%;
    transform: translateY(-50%);
  }

  /* Die Fraunces-Ueberschrift hat oben etwas mehr Weissraum als die per
     Flex zentrierte Initiale im Button - minimaler Versatz nach unten
     gleicht das optisch aus. */
  .page-header.is-compact .site-header h1 {
    margin-top: 0.45rem;
  }

  .page-header.is-compact .site-header {
    padding-bottom: 1.15rem;
  }

  .auth-btn-label {
    display: none;
  }

  .auth-btn {
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    justify-content: center;
    gap: 0;
  }

  .auth-btn .auth-icon {
    width: 1.4rem;
    height: 1.4rem;
  }

  .auth-user-toggle .auth-icon {
    display: block;
  }

  .auth-user-toggle.has-username .auth-icon {
    display: none;
  }

  .auth-user-toggle.has-username .auth-user-avatar-initial {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.15rem;
    font-weight: 800;
  }

  .auth-user-details-name {
    display: block;
    padding: 0.5rem 0.6rem 0.3rem;
    font-weight: 400;
    font-size: 0.82rem;
    color: var(--color-ink);
  }
}

/* Detail-Popup fuer eine Community-Karte: zeigt beim Klick dieselbe grosse
   .card wie in der Suche (buildCardBodyHtml) mit allen Infos, statt nur der
   kompakten Community-Karte. Eigene, hoehere z-index-Ebene als .auth-modal/
   .bottom-nav, damit sie auch ueber der (fixed positionierten) Bottom-Nav
   liegt - aber unter .friend-favorite-popover (500), falls innerhalb des
   Detail-Popups auf den Freundes-Button geklickt wird. */
.restaurant-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(28, 22, 18, 0.45);
  z-index: 120;
}

.restaurant-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 121;
  width: min(460px, calc(100vw - 2rem));
  max-height: min(85vh, 720px);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-hover);
}

/* Nur der Body scrollt (nicht .restaurant-modal selbst) - so bleibt der
   Schliessen-Button oben rechts beim Scrollen fixiert statt mitzuwandern. */
.restaurant-modal-body {
  max-height: min(85vh, 720px);
  overflow-y: auto;
  border-radius: var(--radius-lg);
}

.restaurant-modal-body .card {
  margin: 0;
  box-shadow: none;
}

/* Halb ausserhalb der Karte positioniert statt oben rechts darueber - dort
   ueberlappte er sich mit den Favorit-/Bucket-List-Icons der grossen .card
   (dieselbe Ecke wie .card-actions-col), die dadurch teils unklickbar waren. */
.restaurant-modal-close {
  position: absolute;
  top: -0.7rem;
  right: -0.7rem;
  z-index: 1;
  border: none;
  background: var(--color-surface);
  color: var(--color-text-muted);
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 999px;
  font-size: 0.95rem;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
}

.auth-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(28, 22, 18, 0.45);
  z-index: 80;
}

/* Erfolgs-Animation nach dem Login (siehe playLoginSuccessFlash() in
   auth.js): ein Kreis in --color-accent (dieselbe Farbe wie die
   CTA-Buttons) waechst von der Bildschirmmitte aus per transform:scale, haelt
   kurz voll sichtbar, und blendet danach per opacity wieder aus - dahinter
   ist die Seite (auth-modal bereits geschlossen) laengst im eingeloggten
   Zustand. Durchmesser bewusst knapp bemessen (150vmax statt z.B. 300vmax):
   der Bildschirm-Eck-Abstand von der Mitte ist bei JEDEM Seitenverhaeltnis
   hoechstens ~70.7vmax (Extremfall quadratisches Fenster, Diagonale =
   vmax*sqrt(2)) - bei deutlich groesserem Durchmesser waere die Flaeche schon
   nach einem Bruchteil der Transition-Dauer voll und der Rest der Animation
   wuechse unsichtbar ueber den Bildschirmrand hinaus, was das Wachsen wie
   einen abrupten Flash statt einer sichtbaren Kreisbewegung wirken liesse. */
.login-success-flash {
  position: fixed;
  top: 50%;
  left: 50%;
  width: 150vmax;
  height: 150vmax;
  border-radius: 50%;
  background: var(--color-accent);
  transform: translate(-50%, -50%) scale(0);
  opacity: 0;
  pointer-events: none;
  z-index: 1000;
  /* Dauer synchron mit LOGIN_FLASH_EXPAND_MS in auth.js halten. */
  transition: transform 0.55s cubic-bezier(0.4, 0, 0.2, 1);
}

.login-success-flash.is-covering {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

/* Gleiche Spezifitaet wie .is-covering, aber weiter unten in der Kaskade -
   gewinnt bei gleichzeitig gesetzten Klassen und ersetzt die transform-
   Transition durch eine reine opacity-Transition, damit der Kreis beim
   Ausblenden nicht wieder schrumpft, sondern voll gross verblasst. Dauer
   synchron mit LOGIN_FLASH_FADE_MS in auth.js halten. */
.login-success-flash.is-fading {
  transition: opacity 0.42s ease;
  opacity: 0;
}

.auth-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 81;
  width: min(360px, calc(100vw - 2.5rem));
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-hover);
  padding: 1.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.auth-modal-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  border: none;
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
  width: 2rem;
  height: 2rem;
  border-radius: 999px;
  font-size: 0.95rem;
  cursor: pointer;
}

#auth-modal-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--color-ink);
}

#auth-form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

#auth-form input {
  width: 100%;
  padding: 0.65rem 0.85rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-alt);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 0.92rem;
}

#auth-form input:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px var(--color-accent-soft);
}

#auth-submit-btn {
  border: none;
  background: var(--color-accent);
  color: var(--color-accent-ink);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.92rem;
  padding: 0.7rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  box-shadow: 0 8px 18px -8px rgba(236, 48, 19, 0.55);
}

#auth-submit-btn:hover {
  background: var(--color-accent-dark);
}

#auth-submit-btn:disabled {
  opacity: 0.6;
  cursor: default;
}

.auth-error {
  margin: 0;
  font-size: 0.82rem;
  color: var(--color-closed);
  background: var(--color-closed-bg);
  border-radius: var(--radius-sm);
  padding: 0.55rem 0.75rem;
}

.auth-error.auth-error-success {
  color: var(--color-open);
  background: var(--color-open-bg);
}

.auth-toggle-link {
  align-self: center;
  border: none;
  background: none;
  color: var(--color-accent-dark);
  font-family: var(--font-body);
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
  text-decoration: underline;
}

.auth-field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.field-status {
  margin: 0;
  font-size: 0.78rem;
  color: var(--color-text-muted);
}

.field-status.field-status-ok {
  color: var(--color-open);
}

.field-status.field-status-error {
  color: var(--color-closed);
}

.location-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  border: 1px solid var(--color-border);
  background: transparent;
  color: var(--color-text);
  border-radius: var(--radius-sm);
  padding: 0.55rem;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 0.82rem;
  font-weight: 700;
  transition: background 0.12s ease, color 0.12s ease;
}

.pin-icon {
  width: 1em;
  height: 1em;
  flex-shrink: 0;
}

.location-btn-x {
  width: 0.95rem;
  height: 0.95rem;
  flex-shrink: 0;
  display: none;
}

.location-btn.active .location-btn-x {
  display: block;
}

.location-btn:hover {
  background: var(--color-accent-soft);
  color: var(--color-accent-dark);
}

.location-btn:disabled {
  opacity: 0.6;
  cursor: default;
}

.location-btn.active {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-accent-ink);
  box-shadow: 0 6px 16px -6px rgba(236, 48, 19, 0.55);
}

.location-btn.active:hover {
  background: var(--color-accent-dark);
  color: var(--color-accent-ink);
}

.profile-page-main {
  max-width: 640px;
  margin: 0 auto;
  padding: 0.5rem 1.25rem 3rem;
}

.profile-back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--color-accent-dark);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.85rem;
  text-decoration: none;
  margin-bottom: 1rem;
}

.profile-back-link:hover {
  text-decoration: underline;
}

.profile-page-card,
.profile-logged-out-hint {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 1.75rem;
}

.profile-page-card {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.profile-page-card h2 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--color-ink);
}

.profile-section-hint {
  margin: -0.5rem 0 0;
  font-size: 0.82rem;
  color: var(--color-text-muted);
}

.profile-subsection {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--color-border);
}

.profile-subsection:first-of-type {
  padding-top: 0;
  border-top: none;
}

.profile-subsection-title {
  margin: 0;
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-muted);
}

.profile-subsection .profile-section-hint {
  margin-top: -0.4rem;
}

.profile-logged-out-hint {
  text-align: center;
  color: var(--color-text-muted);
}

.profile-sections {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.profile-info-row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.88rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--color-border);
}

.profile-info-label {
  color: var(--color-text-muted);
  font-weight: 600;
}

.toggle-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-size: 0.85rem;
  font-weight: 500 !important;
  text-transform: none !important;
  letter-spacing: normal !important;
  color: var(--color-text) !important;
  cursor: pointer;
  margin-top: 0.35rem;
}

.toggle-count {
  color: var(--color-text-muted) !important;
  font-weight: 600 !important;
  /* .toggle-row hat einen einheitlichen gap von 0.75rem fuer alle Elemente -
     hier gezielt verringert, damit die Anzahl naeher am vorangehenden Text
     steht statt wie die anderen (bewusst groesseren) Abstaende zu wirken. */
  margin-left: -0.45rem;
}

/* Bei "Kritik vorhanden" steht die Anzahl zusammen mit dem Text in einem
   gemeinsamen .toggle-label-text-Element (statt als eigenes Flex-Geschwister
   wie oben) - dadurch bleiben Text und Zahl auch bei Zeilenumbruch im
   schmalen Sidebar zusammen. Hier gilt der Flex-gap-Ausgleich von oben also
   nicht - stattdessen reicht ein kleiner, normaler Abstand. */
.toggle-label-text .toggle-count {
  margin-left: 0.15rem;
}

.toggle-row .kritik-logo-badge {
  /* Aus demselben Grund wie bei .toggle-count - naeher an "Kritik vorhanden"
     heranruecken, ohne den .kritik-logo-badge-Abstand auf den Karten
     (dortiges .kritik-badges hat einen eigenen, kleineren gap) zu beeinflussen. */
  margin-right: -0.4rem;
}

.toggle-switch {
  position: relative;
  display: inline-block;
  width: 2.4rem;
  height: 1.4rem;
  flex-shrink: 0;
}

.toggle-switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.toggle-slider {
  position: absolute;
  inset: 0;
  background: var(--color-border);
  border-radius: 999px;
  transition: background 0.15s ease;
}

.toggle-slider::before {
  content: "";
  position: absolute;
  width: 1.1rem;
  height: 1.1rem;
  left: 0.15rem;
  top: 0.15rem;
  background: var(--color-surface);
  border-radius: 50%;
  transition: transform 0.15s ease;
  box-shadow: var(--shadow-sm);
}

.toggle-switch input:checked + .toggle-slider {
  background: var(--color-accent);
}

.toggle-switch input:checked + .toggle-slider::before {
  transform: translateX(1rem);
}

#profile-setup-form,
#profile-search-input {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

#profile-setup-username,
#profile-search-input {
  width: 100%;
  padding: 0.65rem 0.85rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-alt);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 0.92rem;
}

.profile-info-row-editable {
  align-items: center;
}

/* ID-Selektor statt Klasse: der generische input[type="text"]-Selektor
   weiter unten in dieser Datei hat dieselbe Spezifitaet und würde per
   Reihenfolge sonst das hier gewuenschte weisse Hintergrund ueberschreiben
   (siehe #profile-search-input/#profile-setup-username oben - gleicher
   Grund fuer den ID- statt Klassen-Selektor). */
#profile-realname-input {
  flex: 1;
  min-width: 0;
  max-width: 220px;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 0.88rem;
  text-align: right;
}

#profile-setup-form button[type="submit"] {
  border: none;
  background: var(--color-accent);
  color: var(--color-accent-ink);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.92rem;
  padding: 0.7rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.profile-user-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.profile-user-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.6rem 0.85rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-alt);
}

.profile-user-info {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.profile-user-name {
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.profile-user-realname {
  font-size: 0.76rem;
  font-weight: 400;
  color: var(--color-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Klarname in Klammern direkt hinter dem Username in den Suchergebnissen
   (siehe renderUserRow()s inlineRealname) - heller als --color-text-muted,
   damit er sich deutlich vom Username selbst absetzt. */
.profile-user-realname-inline {
  font-weight: 400;
  color: var(--color-text-muted);
  opacity: 0.7;
}

/* Rechte Seite: "Folgt dir"-Badge direkt links neben dem Folgen/Entfolgen-
   Button, nicht darueber. */
.profile-user-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

/* Zeigt an, dass dieser User MIR folgt - unabhaengig vom Folgen-Button
   darunter, der ausschliesslich MEINE eigene Folgen-Beziehung steuert (siehe
   renderUserRow() in profile-page.js). */
.profile-user-follows-you {
  flex-shrink: 0;
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-accent-dark);
  background: var(--color-accent-soft);
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
}

.profile-follow-btn {
  border: none;
  background: var(--color-accent);
  color: var(--color-accent-ink);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.78rem;
  padding: 0.4rem 0.85rem;
  border-radius: 999px;
  cursor: pointer;
  flex-shrink: 0;
}

.profile-follow-btn.active {
  background: var(--color-surface);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
}

.profile-empty-hint {
  margin: 0;
  font-size: 0.85rem;
  color: var(--color-text-muted);
  font-style: italic;
}

.header-home-link {
  color: inherit;
  text-decoration: none;
}

.site-header h1 {
  margin: 0 0 0.5rem;
  line-height: 0;
  transition: margin 0.25s ease;
}

.page-header.is-compact .site-header h1 {
  margin-bottom: 0;
}

/* Reset auf reine Bild-Optik - der <button> existiert nur, damit ein Klick
   aufs (im collapsed Header verkleinerte) Logo per JS nach oben scrollen
   kann, ohne visuell wie ein Button auszusehen. */
.site-logo-btn {
  display: inline-block;
  border: none;
  background: none;
  padding: 0;
  line-height: 0;
  cursor: pointer;
}

.site-logo {
  height: clamp(3.7rem, 6.5vw, 4.8rem);
  width: auto;
  vertical-align: middle;
  transition: height 0.25s ease;
}

.page-header.is-compact .site-logo {
  height: 1.7rem;
}

.subtitle {
  margin: 0.4rem 0 0;
  color: var(--color-text-muted);
  font-size: 1.05rem;
  font-weight: 400;
  max-height: 2rem;
  opacity: 1;
  overflow: hidden;
  transition: max-height 0.25s ease, opacity 0.18s ease, margin 0.25s ease;
}

.page-header.is-compact .subtitle {
  max-height: 0;
  opacity: 0;
  margin-top: 0;
  pointer-events: none;
}

.layout {
  display: grid;
  grid-template-columns: 300px 1fr;
  gap: 1.75rem;
  max-width: 1240px;
  margin: 0 auto;
  padding: 0.5rem 1.25rem 3rem;
  align-items: start;
}

@media (max-width: 860px) {
  .layout {
    grid-template-columns: 1fr;
  }

  .community-card {
    flex-basis: 112px;
  }
}

.filters {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 1.35rem;
  position: sticky;
  top: calc(var(--page-header-height, 0px) + 1.25rem);
  display: flex;
  flex-direction: column;
  gap: 1.35rem;
  max-height: calc(100vh - var(--page-header-height, 0px) - 2.5rem);
  overflow-y: auto;
}

.filters-mobile-header {
  display: none;
}

.filters-apply-btn {
  display: none;
}

.mobile-filter-fab {
  display: none;
}

.filters-backdrop {
  display: none;
}

.filters-footer {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

@media (max-width: 860px) {
  .filters {
    position: fixed;
    inset: auto 0 0 0;
    top: auto;
    max-height: 82vh;
    padding-top: 0;
    padding-bottom: 0;
    border-radius: 20px 20px 0 0;
    box-shadow: 0 -12px 32px rgba(44, 36, 32, 0.25);
    transform: translateY(105%);
    transition: transform 0.28s ease;
    /* Hoeher als .map-view.is-fullscreen (z-index: 90) - das Filter-Sheet
       soll auch im Kartenvollbild ueber der Karte erreichbar bleiben. */
    z-index: 110;
  }

  .filters.open {
    transform: translateY(0);
  }

  .filters-mobile-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: sticky;
    top: 0;
    background: var(--color-surface);
    margin: 0 -1.35rem;
    padding: 1rem 1.35rem;
    border-bottom: 1px solid var(--color-border);
    border-radius: 20px 20px 0 0;
  }

  .filters-mobile-title {
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--color-ink);
  }

  .filters-close-btn {
    border: none;
    background: var(--color-surface-alt);
    color: var(--color-text);
    width: 2rem;
    height: 2rem;
    border-radius: 999px;
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
  }

  .filters-apply-btn {
    display: block;
    background: var(--color-accent);
    color: var(--color-accent-ink);
    border: none;
    border-radius: var(--radius-sm);
    padding: 0.75rem;
    font-family: var(--font-body);
    font-weight: 700;
    font-size: 0.9rem;
    cursor: pointer;
    box-shadow: 0 8px 18px -8px rgba(236, 48, 19, 0.55);
  }

  .detail-filter-section {
    margin-bottom: 1.1rem;
  }

  .filters-footer {
    flex-direction: row;
    position: sticky;
    bottom: 0;
    z-index: 2;
    margin: 0 -1.35rem;
    padding: 1rem 1.35rem;
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    box-shadow: 0 -8px 20px -12px rgba(44, 36, 32, 0.35);
  }

  .filters-footer #reset-filters,
  .filters-footer .filters-apply-btn {
    flex: 1;
  }

  .filters-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(28, 22, 18, 0.45);
    /* Hoeher als .map-view.is-fullscreen (z-index: 90) - siehe .filters oben. */
    z-index: 105;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease;
  }

  .filters-backdrop.open {
    opacity: 1;
    pointer-events: auto;
  }

  .mobile-filter-fab {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    position: fixed;
    right: 1.1rem;
    bottom: calc(var(--bottom-nav-height) + 1.25rem);
    /* Hoeher als .map-view.is-fullscreen (z-index: 90) - der FAB soll auch
       im Kartenvollbild erreichbar bleiben, um weiter filtern zu koennen. */
    z-index: 95;
    background: var(--color-ink);
    color: #fffaf5;
    border: none;
    border-radius: 999px;
    padding: 0.8rem 1.3rem;
    font-family: var(--font-body);
    font-weight: 700;
    font-size: 0.9rem;
    letter-spacing: 0.01em;
    box-shadow: 0 10px 26px -8px rgba(28, 22, 18, 0.55);
    cursor: pointer;
  }

  .mobile-filter-fab-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    min-width: 1.3rem;
    height: 1.3rem;
    padding: 0 0.35rem;
    border-radius: 999px;
    background: var(--color-accent);
    color: var(--color-accent-ink);
    font-size: 0.72rem;
    font-weight: 800;
    position: relative;
    cursor: pointer;
  }

  /* Vergroessert die Tap-Flaeche des Badges unsichtbar, ohne die visuelle
     Groesse zu veraendern - links weniger Puffer, damit der Klick nicht mit
     dem "Filter"-Label des umgebenden FAB-Buttons kollidiert. */
  .mobile-filter-fab-count::before {
    content: "";
    position: absolute;
    inset: -0.5rem -0.5rem -0.5rem -0.15rem;
  }

  .mobile-filter-fab-count-x {
    width: 0.95rem;
    height: 0.95rem;
    flex-shrink: 0;
  }

  .mobile-filter-fab-count:active {
    transform: scale(0.88);
  }
}

.filter-group {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.filter-group-label {
  font-weight: 700;
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--color-text-muted);
}

.detail-filter-section {
  border-top: 1px solid var(--color-border);
  padding-top: 1.1rem;
}

.detail-filter-section > summary {
  cursor: pointer;
  list-style: revert;
}

.detail-filter-section > summary:hover {
  color: var(--color-accent-dark);
}

.detail-filter-content {
  display: flex;
  flex-direction: column;
  gap: 1.35rem;
  margin-top: 1rem;
}

.filter-group > label {
  font-size: 0.82rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--color-text-muted);
}

.favorites-login-hint {
  margin: 0;
  font-size: 0.8rem;
  font-style: italic;
  color: var(--color-text-muted);
}

.district-subgroup {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.district-subgroup-label {
  align-self: flex-start;
  font-family: var(--font-body);
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-text-muted);
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: 999px;
  padding: 0.28rem 0.7rem;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease, box-shadow 0.12s ease;
}

.district-subgroup-label:hover {
  background: var(--color-accent-soft);
  color: var(--color-accent-dark);
  box-shadow: var(--shadow-sm);
}

input[type="search"],
input[type="text"] {
  width: 100%;
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-alt);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 0.92rem;
}

input[type="search"]:focus,
input[type="text"]:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px var(--color-accent-soft);
}

.checkbox-row {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-weight: 500 !important;
  text-transform: none !important;
  letter-spacing: normal !important;
  color: var(--color-text) !important;
  cursor: pointer;
}

.chip-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.filter-group-heading {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.location-loading-indicator {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--color-text-muted);
}

.location-spinner {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
  border: 2px solid var(--color-border);
  border-top-color: var(--color-accent);
  border-radius: 50%;
  animation: location-spinner-spin 0.7s linear infinite;
}

@keyframes location-spinner-spin {
  to {
    transform: rotate(360deg);
  }
}

/* Fixe Bottom-Navigation (Suche/Community) statt Tab-Switcher oben - Icon +
   Label wie bei nativen Apps, immer per Daumen erreichbar unabhaengig vom
   Scroll-Stand. Hoehe liegt in --bottom-nav-height (siehe :root), damit
   Seiteninhalt und andere fixe Mobile-Elemente (FAB, Kartenansicht) konsistent
   Platz dafuer lassen. */
.bottom-nav {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--bottom-nav-height);
  display: flex;
  justify-content: center;
  /* Milchglas-Effekt statt deckendem Weiss: halbtransparenter Hintergrund +
     backdrop-filter laesst darunterliegenden Content (Karten/Karte beim
     Scrollen) leicht durchscheinen. -webkit-Praefix fuer Safari/iOS. */
  background: rgba(255, 255, 255, 0.72);
  backdrop-filter: blur(16px) saturate(160%);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  border-top: 1px solid var(--color-border);
  box-shadow: 0 -8px 24px -18px rgba(44, 36, 32, 0.35);
  /* Hoeher als .map-view.is-fullscreen (z-index: 90) - der Umschalter soll
     auch im Kartenvollbild erreichbar bleiben, wie schon der FAB (95). */
  z-index: 96;
}

.bottom-nav-btn {
  flex: 1;
  max-width: 200px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.2rem;
  border: none;
  background: transparent;
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 700;
  cursor: pointer;
  transition: color 0.15s ease;
}

.bottom-nav-btn:not(.active) {
  color: var(--color-text-muted);
}

.bottom-nav-btn.active {
  color: var(--color-accent);
}

.bottom-nav-icon {
  width: 1.5rem;
  height: 1.5rem;
}

.quick-filters {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  max-width: 1240px;
  margin: 0 auto 1.5rem;
  padding: 0 1.25rem;
}

.chip {
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  border-radius: 999px;
  padding: 0.32rem 0.85rem;
  font-family: var(--font-body);
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
  user-select: none;
  transition: background 0.12s ease, box-shadow 0.12s ease, color 0.12s ease;
}

.chip:hover {
  box-shadow: var(--shadow-sm);
}

.chip.active {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-accent-ink);
  box-shadow: 0 6px 16px -6px rgba(236, 48, 19, 0.55);
}

.chip:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  color: var(--color-text-muted);
}

.chip:disabled:hover {
  box-shadow: none;
}

.quick-filter-dropdown {
  position: relative;
}

.quick-filter-open-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-muted);
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease, box-shadow 0.12s ease;
}

.quick-filter-open-btn:hover {
  background: var(--color-accent-soft);
  color: var(--color-accent-dark);
  box-shadow: var(--shadow-sm);
}

.filter-icon {
  width: 1.05em;
  height: 1.05em;
  flex-shrink: 0;
}

.friends-filter-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  /* Als inline-flex-Container mit Text+Icon-Kindern wird die Hoehe sonst
     anhand der Flex-Cross-Size berechnet statt anhand der normalen
     Text-Line-Box wie bei den anderen (nicht-flex) .chip-Buttons - das
     macht den Button ein paar Pixel niedriger als "Alle"/"Restaurants".
     Feste Hoehe erzwingt exakt dieselbe Groesse. */
  height: 2.1rem;
}

.quick-filter-caret {
  width: 0.8rem;
  height: 0.8rem;
}

.quick-filter-icon {
  width: 0.85rem;
  height: 0.85rem;
  flex-shrink: 0;
}

.quick-filter-icon-star {
  font-size: 0.85rem;
  line-height: 1;
  color: var(--color-accent);
}

.quick-filter-btn.active .quick-filter-icon-star {
  color: currentColor;
}

.quick-filter-dropdown-panel {
  position: absolute;
  top: calc(100% + 0.4rem);
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  min-width: 180px;
  max-width: 260px;
  max-height: 260px;
  overflow-y: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-hover);
  padding: 0.4rem;
  text-align: left;
}

.quick-filter-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  width: 100%;
  border: none;
  background: none;
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 0.84rem;
  font-weight: 700;
  text-align: left;
  padding: 0.45rem 0.6rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.quick-filter-option:hover {
  background: var(--color-surface-alt);
}

.quick-filter-option.selected {
  color: var(--color-accent-dark);
}

.quick-filter-option-check {
  flex-shrink: 0;
  width: 0.9rem;
  height: 0.9rem;
  visibility: hidden;
}

.quick-filter-option.selected .quick-filter-option-check {
  visibility: visible;
}

.quick-filter-empty-hint {
  padding: 0.45rem 0.6rem;
  font-size: 0.8rem;
  color: var(--color-text-muted);
}

.quick-filter-divider {
  height: 1px;
  margin: 0.35rem 0.2rem;
  background: var(--color-border);
}

.quick-filter-section-heading {
  margin: 0.2rem 0.6rem 0.3rem;
  font-size: 0.58rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-muted);
}

.option-list {
  max-height: 180px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-alt);
  padding: 0.5rem;
}

.option-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.86rem;
  padding: 0.15rem 0.3rem;
  border-radius: 6px;
}

.option-row:hover {
  background: rgba(236, 48, 19, 0.07);
}

.option-row .count {
  color: var(--color-text-muted);
  font-size: 0.78rem;
  margin-left: auto;
  font-weight: 600;
}

#reset-filters {
  border: 1px solid var(--color-border);
  background: transparent;
  color: var(--color-text-muted);
  border-radius: var(--radius-sm);
  padding: 0.6rem;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 0.82rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  transition: background 0.12s ease, color 0.12s ease;
}

#reset-filters:hover {
  background: var(--color-accent-soft);
  color: var(--color-accent-dark);
}

.results-header {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 1.25rem 1rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  color: var(--color-text-muted);
  font-size: 0.85rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

#result-count {
  font-size: 0.7rem;
  color: var(--color-ink);
}

.result-count-number {
  color: var(--color-accent);
}

.results-header-actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.view-toggle {
  display: flex;
  gap: 0.35rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 999px;
  padding: 0.25rem;
}

.view-toggle-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  border: none;
  background: transparent;
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: none;
  letter-spacing: normal;
  padding: 0.4rem 0.85rem;
  border-radius: 999px;
  cursor: pointer;
}

.view-toggle-btn.active {
  background: var(--color-accent);
  color: var(--color-accent-ink);
}

.view-icon {
  width: 1.05em;
  height: 1.05em;
  flex-shrink: 0;
}

.location-shortcut-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-ink);
  border-radius: 999px;
  cursor: pointer;
  font-size: 1.1rem;
  transition: background 0.12s ease, color 0.12s ease, box-shadow 0.12s ease;
}

.location-shortcut-btn:hover {
  background: var(--color-accent-soft);
  color: var(--color-accent-dark);
  box-shadow: var(--shadow-sm);
}

.location-shortcut-btn.active {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-accent-ink);
  box-shadow: 0 6px 16px -6px rgba(236, 48, 19, 0.55);
}

.location-shortcut-btn.active:hover {
  background: var(--color-accent-dark);
  color: var(--color-accent-ink);
}

.map-view {
  height: 70vh;
  min-height: 420px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
  /* Leaflet nutzt intern z-index-Werte bis 1000 (Panes/Controls). Ohne
     eigenen Stacking-Context wuerden die ueber die fixen Mobile-Elemente
     (FAB, Filter-Sheet, Backdrop) hinausragen. */
  position: relative;
  z-index: 1;
  /* Ohne diesen Puffer kann die Gesamtseite in der Kartenansicht kaum laenger
     als das Sichtfenster sein. Der Header schrumpft dann beim Scrollen zwar
     ganz normal (siehe .page-header.is-compact), verkleinert dabei aber
     kurzzeitig die Dokumenthoehe so stark, dass der Browser scrollY sofort
     wieder auf 0 zurueckdraengt - der Header klappt daraufhin wieder auf und
     man landet augenblicklich zurueck am Seitenanfang. Der Puffer muss dabei
     bewusst klein bleiben (gemessen: Header-Kollaps ca. 130px, natuerlicher
     Ueberschuss ca. 117px, es fehlen also nur ~13px) - ein zu grosser Puffer
     wuerde nach dem Einklappen unnoetig viel Scroll-Spielraum uebrig lassen
     und die Karte dabei weiter unter den fixierten Header schieben.
     margin-bottom (statt z.B. mehr Karten-Hoehe) haelt dabei die sichtbare
     Kartengroesse unveraendert. */
  margin-bottom: 3rem;
}

/* CSS-basiertes Fullscreen statt der nativen Fullscreen-API (siehe
   setMapFullscreen() in app.js) - deckt den gesamten Viewport ab, inkl.
   Header/Sidebar/FAB. 90 liegt bewusst unter dem Auth-Modal (81/80... siehe
   .auth-modal), aber ueber allem sonstigen Fixed-Content der Seite. */
.map-view.is-fullscreen {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  max-height: none;
  min-height: 0;
  margin: 0;
  border: none;
  border-radius: 0;
  z-index: 90;
}

/* Auf Mobile bleibt die feste 70vh-Hoehe (siehe .map-view oben) unabhaengig
   von der tatsaechlichen Headergroesse - je nach Zustand (aus-/eingeklappt)
   ragt die Karte dadurch ueber den sichtbaren Bereich hinaus oder laesst
   unnoetig viel Platz frei. position: fixed relativ zum Viewport (statt
   Groesse per vh/dvh-Formel im normalen Dokumentenfluss) loest das
   zuverlaessig:

   #page-header ist das allererste Element im Body, daher "klebt" es sofort
   ab dem ersten Pixel Scroll-Offset an top:0, waehrend normal fliessender
   Inhalt (wie es die Karte vorher war) ganz regulaer um den vollen
   Scroll-Betrag nach oben wandert - dieser Inhalt rutscht dadurch bei jedem
   Scroll-Pixel unter den (undurchsichtigen) Header, sichtbar als
   abgeschnittener oberer Kartenrand. Ein position:sticky-Versuch fuer die
   Karte selbst schlug am selben Problem eine Ebene tiefer fehl: sticky
   braucht in seinem Elternelement "Slack" (Restplatz oberhalb der eigenen
   natuerlichen Position), um ueberhaupt an der gewuenschten Stelle andocken
   zu koennen - .results/.layout ist hier aber nie hoeher als die Karte
   selbst, es gibt also keinen Slack.
   position: fixed umgeht das komplett, weil es unabhaengig vom Scroll-Stand
   und vom Elternelement direkt gegen den Viewport positioniert - top/bottom
   statt einer Hoehen-Formel uebernehmen dabei automatisch auch die
   dynamische Groesse bei ein-/ausblendenden mobilen Browser-Toolbars, ganz
   ohne "dvh". --page-header-height wird per ResizeObserver in app.js aktuell
   gehalten, samt passendem leafletMap.invalidateSize()-Aufruf dort. */
@media (max-width: 860px) {
  .map-view {
    position: fixed;
    top: calc(var(--page-header-height, 0px) + 0.5rem);
    bottom: calc(var(--bottom-nav-height) + 1.25rem);
    left: 1.25rem;
    right: 1.25rem;
    margin-bottom: 0;
    /* Beide muessen hier explizit zurueckgesetzt werden - sonst bleiben die
       Basisregel-Werte (height: 70vh, min-height: 420px) aktiv: eine
       spaetere Regel fuer denselben Selektor ueberschreibt nur die
       Deklarationen, die sie selbst nennt, nicht automatisch alle anderen.
       Mit height:auto bestimmen stattdessen top+bottom die Groesse. */
    height: auto;
    min-height: 0;
  }
}

.map-fullscreen-btn {
  width: 2.2rem;
  height: 2.2rem;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-surface);
  border: none;
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
  color: var(--color-text);
  cursor: pointer;
}

.map-fullscreen-btn svg {
  width: 1.1rem;
  height: 1.1rem;
}

.map-fullscreen-btn:hover {
  background: var(--color-accent-soft);
  color: var(--color-accent-dark);
}

/* Map-Popup zeigt dieselbe Karte wie die Listenansicht (siehe .card weiter
   unten), nur kompakter skaliert und ohne die dort ueblichen
   Card-Rahmen/Hover-Effekte, da der Leaflet-Popup-Rahmen das schon uebernimmt. */
/* .map-view .card.map-popup-card (statt nur .map-popup-card) fuer hoehere
   Spezifitaet - sonst gewinnen die spaeter im File stehenden .card- bzw.
   .card:nth-child(...)-Basisregeln bei Gleichstand die Kaskade und
   Padding/Rahmen/Radius/Verlaufshintergrund kommen zurueck. */
.map-view .card.map-popup-card {
  font-family: var(--font-body);
  min-width: 200px;
  max-width: 260px;
  padding: 0;
  border: none;
  border-radius: 0;
  box-shadow: none;
  background: var(--color-surface);
  gap: 0.4rem;
}

.map-view .card.map-popup-card:hover {
  transform: none;
  box-shadow: none;
}

/* Leaflet setzt fuer alle <a> im Popup-Inhalt per Default eine eigene
   Link-Farbe (.leaflet-popup-content a) - hier explizit auf die
   Karten-Farben zurueckstellen, da unsere Klassen sonst farblich leer bleiben. */
.map-popup-card .card-title {
  font-size: 1rem;
  color: var(--color-ink);
}

/* Der "Website"-Link nutzt (wie "Google Maps") .maps-link statt .website-link
   - siehe buildCardBodyHtml in app.js, .website-link bleibt reserviert fuer
   den "Kommentieren"-Button im Kommentar-Formular, der nie in einer
   Leaflet-Popup-Karte auftaucht. */
.map-popup-card .maps-link {
  color: var(--color-text);
}

.map-popup-card .gm-badge {
  color: var(--color-text-muted);
}

.map-popup-card .kritik-logo-falter {
  color: #1a1a1a;
}

.map-popup-card .kritik-logo-standard {
  color: #ffffff;
}

.map-popup-card .card-address {
  font-size: 0.76rem;
}

.map-popup-card .card-hours {
  font-size: 0.7rem;
}

.map-popup-card .status-badge {
  height: 1.3rem;
  font-size: 0.6rem;
  padding: 0 0.5rem;
}

.map-popup-card .favorite-btn,
.map-popup-card .friend-favorite-btn,
.map-popup-card .wanna-try-btn {
  width: 1.35rem;
  height: 1.35rem;
}

.map-popup-card .michelin-badge,
.map-popup-card .gm-badge {
  font-size: 0.68rem;
  padding: 0.15rem 0.55rem;
}

.map-popup-card .kritik-logo-falter,
.map-popup-card .kritik-logo-standard {
  font-size: 0.66rem;
}

.map-popup-card .tag-pill {
  font-size: 0.64rem;
  padding: 0.12rem 0.5rem;
}

.map-popup-card .card-actions {
  margin-top: 0.35rem;
}

/* Vertikales Padding bewusst NICHT symmetrisch (0.48rem/0.32rem statt
   0.4rem/0.4rem, Summe bleibt bei 0.8rem - die Hoehen-calc()s unten bleiben
   also gueltig): bei line-height 1.45 sitzt der sichtbare Text innerhalb
   seiner eigenen Zeilenbox nicht exakt mittig (per Messung empirisch
   bestaetigt, unabhaengig vom Textinhalt - keine Unterlaengen-Frage), mit
   gleich grossem Padding oben/unten wirkt der Text dadurch zu hoch. Mehr
   Platz oben / weniger unten gleicht das optisch aus. */
.map-popup-card .maps-link {
  font-size: 0.72rem;
  padding: 0.48rem 0.85rem 0.32rem;
}

/* .card-comments-shortcut-btn ist normalerweise ueber .card-actions auf die
   Groesse des STANDARD-.maps-link kalibriert (0.76rem/1rem vertikales
   Padding, siehe die calc()-Formel dort) - im Map-Popup ist .maps-link aber
   kleiner (siehe Regel oben), ohne dieses Gegenstueck waere der runde Button
   dadurch sichtbar hoeher als die Website/Google-Maps-Pillen daneben, und
   .card-actions (display:flex, align-items:stretch) wuerde die Pillen dann
   wiederum auf diese ueberschuessige Hoehe hochziehen - dadurch stand ihr
   Text sichtbar nicht mehr vertikal zentriert. Selektor bewusst mit
   .card-actions statt nur .map-popup-card: gleiche Spezifitaet wie die
   Basis-Regel .card-actions .card-comments-shortcut-btn weiter unten in
   dieser Datei haette (bei gleicher Spezifitaet gewinnt die spaetere Regel
   per Reihenfolge) sonst dafuer gesorgt, dass dieser Override nie greift.
   Muss in Sync bleiben, falls sich .map-popup-card .maps-link oben nochmal
   aendert. */
.map-popup-card .card-actions .card-comments-shortcut-btn {
  height: calc(0.72rem * 1.45 + 0.8rem + 2px);
  min-width: calc(0.72rem * 1.45 + 0.8rem + 2px);
}

/* Hoehere Spezifitaet als .card-actions .comment-shortcut-icon (steht weiter
   unten in dieser Datei und haette bei gleicher Spezifitaet sonst per
   Reihenfolge gewonnen). */
.map-popup-card .card-actions .comment-shortcut-icon {
  width: 0.78rem;
  height: 0.78rem;
}

/* Kuehle, leicht entsaettigte Einfaerbung der Kartenkacheln, damit die Karte
   zum neuen Weiss/Hellgrau/Rot-Design passt statt wie eine generische
   Navi-Ansicht zu wirken - kein sepia()/negatives hue-rotate() mehr, das
   waermte bewusst Richtung der alten Pfirsich-Palette ein. */
.map-view .leaflet-tile-pane {
  filter: saturate(80%) brightness(1.03) contrast(1.02);
}

.map-view .leaflet-control-attribution {
  background: rgba(255, 252, 248, 0.85);
  color: var(--color-text-muted);
  font-family: var(--font-body);
  font-size: 0.68rem;
}

.map-view .leaflet-control-attribution a {
  color: var(--color-text-muted);
}

.map-view .leaflet-control-zoom {
  border: 1px solid var(--color-border) !important;
  box-shadow: var(--shadow-sm) !important;
  border-radius: var(--radius-sm) !important;
  overflow: hidden;
}

.map-view .leaflet-control-zoom a {
  background: var(--color-surface) !important;
  color: var(--color-text) !important;
  font-family: var(--font-body);
}

.map-view .leaflet-control-zoom a:hover {
  background: var(--color-surface-alt) !important;
}

.map-view .leaflet-popup-content-wrapper {
  background: var(--color-surface);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
}

.map-view .leaflet-popup-tip {
  background: var(--color-surface);
}

.map-view .leaflet-popup-close-button {
  color: var(--color-text-muted) !important;
}

.map-view .leaflet-tooltip.district-label {
  background: none;
  border: none;
  box-shadow: none;
  color: #b7a99c;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  text-shadow:
    0 0 3px var(--color-bg-1),
    0 0 3px var(--color-bg-1),
    0 0 6px var(--color-bg-1);
  pointer-events: none;
}

.map-view .leaflet-tooltip.district-label::before {
  display: none;
}

.map-marker-label {
  /* visibility/opacity statt display:none: Leaflet berechnet beim ersten
     Positionieren eines Tooltips seinen Zentrierungs-Offset anhand von
     offsetWidth - bei display:none waere das 0, wodurch die Bubble beim
     allerersten Anzeigen sichtbar versetzt zum Pin sitzt (bis zum naechsten
     Zoom/Pan, das die Position neu berechnet). Mit visibility:hidden bleibt
     die tatsaechliche Breite jederzeit korrekt messbar. */
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  background: var(--color-ink);
  color: #fffaf5;
  border: none;
  border-radius: 999px;
  padding: 0.25rem 0.7rem;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.72rem;
  white-space: nowrap;
  box-shadow: var(--shadow-sm);
}

.map-marker-label::before {
  border-top-color: var(--color-ink);
}

.map-view.show-labels .map-marker-label {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
}

.map-marker-pin span {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  background: var(--color-accent);
  border: 2.5px solid #fffaf5;
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  box-shadow: 0 3px 8px rgba(44, 36, 32, 0.35);
}

/* Restaurants (Standardfarbe/-icon) brauchen keine eigene Regel - nur Bars
   und Cafés weichen farblich vom roten Standard-Pin ab (siehe getVenueCategory()
   in app.js). */
.map-marker-pin.venue-pin-bars span {
  background: var(--color-venue-bar);
}

.map-marker-pin.venue-pin-cafes span {
  background: var(--color-venue-cafe);
}

.venue-pin-icon {
  width: 13px;
  height: 13px;
  color: #fffaf5;
  flex-shrink: 0;
  /* Das Icon soll aufrecht stehen, obwohl der umgebende Pin fuer die
     Tropfenform um -45deg gedreht ist - die Gegenrotation hebt das wieder auf.
     margin-top rueckt es optisch in die runde obere Haelfte des Pins statt in
     die geometrische Mitte des gedrehten Quadrats (die durch die Pin-Spitze
     unten leicht nach unten verschoben wirkt). */
  transform: rotate(45deg);
  margin-top: -2px;
}

.marker-cluster-small,
.marker-cluster-medium,
.marker-cluster-large {
  background: rgba(236, 48, 19, 0.18) !important;
}

.marker-cluster-small div,
.marker-cluster-medium div,
.marker-cluster-large div {
  background: var(--color-accent) !important;
  color: #fffaf5 !important;
  font-family: var(--font-body) !important;
  font-weight: 700;
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.25rem;
}

/* Nur die Ergebnisliste selbst signalisiert Klickbarkeit - .card wird auch
   fuer die (nicht anklickbare) grosse Karte im Detail-Popup selbst und fuer
   .map-popup-card wiederverwendet, dort waere ein Pointer-Cursor irrefuehrend. */
.cards .card {
  cursor: pointer;
}

.community-view {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0.5rem 1.25rem 2.5rem;
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
}

/* Heller Akzentbalken statt abgesetzter Flaeche als Trenner zwischen den
   Sections - nur zwischen den Rows (nicht vor der ersten), etwas Abstand
   darunter, damit der Balken nicht an der naechsten Ueberschrift klebt. */
.community-row + .community-row {
  border-top: 3px solid var(--color-accent-soft);
  padding-top: 1.75rem;
}

.community-row-header {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin-bottom: 0.85rem;
}

/* Rundes Icon links neben Titel/Subtitel jeder Community-Section - siehe die
   *_ICON-Konstanten in app.js (STAR_ICON, CLOCK_ICON, LOCATION_PIN_ICON,
   BOOKMARK_ICON, FRIENDS_ICON, COMMENT_SHORTCUT_ICON). Genereller
   svg-Selektor statt einzelner Icon-Klassen: COMMENT_SHORTCUT_ICON traegt
   noch seine eigene .comment-shortcut-icon-Klasse (aus der Wiederverwendung
   fuer den Kommentar-Button), soll hier aber trotzdem dieselbe Groesse
   bekommen wie die eigens fuer diesen Zweck angelegten Icons. */
.community-row-icon {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
}

.community-row-icon svg {
  width: 1.2rem;
  height: 1.2rem;
}

.community-row-header-text {
  flex: 1;
  min-width: 0;
}

/* Leitet wie .card-actions .map-locate-btn (volle Suchkarte) auf die
   Kartenansicht weiter, zeigt hier aber alle Lokale der ganzen Reihe statt
   nur eines einzelnen (siehe showRestaurantsOnMap in app.js). */
.community-row-map-btn {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.3rem;
  height: 2.3rem;
  padding: 0;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-ink);
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.community-row-map-btn:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.community-row-map-btn-icon {
  width: 1.1rem;
  height: 1.1rem;
}

.community-row-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 800;
  line-height: 1.25;
  color: var(--color-ink);
}

.community-row-title-accent {
  color: var(--color-accent);
}

.community-row-subtitle {
  margin: 0;
  font-size: 0.8rem;
  font-weight: 400;
  line-height: 1.2;
  color: var(--color-text-muted);
}

/* Ersetzt die Kartenreihe, wenn eine Voraussetzung fehlt (kein Standort
   aktiv / nicht eingeloggt) - Ueberschrift/Unterueberschrift bleiben sichtbar,
   siehe emptyHint in buildCommunityRowHtml (app.js). */
.community-row-empty-hint {
  margin: 0.9rem 0 0;
  padding: 0.9rem 1rem;
  background: var(--color-bg-2);
  border-radius: var(--radius);
}

.community-row-empty-hint p {
  margin: 0 0 0.7rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.community-row-empty-hint p:last-child {
  margin-bottom: 0;
}

.community-row-empty-hint-btn {
  display: inline-block;
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--color-accent-ink);
  background: var(--color-accent);
  border: none;
  padding: 0.5rem 1.1rem;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.12s ease, transform 0.12s ease;
}

.community-row-empty-hint-btn:hover {
  background: var(--color-accent-dark);
  transform: translateY(-1px);
}

.community-row-scroller {
  display: flex;
  gap: 0.85rem;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  /* Scrollbar optisch ausblenden - der Fortschritt wird bereits ueber die
     eigenen .community-row-progress-Balken darunter angezeigt. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.community-row-scroller::-webkit-scrollbar {
  display: none;
}

/* Kleine Balken statt Punkte, zeigen den horizontalen Scroll-Fortschritt der
   Reihe an - siehe setupCommunityScrollProgress() in app.js. Bleibt leer
   (kein Markup), wenn eine Reihe komplett ohne Scrollen sichtbar ist. */
.community-row-progress {
  display: flex;
  gap: 0.3rem;
  margin-top: 0.65rem;
}

.community-row-progress-bar {
  flex: 1;
  max-width: 2.25rem;
  height: 0.2rem;
  border-radius: 999px;
  background: var(--color-border);
  transition: background 0.15s ease;
}

.community-row-progress-bar.active {
  background: var(--color-accent);
}

/* Kompakte Feed-Karte - bewusst ein eigenes, schlankeres Format statt der
   vollen .card (Adresse/Oeffnungszeiten/Tags/Kritiken/Buttons): in der engen
   horizontalen Reihe wirkte die volle Karte ueberladen und viel zu hoch. */
.community-card {
  /* overflow: hidden ist hier absichtlich wieder da (nicht mehr nur fuer die
     abgerundeten Ecken der Kopfleiste): ohne overflow != visible bleibt die
     automatische Mindestbreite eines Flex-Items der content-basierte
     Minimalwert - ein langer, nicht umbrechender Lokalname haette die Karte
     dann trotz "flex: 0 0 130px" ueber 130px hinaus aufgeblaeht. Mit
     overflow: hidden greift stattdessen die Flexbox-Regel "automatische
     Mindestgroesse = 0", die Karte bleibt zuverlaessig 130px breit und
     .community-card-name schneidet lange Namen mit Ellipsis ab. Die
     Freundes-Aktivitaets-Bubble ist davon nicht mehr betroffen, seit sie als
     eigenes Popover an document.body haengt (siehe .friend-favorite-popover). */
  position: relative;
  z-index: 0;
  flex: 0 0 130px;
  min-width: 0;
  overflow: hidden;
  scroll-snap-align: start;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

/* :hover setzt einen transform, der einen eigenen Stacking-Context erzeugt -
   ohne explizites z-index wuerde die angehobene Karte sonst hinter einer
   spaeteren (im DOM nachfolgenden) Nachbarkarte landen. Die Freundes-Bubble
   selbst ist davon nicht mehr betroffen (siehe .friend-favorite-popover),
   das hier ist nur noch fuer die Hover-Anhebung der Karte selbst relevant. */
.community-card:hover {
  z-index: 2;
  transform: translateY(-3px);
  box-shadow: var(--shadow);
}

.community-card-media {
  /* Nur noch ein schmaler Streifen statt Fotohoehe (4:3) - der freigewordene
     Platz geht an .community-card-info (Name/Bezirk/Status/Oeffnungszeiten)
     darunter. */
  position: relative;
  height: 2.75rem;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  border-radius: var(--radius) var(--radius) 0 0;
}

.community-card-media .favorite-btn,
.community-card-media .wanna-try-btn,
.community-card-media .friend-favorite-btn {
  position: absolute;
  top: 0.35rem;
  border: none;
  background: rgba(255, 255, 255, 0.88);
  box-shadow: 0 1px 4px rgba(44, 36, 32, 0.2);
}

.community-card-media .favorite-btn {
  right: 0.35rem;
}

.community-card-media .wanna-try-btn {
  right: 2.15rem;
}

.community-card-media .friend-favorite-wrap {
  position: absolute;
  top: 0.35rem;
  right: 3.95rem;
}

.community-card-media .friend-favorite-wrap .friend-favorite-btn {
  position: static;
}

.community-card-info {
  padding: 0.55rem 0.65rem 0.7rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}

.community-card-name {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.82rem;
  color: var(--color-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.community-card-district {
  font-size: 0.72rem;
  color: var(--color-text-muted);
}

.community-card .status-badge {
  align-self: flex-start;
  height: 1.1rem;
  font-size: 0.6rem;
  padding: 0 0.4rem;
}

.community-card-bottom-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  margin-top: 0.1rem;
}

/* Ersetzt die frueheren Website-/Maps-/Auf-Karte-anzeigen-Buttons - diese
   Aktionen sind weiterhin ueber das Detail-Popup erreichbar (oeffnet dasselbe
   Popup wie ein Klick auf die Karte selbst, siehe setupRestaurantModal in
   app.js). Nur ein dezenter Pfeil statt Text-Button, da die ganze Karte
   ohnehin klickbar ist - der Pfeil signalisiert nur zusaetzlich "mehr Details". */
.community-card-arrow-btn {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.3rem;
  height: 1.3rem;
  margin: -0.2rem -0.25rem -0.2rem 0;
  border: none;
  background: none;
  color: var(--color-text-muted);
  cursor: pointer;
  transition: color 0.12s ease;
}

.community-card-arrow-btn svg {
  width: 1.05rem;
  height: 1.05rem;
}

.community-card-arrow-btn:hover {
  color: var(--color-ink);
}

.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 1.25rem 1.35rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

/* Kleine, statische Locator-Karte am Ende des Restaurant-Detail-Popups (siehe
   openRestaurantModal in app.js) - negative Raender lassen sie ueber die
   sonstige .card-Polsterung hinaus bis an den Kartenrand reichen ("full
   bleed"), .card { gap: 0.5rem } liefert bereits den Abstand nach oben. */
.restaurant-modal-body .card-mini-map {
  height: 300px;
  cursor: pointer;
  margin: 0 -1.35rem -1.25rem;
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  overflow: hidden;
  background: var(--color-bg-2);
}

/* Heller Trenner zwischen den Aktions-Buttons (Website/Google Maps/Auf-Karte-
   anzeigen/Kommentare) und dem darunterliegenden Karte/Kommentare-Umschalter.
   Eigenes, schmaleres (statt randlos ueber die volle Kartenbreite reichendes)
   Element statt border-top direkt auf .card-modal-tabs, da ein Rand oben auf
   der abgerundeten Pille selbst seltsam ausgesehen haette. align-self:
   center zentriert die schmalere Linie horizontal (wie .card-modal-tabs
   selbst); KEIN eigener margin-top/-bottom - der Abstand zu den Nachbarn
   kommt bewusst nur vom gemeinsamen .card { gap: 0.5rem }, damit der Trenner
   oben/unten exakt gleich viel Luft hat statt schief zu wirken. */
.card-modal-divider {
  align-self: center;
  width: 95%;
  border-top: 2px solid var(--color-border);
}

/* Karte/Kommentare-Umschalter im Restaurant-Detail-Popup - reine
   .view-toggle-Wiederverwendung (siehe .view-toggle-btn), horizontal
   zentriert statt am linken Rand. */
.card-modal-tabs {
  align-self: center;
}

/* Kommentar-Panel im Restaurant-Detail-Popup (siehe openRestaurantModal in
   app.js) - anders als .card-mini-map bewusst OHNE negative Raender: Text
   und Formular sollen die normale .card-Polsterung behalten statt randlos
   ("full bleed") zu wirken. */
.card-comments-panel {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

/* Eigener Abstand-Kontext statt der Original-Margin aus dem Community-Feed
   (dort steht .community-row-empty-hint direkt unter einer Ueberschrift ohne
   Flex-Gap-Elternteil) - hier liefert .card { gap: 0.5rem } bereits Abstand. */
.card-comments-panel .community-row-empty-hint {
  margin-top: 0;
}

.card-comments-list {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.card-comments-empty {
  margin: 0;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.card-comment {
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 0.6rem 0.75rem;
}

.card-comment-meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem;
  font-size: 0.78rem;
}

.card-comment-username {
  font-weight: 700;
  color: var(--color-ink);
}

.card-comment-mine-tag {
  font-weight: 400;
  color: var(--color-text-muted);
}

.card-comment-date {
  color: var(--color-text-muted);
  flex-shrink: 0;
}

.card-comment-body {
  margin: 0.35rem 0 0;
  font-size: 0.88rem;
  color: var(--color-text);
  white-space: pre-wrap;
  word-break: break-word;
}

.card-comment-reactions {
  display: flex;
  gap: 0.35rem;
  margin-top: 0.5rem;
}

/* Vertikale, scrollbare Chat-Liste fuer den "Neueste Kommentare und
   Kritiken"-Feed ganz oben in der Community-Ansicht - anders als die
   uebrigen .community-row-scroller-Reihen (horizontal, ein Lokal pro Karte)
   rollt diese Liste vertikal innerhalb einer festen Maximalhoehe, damit sie
   nicht die ganze Seite in die Laenge zieht. */
.community-comments-feed-list {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  max-height: 420px;
  overflow-y: auto;
  padding-right: 0.15rem;
}

/* Lokalname-Button oberhalb von Username/Datum - fuehrt zum jeweiligen
   Detail-Popup direkt im Kommentare-Tab (siehe openRestaurantModal in
   app.js). Akzentfarbig statt der neutralen Kommentar-Textfarben, damit er
   klar als eigene, klickbare Aktion erkennbar ist. */
.community-comment-restaurant-btn {
  display: block;
  margin-bottom: 0.3rem;
  border: none;
  background: none;
  padding: 0;
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--color-accent);
  text-decoration: underline;
  cursor: pointer;
  text-align: left;
}

/* Rohe Emoji-Zeichen statt SVG - gleiches Muster wie .favorite-btn (★). */
.card-comment-reaction-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  border-radius: 999px;
  padding: 0.2rem 0.55rem;
  font-size: 0.85rem;
  line-height: 1;
  cursor: pointer;
}

.card-comment-reaction-btn.active {
  border-color: var(--color-accent);
  background: var(--color-bg-2);
}

.card-comment-reaction-count {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--color-text-muted);
}

.card-comments-form {
  border-top: 1px solid var(--color-border);
  padding-top: 0.7rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.card-comments-textarea {
  width: 100%;
  min-height: 3.2rem;
  resize: vertical;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 0.5rem 0.65rem;
  font-family: inherit;
  font-size: 0.85rem;
  box-sizing: border-box;
}

/* opacity explizit statt dem Browser-Default ueberlassen (Firefox reduziert
   sonst zusaetzlich zur Farbe auf ~54%, Chrome/Safari nicht) - so ist die
   Helligkeit auf jedem Browser gleich und bewusst gesteuert, statt nur der
   volle --color-text-muted-Ton. */
.card-comments-textarea::placeholder {
  color: var(--color-text-muted);
  opacity: 0.6;
}

.card-comments-form-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.card-comments-counter {
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

.card-comments-form-error {
  margin: 0;
  font-size: 0.78rem;
  color: var(--color-closed);
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-hover);
}

/* Die frueheren pastellfarbenen Verlaeufe pro Karte passten zur warmen
   Pfirsich-Palette - im schlichten Weiss/Hellgrau/Rot-Design wirken sie nur
   noch wie ein Bruch, daher jetzt einheitlich die normale Kartenflaeche. */

.card-header-row {
  position: relative;
  display: flex;
  align-items: start;
  gap: 0.5rem;
}

.card-header-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  /* Platz fuer die absolut positionierte Icon-Spalte reservieren (siehe
     .card-actions-col) - ohne Reservierung wuerde der Titel/die Adresse
     unter den Icons durchlaufen. */
  padding-right: 2.1rem;
}

/* Ausgeloggtes Detail-Popup: .card-actions-col bleibt komplett leer (weder
   Favorit/Bucket-List-Buttons noch Freundes-Aktivitaet), die Platzreservierung
   oben wuerde Titel/Adresse dann unnoetig frueh umbrechen lassen. */
.card-header-text--no-actions-col {
  padding-right: 0;
}

.card-title-row {
  display: flex;
  align-items: start;
  gap: 0.5rem;
}

.card-title {
  flex: 1;
  min-width: 0;
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--color-ink);
  letter-spacing: -0.005em;
}

.card-actions-col {
  /* Absolut statt als Flex-Geschwisterkind: eine einspaltige Liste aus 3
     Icons (Favorit, Bucket List, Freunde) ist hoeher als der Titel/Adress-
     Text daneben - als normales Flex-Kind wuerde sie die ganze Kopfzeile
     aufblasen und einen Abstand vor den Oeffnungszeiten erzeugen. Absolute
     Positionierung entkoppelt die Icon-Hoehe vom Textfluss; .card-header-text
     und .card-hours reservieren per padding-right den noetigen Platz rechts. */
  position: absolute;
  top: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.favorite-btn {
  flex-shrink: 0;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: #d3cabb;
  width: 1.55rem;
  height: 1.55rem;
  padding: 0;
  border-radius: 999px;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}

.favorite-btn:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.favorite-btn.active {
  color: #f0cf5f;
}

.wanna-try-btn {
  flex-shrink: 0;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: #d3cabb;
  width: 1.55rem;
  height: 1.55rem;
  padding: 0;
  border-radius: 999px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}

.wanna-try-icon {
  width: 1rem;
  height: 1rem;
}

.wanna-try-btn:hover {
  border-color: var(--color-plum);
  color: var(--color-plum);
}

.wanna-try-btn.active {
  color: var(--color-plum);
}

.map-locate-btn {
  flex-shrink: 0;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: #d3cabb;
  width: 1.55rem;
  height: 1.55rem;
  padding: 0;
  border-radius: 999px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}

.map-locate-icon {
  width: 1rem;
  height: 1rem;
}

.map-locate-btn:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.friend-favorite-wrap {
  position: relative;
}

.friend-favorite-btn {
  flex-shrink: 0;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-sage);
  width: 1.55rem;
  height: 1.55rem;
  padding: 0;
  border-radius: 999px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}

.friend-favorite-btn:hover {
  border-color: var(--color-sage);
  background: var(--color-sage-soft);
}

.friend-favorite-icon {
  width: 0.95rem;
  height: 0.95rem;
}

/* .friend-favorite-bubble bleibt im Markup jeder Karte, wird aber nie selbst
   sichtbar - sie dient nur als Vorlage, deren innerHTML beim Klick auf den
   Button in das echte Popover (.friend-favorite-popover, siehe unten) kopiert
   wird. Grund: siehe Kommentar bei ensureFriendPopover() in app.js. */
.friend-favorite-bubble {
  display: none;
}

.friend-favorite-popover {
  position: fixed;
  z-index: 500;
  min-width: 120px;
  max-width: 220px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-hover);
  padding: 0.5rem 0.65rem;
  text-align: left;
}

.friend-favorite-popover[hidden] {
  display: none;
}

.friend-favorite-bubble-title {
  display: flex;
  align-items: flex-start;
  gap: 0.3rem;
  margin: 0 0 0.12rem;
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-muted);
}

.friend-favorite-bubble-icon {
  flex-shrink: 0;
  width: 0.8rem;
  height: 0.8rem;
  color: var(--color-plum);
}

.friend-favorite-bubble-icon-star {
  width: auto;
  height: auto;
  font-size: 0.85rem;
  line-height: 1;
  color: #d9a92b;
}

.friend-favorite-bubble-names {
  margin: 0;
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--color-text);
}

/* Trennlinie vor dem zweiten Abschnitt, wenn die Bubble sowohl Favoriten- als
   auch Bucket-List-Freunde zeigt. */
.friend-favorite-bubble-names + .friend-favorite-bubble-title {
  margin-top: 0.4rem;
  padding-top: 0.4rem;
  border-top: 1px solid var(--color-border);
}

.status-badge {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  height: 1.55rem;
  box-sizing: border-box;
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 0 0.65rem;
  border-radius: 999px;
  white-space: nowrap;
}

.status-badge.open {
  color: var(--color-open);
  background: var(--color-open-bg);
}

.status-badge.closed {
  color: var(--color-closed);
  background: var(--color-closed-bg);
}

.status-badge.unclear {
  color: var(--color-unclear);
  background: var(--color-unclear-bg);
}

.card-address {
  font-size: 0.86rem;
  color: var(--color-text-muted);
  font-weight: 400;
}

.card-hours {
  font-size: 0.78rem;
  color: var(--color-text-muted);
  /* Sicherheitsabstand fuer den Fall, dass die absolut positionierte
     Icon-Spalte (siehe .card-actions-col) bei 3 Icons bis in diese Zeile
     hineinreicht. */
  padding-right: 2.1rem;
}

.card-hours--no-actions-col {
  padding-right: 0;
}

.gm-badge {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--color-text-muted);
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: 999px;
  padding: 0.22rem 0.7rem;
  text-decoration: none;
}

.gm-badge:hover {
  box-shadow: var(--shadow-sm);
}

.haube-icons {
  display: inline-flex;
  align-items: center;
  gap: 0.05em;
  vertical-align: middle;
}

.haube-icon {
  height: 1em;
  width: auto;
  display: inline-block;
}

.michelin-icons {
  display: inline-flex;
  align-items: center;
  gap: 0.05em;
  vertical-align: middle;
}

.michelin-icon {
  height: 1em;
  width: auto;
  display: inline-block;
}

.rating-badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
}

.michelin-badge {
  display: inline-flex;
  align-items: center;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--color-text-muted);
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: 999px;
  padding: 0.2rem 0.7rem;
  letter-spacing: 0.02em;
}

.kritik-badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
}

.kritik-logo-badge {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  white-space: nowrap;
  text-decoration: none;
  border-radius: 4px;
  line-height: 1;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}

.kritik-logo-badge:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}

.kritik-logo-falter {
  background: #f7d917;
  color: #1a1a1a;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: -0.01em;
  padding: 0.3rem 0.5rem 0.2rem;
}

.kritik-logo-standard {
  background: #e5027e;
  color: #ffffff;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.74rem;
  padding: 0.3rem 0.55rem 0.24rem;
  border-bottom: 2px solid #ffffff;
}

.seasonal-hint {
  font-style: italic;
}

.card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.15rem;
}

.tag-pill {
  font-size: 0.72rem;
  font-weight: 600;
  background: var(--color-sage-soft);
  border-radius: 999px;
  padding: 0.15rem 0.6rem;
  color: var(--color-sage);
}

/* nowrap ist hier bewusst: die Reihe darf nie umbrechen, egal wie schmal die
   Karte ist. .website-link/.maps-link duerfen stattdessen schrumpfen (siehe
   dort, flex-shrink + text-overflow: ellipsis) - die runden Icon-Buttons
   bekommen flex-shrink: 0 (siehe .card-actions .map-locate-btn), damit sie
   dabei nie unleserlich klein werden. */
.card-actions {
  margin-top: 0.5rem;
  display: flex;
  flex-wrap: nowrap;
  gap: 0.5rem;
}

.website-link {
  display: inline-block;
  min-width: 0;
  flex-shrink: 1;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--color-accent-ink);
  background: var(--color-accent);
  padding: 0.5rem 0.95rem;
  border-radius: 999px;
  text-decoration: none;
  box-shadow: 0 8px 18px -8px rgba(236, 48, 19, 0.55);
  transition: background 0.12s ease, transform 0.12s ease;
}

.website-link:hover {
  background: var(--color-accent-dark);
  transform: translateY(-1px);
}

.maps-link {
  display: inline-block;
  min-width: 0;
  flex-shrink: 1;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  padding: 0.5rem 0.95rem;
  border-radius: 999px;
  text-decoration: none;
  transition: background 0.12s ease, transform 0.12s ease;
}

.maps-link:hover {
  background: var(--color-surface-alt);
  transform: translateY(-1px);
}

/* .map-locate-btn ist hier gleichzeitig .maps-link (fuer Farben/Border) und
   braucht trotzdem einen eigenen <button> statt <a> (JS-Aktion statt
   Linkziel). Nur Icon, kein Text - deshalb quadratisch statt eine breite
   Pille wie Website/Google Maps. Breite/Hoehe werden bewusst ueber dieselbe
   Formel wie die Text-Pillen berechnet (Schriftgroesse * body-line-height
   [siehe line-height: 1.45 im body-Selektor] + vertikale Polsterung + Rand),
   statt eine eigene, nur ungefaehr passende Groesse zu verwenden - so ist die
   Hoehe garantiert exakt identisch zu .website-link/.maps-link, unabhaengig
   von Browser-Rundung der "normal" Zeilenhoehe. */
.card-actions .map-locate-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: calc(0.76rem * 1.45 + 1rem + 2px);
  height: calc(0.76rem * 1.45 + 1rem + 2px);
  padding: 0;
  border-radius: 999px;
  cursor: pointer;
  /* <button> hat sonst eine browsereigene Systemschrift statt die von
     .maps-link vorgegebene Font-Family zu erben. */
  font-family: inherit;
}

/* Wie .map-locate-btn: reiner Icon-Button, gleiche Groessenformel. */
.card-actions .card-share-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: calc(0.76rem * 1.45 + 1rem + 2px);
  height: calc(0.76rem * 1.45 + 1rem + 2px);
  padding: 0;
  border-radius: 999px;
  cursor: pointer;
  font-family: inherit;
}

/* Wie .map-locate-btn, aber kein reines Icon: rechts von der Sprechblase
   steht optional die Kommentar-Anzahl des Lokals (siehe
   updateCommentsShortcutCount/loadCommentCountsFor in app.js). Ohne Zahl
   bleibt der Button dank min-width = Hoehe + padding: 0 weiterhin ein
   perfekter Kreis wie .map-locate-btn; die JS-gesetzte .has-count-Klasse
   (nicht :has(), um beim etablierten JS-Klassen-Umschalt-Muster dieses
   Projekts zu bleiben) schaltet dann auf Pillenform mit Innenabstand um. */
.card-actions .card-comments-shortcut-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  height: calc(0.76rem * 1.45 + 1rem + 2px);
  min-width: calc(0.76rem * 1.45 + 1rem + 2px);
  padding: 0;
  border-radius: 999px;
  cursor: pointer;
  font-family: inherit;
}

/* gap lebt bewusst hier statt in der Basis-Regel oben: die leere
   .card-comments-shortcut-count-Span existiert im DOM immer schon (siehe
   buildCardBodyHtml in app.js), auch bevor die Zahl geladen ist - ein gap
   zwischen Icon und einer leeren Span verschiebt das Icon trotzdem sichtbar
   aus der horizontalen Mitte des runden Buttons, auch wenn die Span selbst
   0px breit ist. Ohne Zahl (kein .has-count) bleibt der gap deshalb 0. */
.card-actions .card-comments-shortcut-btn.has-count {
  gap: 0.2rem;
  padding: 0 0.6rem;
}

.card-actions .map-locate-icon,
.card-actions .comment-shortcut-icon,
.card-actions .share-icon {
  width: 0.95rem;
  height: 0.95rem;
  flex-shrink: 0;
}

.card-comments-shortcut-count {
  font-size: 0.72rem;
  font-weight: 700;
}

/* Gleiches Hover-Feedback wie .map-locate-btn:hover (dort ueber die
   .map-locate-btn-Klasse geloest, die dieser Button bewusst nicht traegt, um
   nicht versehentlich den Karten-Klick-Handler in setupMapLocateButtons()
   mitzutriggern). */
.card-comments-shortcut-btn:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.load-more {
  display: block;
  margin: 1.75rem auto 0;
  padding: 0.7rem 2rem;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.88rem;
  letter-spacing: 0.02em;
  border-radius: 999px;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
}

.load-more:hover {
  background: var(--color-accent-soft);
  color: var(--color-accent-dark);
}

.empty-state {
  padding: 2.5rem;
  text-align: center;
  color: var(--color-text-muted);
  font-weight: 400;
}

/* Lade-Zustand der Community-Ansicht (renderCommunityFeed() in app.js) -
   ersetzt den vorherigen reinen "Lädt…"-Text durch einen kleinen animierten
   Spinner, gleiches Rotations-Keyframe wie .location-spinner, nur groesser. */
.community-loading {
  display: flex;
  justify-content: center;
  padding: 2.5rem;
}

.community-loading-spinner {
  width: 1.75rem;
  height: 1.75rem;
  border: 3px solid var(--color-border);
  border-top-color: var(--color-accent);
  border-radius: 50%;
  animation: location-spinner-spin 0.7s linear infinite;
}
