* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* Farben: BMW-Blau und Feuerwehr-Rot nebeneinander.
   Damit sich die zwei nicht beissen, hat jede Farbe genau EINE Aufgabe:
     Blau  = alles, was man anklickt (Knoepfe, aktiver Reiter, Links)
     Rot   = die Marke (Kopfleiste, Ueberschriften) UND alles Zerstoererische
             (Loeschen, Abmelden) - beides passt zusammen, weil Rot in beiden
             Faellen "Achtung, hier ist die Feuerwehr bzw. hier wird's ernst" heisst
     Gruen = nur Bestaetigungen
   Der Untergrund ist kuehles Anthrazit mit einem Stich ins Blaue statt neutralem
   Grau - sonst wirkt das Blau daneben schmutzig. */
:root {
  --bg-dark: #10151b;
  --bg-card: #19212b;
  --bg-hover: #222d39;
  --text-primary: #e3e8ee;
  --text-secondary: #96a3b3;
  --border: #2f3d4d;

  --bmw-blau: #1c69d4;      /* Primaerfarbe: Knoepfe, aktiver Reiter */
  --bmw-blau-hell: #4a91ea; /* Links, Hover */
  --bmw-blau-dunkel: #12498f;
  --feuer-rot: #c8102e;     /* Marke + Gefahr - als Flaeche, mit weisser Schrift */
  --feuer-rot-hell: #e33045;
  /* Rot als SCHRIFT auf dunklem Grund muss heller sein, sonst ist es kaum zu
     lesen. Das volle Feuerwehr-Rot bleibt Flaechen vorbehalten. */
  --rot-schrift: #ff6274;

  --accent: var(--feuer-rot);
  --primary: var(--bmw-blau);
  --success: #1e9e5a;
  --danger: var(--feuer-rot);
}

body {
  background-color: var(--bg-dark);
  color: var(--text-primary);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
  line-height: 1.6;
}

/* ============= AUTH ============= */
.auth-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  background: linear-gradient(135deg, #10151b 0%, #19212b 100%);
}

.auth-box {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 40px;
  max-width: 400px;
  width: 100%;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}

.auth-box h1 {
  text-align: center;
  margin-bottom: 10px;
  font-size: 2.5em;
}

/* --- Das Wappen der Werkfeuerwehr -----------------------------------------
   Das Dreieck ist #183255 und damit nur knapp heller als der Grund der App
   (#19212b): auf dunkel verschwimmen seine Kanten, zu sehen ist praktisch nur
   die weisse Schrift darin. Deshalb bekommt es auf dem Bildschirm einen
   HELLEN Unterleger — dann sitzt es so auf der Seite, wie es auch auf Papier
   sitzt. Auf dem Papier braucht es den Unterleger nicht, dort ist ohnehin
   alles weiss (siehe die Druckregeln weiter unten). */
.wappen {
  display: block;
  height: auto;
  /* Das Seitenverhaeltnis steht hier, damit beim Laden nichts springt und ein
     ausgetauschtes Bild nicht verzerrt wird. */
  aspect-ratio: 284 / 220;
  object-fit: contain;
}

/* Gross ueber dem Anmeldefeld — das Erste, was einer sieht, der den QR-Code
   scannt. Der Unterleger ist bewusst ein weicher Kreis und kein Kasten: das
   Wappen IST schon ein Dreieck, ein Rahmen drumherum macht zwei Formen. */
.wappen.gross {
  width: 128px;
  margin: 0 auto 16px;
  /* Ein weisser Kreis dahinter sah aus wie ein Fleck, aus dem das Dreieck oben
     links und rechts herausragt - zwei Formen, die sich streiten. Ein Schein
     folgt dagegen der KONTUR des Wappens und hebt genau die Kante ab, die auf
     dunklem Grund verschwimmt. */
  filter: drop-shadow(0 0 1px rgba(255, 255, 255, 0.55))
          drop-shadow(0 2px 10px rgba(0, 0, 0, 0.5));
}

/* Im Kopf klein neben dem Schriftzug. Der Name steht daneben als Text, das
   Wappen muss ihn also nicht erklaeren — 34 px reichen, und mehr wuerde den
   Kopf auf dem Handy aufblaehen (der ist ohnehin 117 px hoch). */
/* Das Wappen steht neben dem GANZEN Block, nicht nur neben der ersten Zeile —
   sonst haengt "Wachgruppe B · Wache 2" darunter links daneben und die beiden
   Zeilen fangen an verschiedenen Stellen an. */
.header h1 {
  display: flex;
  align-items: center;
  gap: 12px;
}
.header h1 .kopf-text { display: block; }
.header h1 .wappen.im-kopf {
  /* 34 px waren zu klein: da wird das Wappen zu einem blauen Fleck, in dem
     nichts mehr zu erkennen ist. Lesbar muss es hier nicht sein — der Name
     steht daneben —, aber als WAPPEN erkennbar schon. */
  width: 46px;
  flex: none;
  filter: drop-shadow(0 0 1px rgba(255, 255, 255, 0.5));
}
@media (max-width: 560px) {
  .header h1 { gap: 9px; }
  .header h1 .wappen.im-kopf { width: 37px; }
  .wappen.gross { width: 104px; }
}

/* Auf Papier: kein Unterleger, das Blatt ist weiss. */
.wappen.im-blatt,
.wappen.im-balken { display: none; }

.auth-box h2 {
  text-align: center;
  color: var(--text-secondary);
  margin-bottom: 30px;
  font-size: 1.2em;
}

.auth-box form {
  display: flex;
  flex-direction: column;
  gap: 15px;
  margin-bottom: 20px;
}

.auth-box input {
  padding: 12px;
  background: var(--bg-hover);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text-primary);
  font-size: 1em;
}

.auth-box input:focus {
  outline: none;
  border-color: var(--bmw-blau);
  box-shadow: 0 0 0 3px rgba(28, 105, 212, 0.25);
}

.auth-box button[type="submit"] {
  padding: 12px;
  background: var(--bmw-blau);
  border: none;
  border-radius: 4px;
  color: white;
  font-weight: bold;
  cursor: pointer;
  transition: background 0.2s;
}

.auth-box button[type="submit"]:hover:not(:disabled) {
  background: var(--bmw-blau-hell);
}

.auth-box button[type="submit"]:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.auth-box p {
  text-align: center;
  color: var(--text-secondary);
}

.link-btn {
  background: none;
  border: none;
  color: var(--bmw-blau-hell);
  cursor: pointer;
  text-decoration: underline;
  font-weight: bold;
}

.error {
  color: var(--rot-schrift);
  text-align: center;
  padding: 10px;
  background: rgba(200, 16, 46, 0.14);
  border-radius: 4px;
}

/* ============= MAIN APP ============= */
.app {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.header {
  background: linear-gradient(135deg, #19212b 0%, #10151b 100%);
  border-bottom: 3px solid transparent;
  /* Rot der Feuerwehr laeuft nach BMW-Blau aus - die einzige Stelle, wo sich die
     beiden Farben beruehren, und damit der Wiedererkennungspunkt der Seite. */
  border-image: linear-gradient(90deg, var(--feuer-rot) 0%, var(--feuer-rot) 35%, var(--bmw-blau) 100%) 1;
  padding: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: sticky;
  top: 0;
  z-index: 100;
}

.header h1 {
  font-size: 1.8em;
}

.user-info {
  display: flex;
  align-items: center;
  gap: 15px;
  font-size: 0.9em;
}

.user-info button {
  background: var(--accent);
  border: none;
  color: white;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  font-weight: bold;
}

.user-info button:hover {
  background: var(--bmw-blau-hell);
}

.badge {
  background: var(--primary);
  color: white;
  padding: 4px 8px;
  border-radius: 3px;
  font-size: 0.85em;
  font-weight: bold;
}

.badge.success {
  background: var(--success);
}

.badge.danger {
  background: var(--danger);
}

/* ============= NAVIGATION ============= */
.nav {
  background: var(--bg-card);
  border-bottom: 1px solid var(--border);
  display: flex;
  overflow-x: auto;
  gap: 5px;
  padding: 10px;
  position: sticky;
  top: 70px;
  z-index: 50;
}

.nav button {
  background: var(--bg-hover);
  border: 1px solid var(--border);
  color: var(--text-primary);
  padding: 10px 15px;
  border-radius: 4px;
  cursor: pointer;
  white-space: nowrap;
  transition: all 0.2s;
  font-weight: 500;
}

.nav button:hover {
  background: var(--bg-dark);
  border-color: var(--bmw-blau);
}

.nav button.active {
  background: var(--bmw-blau);
  color: white;
  border-color: var(--bmw-blau);
}

/* ============= CONTENT ============= */
.content {
  flex: 1;
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
  width: 100%;
}

.section {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 20px;
  margin-bottom: 20px;
}

.section h2 {
  margin-bottom: 20px;
  color: var(--text-primary);
  font-size: 1.5em;
}

.section h3 {
  margin-top: 20px;
  margin-bottom: 15px;
  color: var(--text-primary);
  font-size: 1.1em;
}

/* ============= FORMS ============= */
.form {
  display: grid;
  gap: 15px;
  margin-bottom: 20px;
  padding: 15px;
  background: var(--bg-hover);
  border-radius: 4px;
}

.form input,
.form select,
.form textarea {
  padding: 12px;
  background: var(--bg-dark);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text-primary);
  font-size: 1em;
  font-family: inherit;
}

.form input:focus,
.form select:focus,
.form textarea:focus {
  outline: none;
  border-color: var(--bmw-blau);
  box-shadow: 0 0 0 3px rgba(28, 105, 212, 0.25);
}

.form textarea {
  resize: vertical;
  min-height: 80px;
}

.form button {
  padding: 12px;
  background: var(--bmw-blau);
  border: none;
  border-radius: 4px;
  color: white;
  font-weight: bold;
  cursor: pointer;
  transition: background 0.2s;
}

.form button:hover:not(:disabled) {
  background: var(--bmw-blau-hell);
}

/* Ein gesperrter Knopf muss gesperrt AUSSEHEN.
   Gefunden im Bild zum Korrektur-Fenster (1.73): "Fertig" war ohne Grund
   disabled und sah trotzdem aus wie ein Knopf, den man druecken kann. Man
   tippt drauf, es passiert nichts, und man sucht den Fehler bei sich.
   Es gab in der ganzen App keine allgemeine Regel dafuer - nur eine fuer die
   Zaehlerknoepfe (.step-btn:disabled). Die hier gilt fuer alle. */
button:disabled, .small-btn:disabled, .link-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Ein .link-btn IN einem Formular war bisher ein zweiter blauer Knopf — nur
   unterstrichen. Neben dem echten Absenden-Knopf steht dann zweimal dasselbe
   Blau untereinander, und "Abbrechen" sieht aus wie die Hauptsache. Genau der
   Fehler, den wir bei "Hab bezahlt (€ 12,50)" schon einmal hatten: zwei
   Knoepfe, die gleich aussehen, sind ein Ratespiel.
   Muss hinter .form button stehen und beide Regeln ueberbieten. */
.form .link-btn,
.form .karte-fuss .link-btn {
  padding: 12px 4px;
  min-height: 0;
  background: none;
  color: var(--bmw-blau-hell);
  text-transform: none;
  letter-spacing: normal;
  border-radius: 0;
  font-size: 0.95em;
}
.form .link-btn:hover { background: none; color: var(--text-primary); }

/* ============= LISTS ============= */
.list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.list-item {
  background: var(--bg-hover);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 15px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 15px;
  flex-wrap: wrap;
  transition: all 0.2s;
}

.list-item:hover {
  background: var(--bg-dark);
  border-color: var(--bmw-blau);
}

.list-item strong {
  color: var(--text-primary);
}

.list-item small {
  color: var(--text-secondary);
  font-size: 0.85em;
}

.list-item p {
  margin: 5px 0;
  color: var(--text-secondary);
}

.list-item a {
  color: var(--primary);
  text-decoration: none;
  font-weight: bold;
}

.list-item a:hover {
  text-decoration: underline;
}

.tausch-item {
  flex-direction: column;
  align-items: flex-start;
}

.admin-item {
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
}

.admin-actions {
  display: flex;
  gap: 10px;
  align-items: center;
}

.small-btn {
  background: var(--primary);
  border: none;
  color: white;
  padding: 6px 12px;
  border-radius: 3px;
  cursor: pointer;
  font-weight: bold;
  font-size: 0.85em;
}

.small-btn:hover {
  background: var(--bmw-blau-hell);
}

.small-select {
  padding: 6px 10px;
  background: var(--bg-dark);
  border: 1px solid var(--border);
  border-radius: 3px;
  color: var(--text-primary);
  /* Nicht 0.85em: unter 16px zoomt iOS beim Antippen hinein und nicht wieder
     heraus. Kleiner wirken laesst sich das ueber Polsterung und Farbe. */
  font-size: max(16px, 0.85em);
}

/* ============= DASHBOARD ============= */
.dashboard {
  width: 100%;
}

.stat-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 15px;
  margin-top: 20px;
}

.stat-card {
  background: linear-gradient(135deg, var(--bmw-blau) 0%, var(--bmw-blau-dunkel) 100%);
  border-radius: 8px;
  padding: 20px;
  text-align: center;
}

.stat-card h3 {
  margin: 0 0 10px 0;
  font-size: 1.1em;
}

.stat-card p {
  font-size: 1.5em;
  font-weight: bold;
}

/* ============= RESPONSIVE ============= */
@media (max-width: 768px) {
  .header {
    flex-direction: column;
    gap: 15px;
    padding: 15px;
  }

  .header h1 {
    font-size: 1.4em;
  }

  .user-info {
    width: 100%;
    justify-content: space-between;
  }

  .nav {
    gap: 3px;
    padding: 8px;
    top: 85px;
  }

  .nav button {
    padding: 8px 12px;
    font-size: 0.9em;
  }

  .content {
    padding: 15px;
  }

  .section {
    padding: 15px;
  }

  .list-item {
    flex-direction: column;
    align-items: flex-start;
  }

  .admin-item {
    flex-direction: column;
    align-items: flex-start;
  }

  .admin-actions {
    width: 100%;
    flex-wrap: wrap;
  }

  .stat-cards {
    grid-template-columns: 1fr;
  }

  .form {
    grid-template-columns: 1fr;
  }

  .auth-box {
    padding: 25px;
    margin: 20px;
  }
}

@media (max-width: 480px) {
  .header h1 {
    font-size: 1.2em;
  }

  .nav {
    gap: 2px;
  }

  .nav button {
    padding: 6px 10px;
    font-size: 0.8em;
  }

  .section {
    padding: 12px;
  }

  .list-item {
    padding: 12px;
  }

  .badge {
    font-size: 0.75em;
  }

  .user-info {
    font-size: 0.8em;
  }

  .user-info button {
    padding: 6px 12px;
    font-size: 0.8em;
  }
}

/* ==========================================================================
   Ergaenzungen: Wochenplan, Kochkarten, Kaffeekasse, QR-Einladung
   ========================================================================== */

.hinweis { color: var(--text-secondary); }
.klein { font-size: 0.85em; line-height: 1.45; }
.gross { font-size: 1.4em; font-weight: bold; }
.rot { color: var(--rot-schrift); }
.wachsend { flex: 1; min-width: 0; }

/* Meldungen — anklickbar zum Wegräumen */
.meldung {
  padding: 10px 14px;
  border-radius: 4px;
  margin: 10px 0;
  cursor: pointer;
  font-size: 0.95em;
}
.meldung.fehler { color: var(--rot-schrift); background: rgba(231, 76, 60, 0.12); border: 1px solid rgba(231, 76, 60, 0.4); }
.meldung.gut { color: var(--success); background: rgba(46, 204, 113, 0.12); border: 1px solid rgba(46, 204, 113, 0.4); }

/* Beschriftetes Feld: Datumsfelder ohne Beschriftung raet man sonst nur */
.feld { display: flex; flex-direction: column; gap: 5px; font-size: 0.85em; color: var(--text-secondary); }
/* Gestylt war bisher nur "was in einem .form steht". Ein .feld ausserhalb
   davon — die beiden Erinnerungen bei den Schichttagen zum Beispiel — bekam
   das nackte Browser-Feld: weisser Kasten mit schwarzer Schrift mitten in
   einer dunklen Seite. Dieselben Werte wie bei .form, an einer Stelle mehr. */
.feld > input,
.feld > select,
.feld > textarea {
  padding: 10px 12px;
  background: var(--bg-dark);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text-primary);
  font-size: 1rem;
  font-family: inherit;
}
.feld > input:focus,
.feld > select:focus,
.feld > textarea:focus {
  outline: none;
  border-color: var(--bmw-blau);
  box-shadow: 0 0 0 3px rgba(28, 105, 212, 0.25);
}
/* Abgeschaltet heisst: sieht man, kann man aber nicht anfassen. Ohne das
   sieht ein ausgegrautes Feld genauso aus wie ein bedienbares. */
.feld > input:disabled,
.feld > select:disabled { opacity: 0.5; cursor: not-allowed; }

.form.eingebettet { margin: 0; }

.stat-card.klickbar { cursor: pointer; transition: transform 0.15s; }
.stat-card.klickbar:hover { transform: translateY(-2px); }
.stat-card small { display: block; opacity: 0.85; font-size: 0.8em; font-weight: normal; }

.naechster {
  margin-top: 20px;
  padding: 18px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: 6px;
}
.naechster h3 { margin: 0 0 8px; font-size: 1em; color: var(--text-secondary); }
.naechster button { margin-top: 10px; }

/* --- Wochenplan --------------------------------------------------------- */
.wochenwahl { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 15px; }

/* Auf schmalen Handys laesst sich die Tabelle seitlich schieben, statt die
   ganze Seite quer scrollen zu lassen. */
.tabelle-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.wochenplan { border-collapse: collapse; width: 100%; min-width: 460px; }
.wochenplan th, .wochenplan td {
  border: 1px solid var(--border);
  padding: 8px;
  vertical-align: top;
  text-align: left;
}
.wochenplan thead th { background: var(--bg-hover); font-size: 0.9em; }
.wochenplan .tagspalte { background: var(--bg-hover); width: 110px; font-weight: 600; font-size: 0.9em; }
.wochenplan .tagspalte small { color: var(--text-secondary); font-weight: normal; }

.zelle-eintrag { display: flex; align-items: center; justify-content: space-between; gap: 6px; padding: 2px 0; }
.zelle-aktionen { display: flex; gap: 4px; flex-shrink: 0; }

.mini {
  background: var(--bg-dark);
  border: 1px solid var(--border);
  color: var(--text-secondary);
  border-radius: 3px;
  padding: 2px 7px;
  cursor: pointer;
  font-size: 0.85em;
  line-height: 1.4;
}
.mini:hover { color: var(--text-primary); border-color: var(--bmw-blau); }
.mini.gefahr:hover { color: white; background: var(--danger); border-color: var(--danger); }
.mini.leer { width: 100%; margin-top: 4px; opacity: 0.5; }
.mini.leer:hover { opacity: 1; }

/* --- Karten (Kochliste, Tausch) ----------------------------------------- */
.karte { flex-direction: column; align-items: stretch; }
.karte:hover { background: var(--bg-hover); border-color: var(--border); }
.karte-kopf { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.karte-fuss { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 8px; }
.karte .koch { color: var(--text-secondary); font-size: 0.9em; }
.karte .menue { font-size: 1.05em; color: var(--text-primary); margin: 8px 0; }
.vergangen { opacity: 0.55; }

.esser { list-style: none; margin: 8px 0 0; padding: 8px 12px; background: var(--bg-dark); border-radius: 4px; }
.esser li { font-size: 0.9em; padding: 2px 0; }
.esser em { color: var(--text-secondary); font-style: normal; }

.anmeldung { display: flex; gap: 10px; align-items: center; margin-top: 10px; flex-wrap: wrap; }
.anmeldung input {
  flex: 1;
  min-width: 160px;
  padding: 8px 10px;
  background: var(--bg-dark);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text-primary);
  font-family: inherit;
}
.small-btn.danger { background: var(--danger); }
.small-btn.danger:hover { background: var(--feuer-rot-hell); }
.small-btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* --- Kaffeekasse -------------------------------------------------------- */
.kassenstand {
  text-align: center;
  padding: 18px;
  background: var(--bg-hover);
  border: 1px solid var(--border);
  border-radius: 6px;
  margin-bottom: 15px;
}
.kassenstand small { color: var(--text-secondary); }

.artwahl { display: flex; gap: 10px; }
.artwahl label {
  flex: 1;
  text-align: center;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  background: var(--bg-dark);
}
.artwahl label.gewaehlt { border-color: var(--bmw-blau); background: rgba(28, 105, 212, 0.16); }
.artwahl input { display: none; }

.list-item.zeile { flex-direction: row; align-items: center; }
.betrag { font-weight: bold; font-variant-numeric: tabular-nums; white-space: nowrap; }
.betrag.einzahlung { color: #3fc47f; }
.betrag.ausgabe { color: var(--rot-schrift); }

/* --- QR-Einladung ------------------------------------------------------- */
.overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 200;
}
.qr-box {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 24px;
  max-width: 420px;
  width: 100%;
  text-align: center;
  /* Wird der Inhalt hoeher als der Bildschirm (Statistik auf dem Handy), scrollt
     das Fenster in sich. Ohne das rutscht der Schliessen-Knopf aus dem Bild und
     man kommt nicht mehr raus. */
  max-height: calc(100vh - 40px);
  overflow-y: auto;
}
.qr-box h3 { margin-top: 0; }
/* Ein QR-Code gehoert mittig, ein Absatz nicht. Fenster, in denen wirklich
   etwas zu LESEN steht, setzen ihren Text deshalb linksbuendig - zentrierte
   Fliesstexte ueber mehrere Zeilen zwingen das Auge bei jeder Zeile neu, den
   Anfang zu suchen. Ueberschriften und Knopfleisten bleiben mittig. */
.qr-box.zumlesen { text-align: left; }
/* Die Absaetze ausdruecklich mitnehmen. Vererben reicht hier NICHT: das
   Anmelde-Fenster steht innerhalb von .auth-box, und ".auth-box p" setzt die
   Ausrichtung direkt am Absatz - eine direkt gesetzte Eigenschaft schlaegt
   immer die geerbte, egal wie spezifisch die andere Regel ist. */
.qr-box.zumlesen p, .qr-box.zumlesen li, .qr-box.zumlesen label { text-align: left; }
.qr-box.zumlesen h3, .qr-box.zumlesen h4 { text-align: center; }
.qr-box.zumlesen h4 { margin: 0 0 6px; }
/* Weisser Grund: viele Handykameras erkennen einen QR-Code auf dunklem
   Untergrund nicht zuverlaessig. */
.qr { background: #fff; padding: 12px; border-radius: 6px; display: inline-block; margin: 10px 0; }
.qr svg { width: 100%; max-width: 260px; height: auto; display: block; }
.qr-box .karte-fuss { justify-content: center; }
.qr-box .karte-fuss.links { justify-content: flex-start; }

/* Ein Bon ist ein Foto und darf breiter sein als ein QR-Code - man will die
   Posten lesen koennen. Hoehe gedeckelt, damit der Schliessen-Knopf auf dem
   Handy im Bild bleibt; was nicht passt, scrollt die Box (siehe oben). */
.qr-box.bon-box { max-width: 640px; }
.bon-bild {
  width: 100%;
  height: auto;
  max-height: 70vh;
  object-fit: contain;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: #fff;
  margin: 10px 0;
}

/* Der Druckbogen steht im DOM, aber nur der Drucker sieht ihn (Suche:
   "@media print"). Am Bildschirm zeigt stattdessen .qr-vorschau kleine
   Kaertchen - man will ja sehen, wer alles auf dem Blatt landet. */
.qr-bogen { display: none; }
.qr-vorschau {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 10px; margin: 12px 0;
}
.qr-vorschau-karte {
  background: var(--bg-dark); border: 1px solid var(--border); border-radius: 6px;
  padding: 8px; text-align: center;
}
.qr-vorschau-karte div { background: #fff; border-radius: 4px; padding: 5px; }
.qr-vorschau-karte svg { width: 100%; height: auto; display: block; }
.qr-vorschau-karte span { display: block; margin-top: 6px; font-size: 0.8em; font-weight: 600; }

/* --- Wochenende: was der Koch ausgelegt hat -------------------------------
   Der Kasten steht direkt unter den Kacheln, damit der Koch beim Reinkommen
   sieht, was schon drin ist und was noch fehlt. */
.ausgaben {
  margin: 14px 0; padding: 12px 14px; border-radius: 8px;
  background: var(--bg-dark); border: 1px solid var(--border);
  border-left: 3px solid var(--feuer-rot);
}
.ausgaben > h3 { margin: 0 0 4px; }
.ausgaben-liste { list-style: none; margin: 10px 0; display: flex; flex-direction: column; }
.ausgaben-liste li {
  display: flex; align-items: center; gap: 10px; padding: 7px 2px;
  border-bottom: 1px solid var(--border);
}
.ausgaben-liste li.summe { border-bottom: none; border-top: 2px solid var(--border); font-size: 1.05em; }
.ausgaben .rechnung {
  margin: 8px 0 0; padding: 8px 10px; border-radius: 6px;
  background: rgba(28, 105, 212, 0.15); font-size: 1.02em;
}
.ausgaben .rechnung strong { font-size: 1.15em; }
.stat-card.stark { border: 1px solid var(--feuer-rot); }
/* Am Ganztags-Tag ist die eine Frage "esse ich mit?" - dann darf das Kaestchen
   auch aussehen wie die Hauptsache und nicht wie eine Fussnote. */
.toggle.abend.gross { font-size: 1.08em; padding: 8px 0; }

/* --- Wochentage am Artikel ----------------------------------------------- */
.wochentage { margin-top: 4px; }
.tage-haken { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 5px; }
.tage-haken label {
  display: flex; align-items: center; gap: 3px; cursor: pointer;
  padding: 3px 6px; border-radius: 999px; font-size: 0.8em;
  border: 1px solid var(--border); color: var(--text-secondary);
}
.tage-haken label.an { border-color: var(--bmw-blau); background: rgba(28, 105, 212, 0.18); color: var(--text-primary); }
.tage-haken input { margin: 0; }

/* --- Wuensche an die App -------------------------------------------------
   Steht unten auf der Uebersicht. Der Daumen links ist absichtlich gross und
   traegt die Zahl mit: das ist der Knopf, den man am haeufigsten drueckt, und
   er sagt gleichzeitig, wie viele schon dafuer sind. */
/* --- Was fehlt (Bedarfsanforderung) ---------------------------------------
   Steht auf der Uebersicht ueber dem Wunschkasten. Gruener Rand, weil es um
   etwas geht, das man ERLEDIGEN kann - im Gegensatz zu den offenen Betraegen
   darueber, die rot sind. */
.was-fehlt {
  margin-top: 22px; padding: 14px 16px;
  background: var(--bg-card); border: 1px solid var(--border);
  border-left: 4px solid var(--gut, #2e9e5b); border-radius: 8px;
}
.was-fehlt > h3 { margin: 0 0 8px; }

/* Die Vorschlaege zum Antippen: eine Reihe, die umbricht. Auf dem Handy wird
   daraus von selbst ein Block - das ist richtig so, jeder Knopf bleibt voll
   antippbar statt auf halbe Breite gequetscht zu werden. */
/* Vorschlaege sind ANGEBOTE, keine Hauptsache — sie duerfen nicht aussehen
   wie acht Knoepfe, die alle gedrueckt werden wollen. Am Handy nahmen sie in
   voller Knopfgroesse den halben Bildschirm ein. Also flach, mit Rahmen statt
   Flaeche: erkennbar antippbar, aber ruhig. */
.bedarf-vorschlaege {
  display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px;
}
.bedarf-vorschlaege .small-btn {
  flex: none;
  padding: 6px 11px;
  font-size: 0.82rem;
  font-weight: 500;
  background: transparent;
  color: var(--text-secondary);
  border: 1px solid var(--border);
}
.bedarf-vorschlaege .small-btn:hover:not(:disabled) {
  background: var(--bg-hover); color: var(--text-primary); border-color: var(--bmw-blau);
}

.bedarf-verlauf { margin-top: 12px; }
.bedarf-verlauf summary { cursor: pointer; }
.bedarf-verlauf .list-item.erledigt strong { font-weight: normal; }

.wuensche { margin-top: 22px; }
.wuensche > h3 { margin-bottom: 4px; }
.list-item.wunsch { align-items: flex-start; gap: 12px; }
.wunsch-text { margin: 0 0 4px; line-height: 1.4; }
.wunsch-antwort {
  margin: 6px 0 0; padding: 6px 10px; font-size: 0.9em;
  background: var(--bg-dark); border-left: 3px solid var(--bmw-blau); border-radius: 4px;
}
.ich-auch {
  flex-shrink: 0; display: flex; flex-direction: column; align-items: center; gap: 2px;
  min-width: 52px; padding: 7px 6px; cursor: pointer;
  background: var(--bg-dark); border: 1px solid var(--border); border-radius: 8px;
  color: var(--text-secondary); transition: transform 0.12s, border-color 0.15s;
}
.ich-auch:hover { transform: translateY(-1px); border-color: var(--bmw-blau); }
.ich-auch .daumen { font-size: 1.1em; filter: grayscale(1); opacity: 0.6; }
.ich-auch .zahl { font-weight: bold; font-size: 0.95em; }
.ich-auch.dabei { border-color: var(--bmw-blau); background: rgba(28, 105, 212, 0.18); color: var(--text-primary); }
.ich-auch.dabei .daumen { filter: none; opacity: 1; }

/* --- "Was gab's schon?" -------------------------------------------------- */
.ideen-liste { max-height: 50vh; overflow-y: auto; }
.ideen-nehmen {
  margin-top: 12px; padding: 10px 12px; border-radius: 6px;
  background: var(--bg-dark); border: 1px solid var(--bmw-blau);
}
.ideen-nehmen p { margin: 0 0 8px; }
.ideen-nehmen .form { margin-bottom: 6px; }

/* Die Auswahlliste vorm Erzeugen: lang, deshalb scrollt sie fuer sich. */
.wahl-liste {
  max-height: 46vh; overflow-y: auto; margin: 10px 0;
  border: 1px solid var(--border); border-radius: 6px; padding: 6px 10px;
}
.wahl-liste .haken { display: flex; align-items: center; gap: 8px; padding: 5px 0; }
.wahl-liste .haken + .haken { border-top: 1px solid var(--border); }
.hinweis.warnung {
  background: rgba(214, 40, 40, 0.12); border-left: 3px solid var(--feuer-rot);
  padding: 8px 10px; border-radius: 4px;
}

/* Das Druckbild steht weiter unten gesammelt (Suche: "@media print"). */

@media (max-width: 768px) {
  /* Die Zeilen-Layouts sollen auch schmal Zeilen bleiben — sonst zerfaellt
     die Kaffeekassen-Liste in vier Zeilen pro Buchung. */
  .list-item.zeile { flex-direction: row; align-items: center; flex-wrap: wrap; }
  .artwahl { flex-direction: column; }
}

/* Handy-Feinschliff: vier volle Kacheln untereinander hiessen scrollen, bevor
   ueberhaupt etwas zu sehen ist — zwei nebeneinander passen aufs erste Bild.
   Und der Wochenplan soll ohne Seitwaertsschieben komplett draufpassen. */
@media (max-width: 600px) {
  .stat-cards { grid-template-columns: 1fr 1fr; gap: 10px; }
  .stat-card { padding: 14px 10px; }
  .stat-card h3 { font-size: 0.9em; }
  .stat-card p { font-size: 1.25em; }

  .wochenplan { min-width: 0; font-size: 0.9em; }
  .wochenplan th, .wochenplan td { padding: 5px 4px; }
  .wochenplan .tagspalte { width: 72px; font-size: 0.8em; }
  .zelle-eintrag { flex-wrap: wrap; }
  .mini { padding: 1px 5px; }
}

/* Wachgruppe/Wache unter dem Titel — klein genug, dass sie den Kopf nicht
   aufblaeht, gross genug, dass klar ist, wessen Listen das hier sind. */
.header h1 .wache {
  display: block;
  font-size: 0.5em;
  font-weight: normal;
  letter-spacing: 0.06em;
  color: var(--text-secondary);
  margin-top: 2px;
}
.auth-box .wache-gross {
  text-align: center;
  color: var(--rot-schrift);
  font-size: 0.95em;
  letter-spacing: 0.06em;
  margin-bottom: 18px;
}

/* Auf den blauen Kacheln braucht ein negativer Kassenstand ein helleres Rot —
   das Feuerwehr-Rot verschwindet dort im Blau. */
.stat-card .rot { color: #ffc3c9; }

/* ==========================================================================
   Kochplan
   ========================================================================== */

.plan-kopf { display: flex; align-items: center; justify-content: space-between; gap: 15px; flex-wrap: wrap; }
.plan-kopf h2 { margin-bottom: 0; }
.jahr { font-size: 1.2em; min-width: 60px; text-align: center; }

.werkzeuge { display: flex; gap: 8px; flex-wrap: wrap; margin: 15px 0 10px; }

/* Eingabeleisten liegen waagrecht, damit "Monat / Tag / Wer" eine Zeile bleibt
   statt drei Zeilen Formular zu werden. */
.form.leiste { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.form.leiste .feld { flex: 0 1 auto; }
.form.leiste input[type="text"] { min-width: 150px; }
.form.leiste button { padding: 10px 14px; }

.namensbereich { margin: 5px 0 15px; }

.pillen { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.pille {
  display: inline-flex; align-items: center; gap: 2px;
  border: 1.5px solid var(--border); border-radius: 20px;
  padding: 2px 6px 2px 4px; background: var(--bg-dark);
}
.pille .pillenname {
  display: inline-flex; align-items: center; gap: 6px;
  background: none; border: none; color: var(--text-secondary);
  font-size: 0.85em; font-weight: 700; cursor: pointer; padding: 4px 6px;
  font-family: inherit;
}
.pille .punkt { width: 7px; height: 7px; border-radius: 50%; background: #5a6a76; flex-shrink: 0; }
.pille.an { border-color: rgba(28, 105, 212, 0.5); background: rgba(28, 105, 212, 0.12); }
.pille.an .pillenname { color: var(--text-primary); }
.pille.an .punkt { background: var(--bmw-blau); }
.pille.aus .pillenname { text-decoration: line-through; opacity: 0.6; }

/* Plan und Auswertung nebeneinander, auf schmalen Geraeten untereinander. */
.plan-flaeche { display: grid; grid-template-columns: 1fr 260px; gap: 15px; align-items: start; }

.monatsraster { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 10px; }

.monatskarte {
  background: var(--bg-hover);
  border: 1px solid var(--border);
  border-top: 3px solid var(--monatsfarbe);
  border-radius: 6px;
  overflow: hidden;
}
.monatskarte.leer { opacity: 0.5; }
/* Ein gesperrter Monat ist NICHT dasselbe wie ein leerer: der obere Rand wird
   gestrichelt und grau statt in der Monatsfarbe. Man sieht auf einen Blick, wo
   der Plan aufhoert - ohne die Zeile lesen zu muessen. */
.monatskarte.gesperrt { border-top-style: dashed; border-top-color: var(--border); opacity: 0.65; }
.monatskarte.gesperrt:hover { transform: none; }

/* Ein ruhiger Strich zwischen zwei Blöcken in einem Fenster. */
.trenner { border: 0; border-top: 1px solid var(--border); margin: 18px 0 12px; }
.monatskopf {
  display: flex; align-items: center; gap: 7px;
  padding: 8px 10px; background: rgba(255, 255, 255, 0.03);
  border-bottom: 1px solid var(--border);
}
.monatskopf .punkt { width: 8px; height: 8px; border-radius: 50%; background: var(--monatsfarbe); flex-shrink: 0; }
/* Der Monatsname stand in der Monatsfarbe - bei Mai und November ergab das auf
   dem dunklen Grund einen Kontrast von 1,2:1, also praktisch unsichtbar. Die
   Farbcodierung tragen der Punkt links und die 3px-Oberkante ohnehin schon. */
.monatskopf strong { color: var(--text-primary); letter-spacing: 0.04em; }
.monatskopf small { margin-left: auto; color: var(--text-secondary); font-size: 0.75em; }

.planzeile {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  font-size: 0.92em;
}
.planzeile:last-child { border-bottom: none; }
.planzeile[title] { cursor: pointer; }
.planzeile[title]:hover { background: var(--bg-dark); }
.planzeile.vergangen { opacity: 0.45; }
.plantag { color: var(--text-secondary); font-variant-numeric: tabular-nums; font-weight: 700; font-size: 0.85em; min-width: 38px; }
.plankoch { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stift { opacity: 0; color: var(--text-secondary); font-size: 0.8em; }
.planzeile:hover .stift { opacity: 1; }
.leerzeile { color: var(--text-secondary); justify-content: center; }

.tracking h3 { margin-top: 0; }
.track-tabelle { width: 100%; border-collapse: collapse; font-size: 0.85em; }
.track-tabelle th {
  text-align: left; padding: 6px 8px; background: var(--bg-dark);
  color: var(--text-secondary); font-size: 0.9em; border-bottom: 1px solid var(--border);
}
.track-tabelle td { padding: 5px 8px; border-bottom: 1px solid rgba(255, 255, 255, 0.05); }
.track-tabelle .zahl { text-align: right; font-variant-numeric: tabular-nums; font-weight: 700; }
/* Gelb = als Naechstes dran. Dieselbe Kennzeichnung wie auf dem Ausdruck. */
.track-tabelle tr.dran td { background: rgba(232, 162, 37, 0.16); color: #ffd489; }

.tauschpfeil { text-align: center; font-size: 1.3em; color: var(--text-secondary); }
.zufall-ergebnis {
  text-align: center; padding: 22px 12px; margin: 12px 0;
  background: var(--bg-dark); border: 1px solid var(--border); border-radius: 6px;
}
.qr-box.breit { max-width: 620px; }
.qr-box .stat-cards { margin-bottom: 12px; }
.qr-box .form { margin-bottom: 0; }

@media (max-width: 900px) {
  /* Untereinander, und der Plan zuerst - die Auswertung schaut man erst danach an.
     Andersherum musste man am Handy an einer 20-zeiligen Tabelle vorbeiscrollen,
     bevor man ueberhaupt sah, wer wann kocht. */
  .plan-flaeche { grid-template-columns: 1fr; }
}
@media (max-width: 600px) {
  .monatsraster { grid-template-columns: 1fr 1fr; gap: 8px; }
  .monatskarte { font-size: 0.9em; }
  .monatskopf { padding: 6px 7px; gap: 5px; }
  .planzeile { padding: 5px 7px; gap: 5px; }
  .plantag { min-width: 32px; }
  .stift { display: none; }
  .form.leiste { display: grid; grid-template-columns: 1fr 1fr; }
  .form.leiste button, .form.leiste .link-btn { grid-column: 1 / -1; }
}

/* ==========================================================================
   Auftritt — kraeftiger, ohne unbedienbar zu werden
   --------------------------------------------------------------------------
   Regeln, an die sich das hier haelt:
   - Schrift wird groesser, nie kleiner. Gelesen wird das auf der Wache am Handy.
   - Nichts wackelt laenger als 0,2 s, und wer im System "Bewegung reduzieren"
     eingestellt hat, bekommt gar keine (ganz unten).
   - Farbe traegt weiter Bedeutung: Blau = anklicken, Rot = Marke und Achtung.
     Die Show kommt aus Groesse, Kontrast und Flaeche, nicht aus mehr Farben.
   - Beruehrflaechen bleiben mindestens 40 px hoch.
   ========================================================================== */

/* Beide Schriften liegen lokal unter /schriften - kein Aufruf zu Google. */
@font-face {
  font-family: 'Bebas Neue';
  src: url('/schriften/bebas-neue-latin-400-normal.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'DM Sans';
  src: url('/schriften/dm-sans-latin-400-normal.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'DM Sans';
  src: url('/schriften/dm-sans-latin-500-normal.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'DM Sans';
  src: url('/schriften/dm-sans-latin-700-normal.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}

:root {
  --schrift: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --plakat: 'Bebas Neue', 'DM Sans', Impact, sans-serif;
}

body {
  font-family: var(--schrift);
  /* Ein sehr weiter, sehr dunkler Schein hinter dem Kopf - gibt der Seite Tiefe,
     ohne dass irgendwo Kontrast verloren geht. */
  background:
    radial-gradient(1100px 420px at 50% -180px, rgba(28, 105, 212, 0.16), transparent 70%),
    radial-gradient(700px 300px at 12% -80px, rgba(200, 16, 46, 0.12), transparent 70%),
    var(--bg-dark);
  background-attachment: fixed;
}

/* --- Plakatschrift fuer alles, was gross ist ------------------------------ */
.header h1, .auth-box h1,
.section h2, .dashboard h2,
.stat-card p, .kassenstand .gross, .zufall-ergebnis .gross,
.monatskopf strong, .jahr {
  font-family: var(--plakat);
  font-weight: 400;
  letter-spacing: 0.035em;
}

.header h1 { font-size: 2.1em; line-height: 1.05; }
.auth-box h1 { font-size: 3.1em; line-height: 1; }
.section h2, .dashboard h2 { font-size: 2em; line-height: 1.1; }
.stat-card p { font-size: 2.5em; line-height: 1; letter-spacing: 0.02em; }
.kassenstand .gross { font-size: 2.6em; }
.zufall-ergebnis .gross { font-size: 2.4em; }
.jahr { font-size: 1.9em; }
/* Bebas hat keine Kleinbuchstaben - Umlaute und Ziffern sitzen dadurch etwas
   hoeher; die Zeilenhoehe faengt das ab. */

/* --- Kopfleiste ---------------------------------------------------------- */
.header {
  background: linear-gradient(160deg, #1b2634 0%, #10151b 65%);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
}
.header h1 .wache {
  font-family: var(--schrift);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-size: 0.38em;
}

/* --- Navigation ---------------------------------------------------------- */
.nav {
  background: rgba(16, 21, 27, 0.92);
  backdrop-filter: blur(8px);
  padding: 12px 10px;
}
.nav button {
  border-radius: 999px;
  padding: 10px 18px;
  min-height: 42px;
  letter-spacing: 0.01em;
  transition: transform 0.14s, background 0.14s, border-color 0.14s;
}
.nav button:hover { transform: translateY(-1px); }
.nav button.active {
  box-shadow: 0 4px 16px rgba(28, 105, 212, 0.45);
}

/* --- Flaechen ------------------------------------------------------------ */
.section {
  border-radius: 12px;
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.32);
  position: relative;
  overflow: hidden;
}
/* Feiner Farbverlauf oben auf jeder Karte - dasselbe Motiv wie in der Kopfleiste. */
.section::before {
  content: '';
  position: absolute; inset: 0 0 auto 0; height: 3px;
  background: linear-gradient(90deg, var(--feuer-rot), var(--bmw-blau) 65%, transparent);
}
.section h2 { margin-top: 4px; }

/* --- Kacheln ------------------------------------------------------------- */
.stat-card {
  border-radius: 12px;
  background:
    linear-gradient(150deg, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0) 55%),
    linear-gradient(135deg, var(--bmw-blau) 0%, var(--bmw-blau-dunkel) 100%);
  box-shadow: 0 8px 22px rgba(6, 83, 163, 0.32);
  border: 1px solid rgba(255, 255, 255, 0.12);
}
.stat-card h3 {
  font-size: 0.8em; letter-spacing: 0.12em; text-transform: uppercase;
  opacity: 0.9; font-weight: 700;
}
.stat-card.klickbar:hover { transform: translateY(-3px); box-shadow: 0 14px 30px rgba(6, 83, 163, 0.45); }

/* --- Knoepfe ------------------------------------------------------------- */
.form button, .auth-box button[type="submit"] {
  border-radius: 8px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 0.92em;
  min-height: 44px;
  box-shadow: 0 4px 14px rgba(28, 105, 212, 0.35);
  transition: transform 0.12s, box-shadow 0.12s, background 0.15s;
}
.form button:hover, .auth-box button[type="submit"]:hover:not(:disabled) { transform: translateY(-1px); }
.form button:active, .auth-box button[type="submit"]:active { transform: translateY(1px); box-shadow: none; }

.small-btn { border-radius: 999px; padding: 8px 15px; min-height: 36px; letter-spacing: 0.02em; transition: transform 0.12s, background 0.15s; }
.small-btn:hover:not(:disabled) { transform: translateY(-1px); }
.user-info button { border-radius: 999px; letter-spacing: 0.06em; text-transform: uppercase; font-size: 0.8em; }

/* Eine neutrale Marke ist eine ANZEIGE, kein Knopf - sah aber genauso aus:
   dieselbe Farbe, dieselbe Pillenform, weisse Fettschrift. In der Warteliste
   stand "Brotzeit" direkt neben dem echten "✓ Stimmt", in der Feiertagsliste
   sechs blaue Pillen genau dort, wo darunter die echten Knoepfe sitzen - man
   tippt drauf und es passiert nichts. Also: nur Rahmen, ruhige Schrift.
   "bezahlt" und "offen" (success/danger) bleiben farbig, die sagen etwas aus. */
.badge {
  border-radius: 999px; letter-spacing: 0.04em; padding: 4px 10px;
  background: transparent; border: 1px solid var(--border);
  color: var(--text-secondary); font-weight: 600;
}
.badge.success, .badge.danger { color: #fff; border-color: transparent; }

/* --- Monatskarten -------------------------------------------------------- */
.monatskarte {
  border-top-width: 4px;
  border-radius: 10px;
  transition: transform 0.14s, box-shadow 0.14s;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28);
}
.monatskarte:not(.leer):hover { transform: translateY(-2px); box-shadow: 0 12px 26px rgba(0, 0, 0, 0.4); }
.monatskopf {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0));
}
.monatskopf strong { font-size: 1.35em; letter-spacing: 0.09em; }
.monatskopf .punkt { box-shadow: 0 0 10px var(--monatsfarbe); }
.plantag { font-family: var(--plakat); font-size: 1.05em; letter-spacing: 0.04em; }
.plankoch { font-weight: 500; }

/* --- Auswertung ---------------------------------------------------------- */
.track-tabelle th { text-transform: uppercase; letter-spacing: 0.1em; font-size: 0.78em; }
.track-tabelle .zahl { font-family: var(--plakat); font-size: 1.15em; }
/* Wer dran ist, bekommt zusaetzlich einen Balken links - Farbe allein reicht
   nicht, wenn jemand Rot/Gruen schlecht unterscheidet oder das Blatt s/w druckt. */
.track-tabelle tr.dran td:first-child { box-shadow: inset 3px 0 0 #e8a225; }

/* --- Fenster ------------------------------------------------------------- */
.overlay { backdrop-filter: blur(3px); }
.qr-box {
  border-radius: 12px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.6);
  border-top: 3px solid var(--feuer-rot);
}
.qr-box h3 { font-family: var(--plakat); font-size: 1.7em; letter-spacing: 0.05em; }

/* --- Anmeldeseite -------------------------------------------------------- */
.auth-box {
  border-radius: 14px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
  position: relative;
  overflow: hidden;
}
/* Der Farbverlauf gehoert nur nach OBEN. Mit border-image faerbt er alle vier
   Seiten - links rot, rechts blau -, was wie ein Fehler aussieht. Also als
   eigener Balken. */
.auth-box::before {
  content: '';
  position: absolute; inset: 0 0 auto 0; height: 4px;
  background: linear-gradient(90deg, var(--feuer-rot), var(--bmw-blau));
}
.auth-box h2 { letter-spacing: 0.14em; text-transform: uppercase; font-size: 0.95em; }
.auth-box .wache-gross { letter-spacing: 0.18em; text-transform: uppercase; font-weight: 700; font-size: 0.8em; }

.naechster { border-left-width: 5px; border-radius: 10px; }
.naechster h3 { text-transform: uppercase; letter-spacing: 0.12em; font-size: 0.8em; }
.naechster .gross { font-family: var(--plakat); font-size: 1.9em; letter-spacing: 0.03em; }

/* Auf kleinen Geraeten eine Spur zurueckdrehen, damit nichts umbricht. */
@media (max-width: 600px) {
  .header h1 { font-size: 1.7em; }
  .auth-box h1 { font-size: 2.4em; }
  .section h2, .dashboard h2 { font-size: 1.6em; }
  .stat-card p { font-size: 2em; }
  .monatskopf strong { font-size: 1.15em; }
}

/* Wer im Betriebssystem "Bewegung reduzieren" gesetzt hat, bekommt keine. */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
  .nav button:hover, .small-btn:hover, .stat-card.klickbar:hover,
  .monatskarte:not(.leer):hover, .form button:hover { transform: none; }
}

/* Ehemalige: stehen nur noch in der Auswertung, damit das Jahr vollstaendig
   bleibt - aber deutlich zurueckgenommen, damit man sie nicht fuer aktiv haelt. */
.track-tabelle tr.ehemalig td { opacity: 0.55; font-style: italic; }

/* Rechte-Zeile in der Verwaltung: Zuordnung und die zwei Haken nebeneinander. */
.rechte { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 10px; }
.rechte .feld { flex-direction: row; align-items: center; gap: 6px; }
.haken { display: inline-flex; align-items: center; gap: 6px; font-size: 0.85em; color: var(--text-secondary); cursor: pointer; }
.haken input { width: 16px; height: 16px; accent-color: var(--bmw-blau); }
.haken input:disabled { opacity: 0.5; cursor: default; }

/* Eigene Termine und laufende Anfragen im Plan erkennbar machen. */
.planzeile.meiner { box-shadow: inset 3px 0 0 var(--bmw-blau-hell); }
.planzeile.meiner .plankoch { font-weight: 700; }
.planzeile.inanfrage { background: rgba(232, 162, 37, 0.10); }
.planzeile .marke { color: #e8a225; font-weight: 700; }
.list-item.hervor { border-color: var(--bmw-blau); box-shadow: 0 0 0 1px var(--bmw-blau) inset; }

/* Offene Termine: gestrichelt und blass, damit man auf einen Blick sieht, wo noch
   jemand fehlt - ohne dass sie wie ein Fehler aussehen. */
.planzeile.offen { border-left: 3px dashed var(--text-secondary); }
.planzeile.offen .plankoch { color: var(--text-secondary); font-style: italic; font-weight: 400; }
.mini.uebernehmen {
  background: var(--bmw-blau); border-color: var(--bmw-blau); color: #fff;
  font-weight: 700; padding: 3px 10px; white-space: nowrap;
}
.mini.uebernehmen:hover { background: var(--bmw-blau-hell); color: #fff; }

/* Am Handy nimmt der Knopf so viel Platz weg, dass "noch offen" auf "noch …"
   zusammenschrumpft. Dann lieber umbrechen - Platz ist nach unten genug. */
@media (max-width: 600px) {
  .planzeile { flex-wrap: wrap; }
  .mini.uebernehmen { margin-left: auto; }
}

/* ==========================================================================
   Brotzeitliste
   ========================================================================== */

/* Wer heute holt - die einzige Rolle, die taeglich wechselt, gehoert nach oben. */
.holer {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--bg-hover); border: 1px solid var(--border);
  border-left: 4px solid var(--feuer-rot); border-radius: 8px;
  padding: 12px 14px; margin: 12px 0;
}
.holer .gross { font-family: var(--plakat); font-size: 1.5em; letter-spacing: 0.03em; }
/* Zwei Kaesten untereinander ("Heute holt" / "Kocht heute Abend") - der zweite
   bekommt eine andere Kante, sonst liest man sie als einen Block. */
.holer.kochen { border-left-color: var(--bmw-blau-hell); }

/* Das Austritts-Fenster ist ein Formular, kein Plakat: links ausgerichtet,
   etwas breiter als der QR-Kasten, und die Bloecke bekommen Luft dazwischen. */
.austritt-box { max-width: 520px; text-align: left; }
.austritt-box .feld, .austritt-box .toggle, .austritt-box .meldung { margin: 10px 0; }
/* Ohne das stehen die beiden Haken am Ende in EINER Zeile hintereinander und
   lesen sich wie ein einziger langer Satz - man sieht dann nicht, dass es zwei
   getrennte Entscheidungen sind. */
.austritt-box .toggle { display: flex; align-items: flex-start; gap: 8px; }
.austritt-box .toggle input { margin-top: 3px; flex: none; }
.austritt-block {
  background: var(--bg-hover); border: 1px solid var(--border);
  border-radius: 8px; padding: 12px; margin: 12px 0;
}
.holer-wahl.mitte { justify-content: flex-end; margin-top: 16px; }

/* Die Beitragserinnerung ist eine Einstellung, kein Teil der Buchungsliste -
   also ein eigener Kasten mit Luft drumherum, sonst klebt sie am Knopf
   darueber und liest sich wie dessen Fussnote. */
.beitrag-erinnerung {
  background: var(--bg-hover); border: 1px solid var(--border);
  border-radius: 8px; padding: 14px; margin: 16px 0;
}
.beitrag-erinnerung h4 { margin: 0 0 6px; }

/* Zwei Knoepfe ("überwiesen" / "bar") stehen als EINE Einheit in der Zeile -
   sonst rutscht der zweite beim Umbrechen allein in die naechste Zeile und
   sieht aus, als gehoerte er zur naechsten Person. */
.topfwahl { display: inline-flex; gap: 6px; flex-wrap: nowrap; }

/* Wer holt wie oft: ein Balken je Name. Auf einen Blick soll man sehen, ob es
   gleichmaessig zugeht - Zahlen nebeneinander vergleicht niemand. */
.holer-zeile {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 10px; border-bottom: 1px solid var(--border);
}
.holer-zeile:last-child { border-bottom: none; }
.holer-zeile .name { flex: 0 0 34%; font-weight: 600; }
.holer-zeile .balken {
  flex: 1; height: 10px; background: var(--bg-hover); border-radius: 5px; overflow: hidden;
}
.holer-zeile .balken > span { display: block; height: 100%; background: var(--bmw-blau); }
.holer-zeile .zahl { flex: 0 0 2.5em; text-align: right; font-variant-numeric: tabular-nums; }
.holer-zeile.ruhig { opacity: 0.55; }
@media (max-width: 640px) {
  .holer-zeile { flex-wrap: wrap; }
  .holer-zeile .name { flex: 1 1 60%; }
  .holer-zeile .balken { flex: 1 1 100%; order: 3; }
}
/* "Bezahlt wird an ..." steht unter dem Namen und muss dort auffallen, ohne
   den Namen selbst zu ueberbieten - also eine eigene Zeile mit etwas Luft. */
.holer .geld-an { display: block; margin-top: 6px; color: var(--text-primary); }

.abrechnung { margin: 12px 0; }

.preisgitter { display: flex; flex-wrap: wrap; gap: 10px; margin: 10px 0; }
.preisfeld {
  display: flex; flex-direction: column; gap: 4px;
  background: var(--bg-hover); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px; min-width: 132px;
}
.preisfeld.abend { border-color: var(--feuer-rot); }
.artikelname {
  background: var(--bg-dark); border: 1px solid var(--border); border-radius: 6px;
  color: var(--text-primary); padding: 6px 8px; font-size: 0.85em; font-weight: 700;
  width: 100%; font-family: inherit;
}
.artikelname.fest { border-color: transparent; background: none; padding-left: 0; }
.preiszeile { display: flex; align-items: center; gap: 5px; }
.preiszeile input {
  width: 74px; background: var(--bg-dark); border: 1px solid var(--border);
  border-radius: 6px; color: var(--text-primary); padding: 6px 8px;
  font-family: inherit; font-variant-numeric: tabular-nums;
}

.cards-brotzeit { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; margin-top: 12px; }
.person-karte {
  background: var(--bg-hover); border: 1px solid var(--border); border-radius: 10px;
  padding: 12px; display: flex; flex-direction: column; gap: 10px;
}
/* Wer schon bestellt hat, hebt sich ab - beim Durchgehen sieht man sofort, wer fehlt. */
.person-karte.bestellt { border-color: var(--bmw-blau); box-shadow: inset 3px 0 0 var(--bmw-blau); }
/* Die eigene Karte steht oben und ist rot umrandet - man findet sich sofort. */
.person-karte.ich { border-color: var(--feuer-rot); box-shadow: inset 3px 0 0 var(--feuer-rot); }
.person-karte .karte-kopf strong { font-size: 1.05em; }
.badge.du { background: var(--feuer-rot); color: #fff; border-color: transparent; }

/* ---- Zugeklappte Karte --------------------------------------------------
   Bis 1.68 war jede Karte 652 Pixel hoch, weil sie alle sieben Artikel mit
   Zaehlern zeigte - auch die sechs auf 0. Achtzehn Karten waren fuenfzehn
   Bildschirmlaengen, und wer abrechnen oder abhaken wollte, scrollte daran
   vorbei.

   Zugeklappt ist die Karte eine Zeile: Name, was bestellt wurde, der Betrag.
   Genug, um zu entscheiden, ob man sie ueberhaupt aufmachen muss. */
.person-karte.zu { padding: 8px 12px; gap: 0; }
.person-karte .karte-kopf {
  /* display MUSS hier stehen: .wie-knopf setzt display:block und kommt in der
     Datei spaeter - ohne das ist der Kopf kein Flex-Container mehr, das gap
     greift nicht, und Pfeil und Name kleben aneinander ("▾Allwang"). */
  /* Und justify-content auch: die alte Regel verteilt mit space-between. Ohne
     Kurzfassung (aufgeklappt) stehen dann Pfeil, Name und "Du" gleichmaessig
     verteilt - der Name landet mitten in der Zeile. Links ist richtig; die
     Kurzfassung schiebt sich mit margin-left:auto selbst nach rechts. */
  display: flex; justify-content: flex-start; align-items: center;
  width: 100%; gap: 8px;
  /* Der Kopf ist jetzt ein <button> (damit der Tabulator hinkommt) - der
     bringt eigene Schrift und eigene Ausrichtung mit. */
  font: inherit; color: inherit; text-align: left;
  background: none; border: none; padding: 0; cursor: pointer;
}
.klapp-pfeil { color: var(--text-secondary); font-size: 0.8em; flex: 0 0 auto; }
.karte-gast-weg { align-self: flex-end; margin-top: -28px; }

/* Die Kurzfassung schiebt sich nach rechts und darf umbrechen - "2× Brezen ·
   Leberkaes · Kaesesemmel" passt sonst auf keinem Handy in eine Zeile. */
.karte-kurz {
  margin-left: auto; display: flex; flex-wrap: wrap; justify-content: flex-end;
  align-items: baseline; gap: 4px 8px; font-size: 0.86em;
  color: var(--text-secondary); text-align: right; min-width: 0;
}
.kurz-was { overflow-wrap: anywhere; }
.kurz-essen { color: var(--bmw-blau); }
.kurz-geld { font-variant-numeric: tabular-nums; color: var(--text-primary); }
/* Der offene Betrag ist das Einzige hier, was eine Handlung nach sich zieht -
   also als Einziges farbig. */
.kurz-offen {
  font-variant-numeric: tabular-nums; color: var(--rot-schrift);
  background: rgba(200, 16, 46, 0.14); border-radius: 999px; padding: 1px 8px;
}

/* Was bestellt wurde, wenn sich nichts mehr aendern laesst (abgerechnet,
   gesperrt, kein Netz). Sieben tote Zaehler sagen weniger als diese Zeile. */
.bestellung-fest {
  margin: 0; font-size: 0.92em; color: var(--text-primary);
  background: var(--bg-dark); border-radius: 8px; padding: 8px 10px;
  overflow-wrap: anywhere;
}
.mehr-artikel { align-self: flex-start; }

.brotzeit-filter { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 14px; }
.brotzeit-filter input { flex: 1 1 200px; max-width: 320px; }

.stepper-reihe { display: flex; flex-wrap: wrap; gap: 6px; }
.stepper {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1.5px solid var(--border); border-radius: 999px;
  padding: 3px 4px 3px 11px; background: var(--bg-dark);
}
.stepper.has-qty { background: var(--bmw-blau); border-color: var(--bmw-blau); }
/* Artikel, die es nur heute gibt: gestrichelt, damit man sie nicht mit dem
   festen Sortiment verwechselt. Der Stern dahinter sagt dasselbe ohne Farbe. */
.stepper.heute { border-style: dashed; }
.preisfeld.heute { border-style: dashed; }
.preisfeld .link-btn.klein { font-size: 0.78em; text-decoration: none; text-align: left; padding: 0; }
/* Der Knopf unter dem Sonstiges-Feld: der Weg zum gemeinsamen Zaehler. Als
   richtiger Knopf, nicht als Link - ein unterstrichener Halbsatz mitten in der
   Karte liest sich wie ein Hinweis und wird uebersehen. */
/* Steht nur auf einer leeren Karte und soll dort nicht schreien: derselbe
   zurueckhaltende Ton wie "fuer alle", nur mit etwas Luft nach oben. */
.wie-immer { align-self: flex-start; font-size: 0.85em; margin-top: 4px; }

/* Zwei Quittier-Knoepfe nebeneinander (Brotzeit / Abendessen). */
.bezahlt-reihe { display: flex; flex-wrap: wrap; gap: 6px; }
.bezahlt-reihe .small-btn { flex: 1 1 auto; }

/* --- "Hab bezahlt" ------------------------------------------------------ */
/* Auf der eigenen Karte abgesetzt, damit der Melde-Knopf nicht mit den
   Quittier-Knoepfen des Holers verwechselt wird - die sehen sonst gleich aus,
   machen aber etwas voellig anderes. */
.bezahlt-reihe.eigen { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--border); }
.zahlung-warte {
  flex: 1 1 auto; display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  font-size: 0.9em; color: var(--warn-gelb, #e8a225);
  background: rgba(232, 162, 37, 0.1); border: 1px solid rgba(232, 162, 37, 0.35);
  border-radius: 8px; padding: 7px 10px;
}
.zahlung-warte .link-btn { padding: 0; font-size: 0.95em; }
.warteliste {
  border: 1px solid rgba(232, 162, 37, 0.4); border-left-width: 4px; border-radius: 10px;
  background: rgba(232, 162, 37, 0.08); padding: 12px 16px; margin-bottom: 18px;
}
.warteliste h3 { margin: 0 0 8px; }
.warteliste .betrag { min-width: 5em; text-align: right; }
.beitrag-eigen { flex-wrap: wrap; }
/* Auf dem Handy ist neben Betrag und Stand kein Platz mehr fuer einen Knopf -
   dann bekommt er eine eigene Zeile, statt den Namen zu einer Buchstabensaeule
   zu quetschen. */
.zahlung-abgelehnt {
  flex: 1 1 100%; display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  font-size: 0.9em; color: var(--rot-schrift);
  background: rgba(231, 76, 60, 0.12); border: 1px solid rgba(231, 76, 60, 0.4);
  border-radius: 8px; padding: 7px 10px;
}
.zahlung-abgelehnt .link-btn { padding: 0; font-size: 0.95em; }
.beitrag-eigen .zahlung-warte, .beitrag-eigen .zahlung-abgelehnt, .beitrag-eigen .small-btn { flex: 1 1 100%; }
@media (min-width: 640px) {
  .beitrag-eigen .zahlung-warte, .beitrag-eigen .zahlung-abgelehnt,
  .beitrag-eigen .small-btn { flex: 0 1 auto; }
}

/* Einkaufszettel: gross und mit viel Luft, das wird mit kalten Fingern im
   Laden angetippt. Zahl links, Ware rechts - so liest man eine Liste. */
.qr-box.einkauf { max-width: 520px; }
.einkauf-liste { list-style: none; margin: 12px 0; display: flex; flex-direction: column; }
.einkauf-liste li {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  border-bottom: 1px solid var(--border); font-size: 1.15em;
}
/* Die ganze Zeile ist der Haken - im Laden trifft man mit kalten Fingern kein
   kleines Kaestchen. Der Knopf statt eines onClick auf dem li: so kommt man
   auch mit der Tastatur hin, und ein Gast bekommt ihn ausgegraut statt
   klickbar. */
.einkauf-liste .zeile-haken {
  flex: 1; display: flex; align-items: center; gap: 12px;
  background: none; border: none; color: inherit; font: inherit; text-align: left;
  padding: 12px 6px; cursor: pointer; min-width: 0;
}
.einkauf-liste .zeile-haken:disabled { cursor: default; }
.einkauf-liste li:hover { background: var(--bg-hover); }
.einkauf-liste li.weg { opacity: 0.45; }
.einkauf-liste li.weg .ware { text-decoration: line-through; }
.einkauf-liste .haken { font-size: 1.5em; line-height: 1; }
.einkauf-liste .anzahl { font-family: var(--plakat); font-size: 1.5em; min-width: 2.2em; text-align: right; }
.einkauf-liste .was { min-width: 0; }
.einkauf-liste .was em { color: var(--text-secondary); font-style: normal; font-size: 0.85em; }
/* Der Originaltext eines zerlegten Wunsches und "geholt von ..." - eigene
   Zeile, sonst schiebt es die Ware aus dem Bild. */
.einkauf-liste .was em.herkunft { display: block; font-size: 0.72em; opacity: 0.75; }

/* Das Abteilungs-Menue bekommt eine EIGENE Zeile. Daneben gestellt quetscht es
   die Ware auf eine Spalte von zwei Zentimetern, und dann steht jedes Wort
   einzeln untereinander. */
.einkauf-liste .small-select { flex: 1 0 100%; max-width: none; margin: 0 6px 10px; }

/* Abteilungen: der Laufweg durch den Laden. Die Ueberschrift klebt beim
   Scrollen oben, damit man im Regal stehend noch weiss, wo man ist. */
.abteilung h4 {
  position: sticky; top: 0; z-index: 2;
  margin: 16px 0 0; padding: 8px 6px;
  background: var(--bg-card);
  border-bottom: 2px solid var(--bmw-blau);
  font-size: 0.95em; letter-spacing: .04em; text-transform: uppercase;
}
.abteilung:first-of-type h4 { margin-top: 4px; }
.abteilung .einkauf-liste { margin: 0 0 4px; }

/* Wie weit der Einkauf ist, direkt am Einkaufswagen. */
.small-btn .fortschritt {
  margin-left: 8px; padding: 1px 7px; border-radius: 999px;
  background: rgba(255, 255, 255, .22); font-size: .85em; font-weight: 600;
}
.small-btn.stark { background: var(--bmw-blau); color: #fff; border-color: var(--bmw-blau); }

/* Offene Betraege: rot umrandet, damit man es beim Aufmachen der App sieht,
   aber keine Flaeche - es ist eine Erinnerung, keine Warnung. */
.offen-karte {
  border: 1px solid var(--feuer-rot); border-left-width: 4px; border-radius: 10px;
  background: rgba(200, 16, 46, 0.08); padding: 14px 16px; margin-bottom: 16px;
}
.offen-karte h3 { font-family: var(--plakat); font-size: 1.5em; letter-spacing: 0.03em; margin: 0 0 8px; }
.offen-zeile { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; padding: 4px 0; }
.offen-zeile a { text-decoration: none; }

/* Aushang-Verwaltung */
.aushang {
  border: 1px solid var(--border); border-radius: 10px;
  padding: 14px 16px; margin-bottom: 18px; background: var(--bg-hover);
}
.aushang h3 { margin-top: 0; }
/* --- Der Zettel fuer die Gaeste ------------------------------------------
   Haengt an der Wand der Wache und wird von Leuten gelesen, die die App nicht
   kennen - meistens im Vorbeigehen. Also: eine Sache gross (der Code), drei
   Schritte darunter, und das Kleingedruckte wirklich klein. Was hier am
   Bildschirm steht, ist schon das fertige Blatt; die Druckregeln weiter unten
   rechnen es nur noch in Millimeter um. */
.aushang-zettel { text-align: center; max-width: 480px; }
.aushang-zettel .gross-hinweis { font-family: var(--plakat); font-size: 1.4em; letter-spacing: 0.04em; margin-bottom: 12px; }

.blatt {
  background: #fff; color: #111; border-radius: 10px;
  padding: 22px 26px 26px; border-top: 6px solid var(--feuer-rot);
}
.blatt-kopf {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 10px; flex-wrap: wrap;
  border-bottom: 1px solid #d8d8d8; padding-bottom: 8px; margin-bottom: 16px;
}
.blatt-marke {
  font-family: var(--plakat); letter-spacing: 0.06em; text-transform: uppercase;
  font-size: 1.05em; color: var(--feuer-rot);
}
.blatt-wache {
  font-size: 0.72em; letter-spacing: 0.14em; text-transform: uppercase; color: #666;
}
/* Doppelte Klasse mit Absicht: .section h2 faerbt jede Ueberschrift im
   Abschnitt hell, und der Zettel liegt in einem Abschnitt. Auf weissem Papier
   waere die Ueberschrift damit fast unsichtbar - genau das war sie auch. */
.blatt .blatt-titel {
  font-family: var(--plakat); text-transform: uppercase; letter-spacing: 0.03em;
  font-size: 2.6em; line-height: 1; margin: 0 0 6px; color: #111;
}
.blatt-unter { font-size: 1.05em; color: #444; margin: 0 0 18px; }

/* Der Code ist das Einzige, was von weitem zaehlt. Weisser Grund und ein
   ruhiger Rahmen - manche Kameras tun sich schwer, wenn direkt daneben noch
   etwas Dunkles steht. */
.blatt-qr {
  display: inline-block; padding: 12px; background: #fff;
  border: 2px solid #111; border-radius: 8px;
}
/* Der aeussere .qr bringt Polsterung und Rand mit - hier stoert beides, der
   Rahmen sitzt ja schon an .blatt-qr. Und sein max-width haette den Code auf
   dem Blatt auf ein Drittel der vorgesehenen Groesse eingedampft. */
.blatt-qr .qr { padding: 0; margin: 0; border-radius: 0; }
.blatt-qr .qr svg { display: block; width: 190px; height: 190px; max-width: none; }

.blatt-schritte {
  list-style: none; margin: 18px auto 0; padding: 0; max-width: 320px;
  display: flex; flex-direction: column; gap: 8px; text-align: left;
}
.blatt-schritte li {
  display: flex; align-items: center; gap: 10px;
  font-size: 1.02em; color: #222;
}
.blatt-schritte .nr {
  flex-shrink: 0; width: 26px; height: 26px; border-radius: 50%;
  background: var(--bmw-blau); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-weight: bold; font-size: 0.85em;
}
.blatt-fuss {
  margin: 18px 0 0; padding-top: 12px; border-top: 1px solid #d8d8d8;
  font-size: 0.78em; line-height: 1.5; color: #555;
}

/* Jahresbeitrag: die eigene Zeile fuer alle ohne Kassenrecht. */
.beitrag-eigen {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  border: 1px solid var(--feuer-rot); border-left-width: 4px; border-radius: 10px;
  background: rgba(200, 16, 46, 0.08); padding: 12px 16px; margin-bottom: 16px;
}
.beitrag-eigen.bezahlt { border-color: var(--success); background: rgba(30, 158, 90, 0.1); }
.beitrag-eigen .gross { font-family: var(--plakat); font-size: 1.5em; letter-spacing: 0.03em; }
.beitrag { margin-bottom: 18px; }
.beitrag-liste select {
  padding: 8px 10px; background: var(--bg-dark); border: 1px solid var(--border);
  border-radius: 6px; color: var(--text-primary); font-family: inherit;
}
.beitrag-liste .list-item.erledigt { opacity: 0.65; }
.beitrag-liste .betrag { min-width: 5em; text-align: right; font-weight: 600; }

/* Fusszeile mit der Versionsnummer - klein, grau, aber da. */
/* "Ich hol heute" und die Namensauswahl stehen nebeneinander, auf dem Handy
   untereinander - der Knopf ist der haeufige Fall und steht deshalb zuerst. */
.holer-wahl { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.holer-wahl select {
  padding: 9px 10px; background: var(--bg-dark); border: 1px solid var(--border);
  border-radius: 6px; color: var(--text-primary); font-family: inherit;
  /* Siehe .small-select: mindestens 16px, sonst zoomt iOS hinein. Diese Regel
     ist spezifischer als die allgemeine am Dateiende und wuerde sie sonst
     ueberstimmen - deshalb hier und nicht dort. */
  font-size: max(16px, 0.95em);
}

.fusszeile {
  padding: 14px 20px 24px; text-align: center;
  color: var(--text-secondary); font-size: 0.8em; letter-spacing: 0.04em;
}
.stepper-label { font-size: 0.78em; font-weight: 700; color: var(--text-secondary); white-space: nowrap; }
.stepper.has-qty .stepper-label { color: #fff; }
.step-btn {
  width: 26px; height: 26px; border-radius: 50%; border: none;
  background: var(--bg-hover); color: var(--text-primary);
  font-weight: 700; font-size: 1.05em; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
}
.stepper.has-qty .step-btn { background: #fff; color: var(--bmw-blau-dunkel); }
.step-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.step-count {
  min-width: 1.2em; text-align: center; font-weight: 700;
  font-family: var(--plakat); font-size: 1.1em; color: var(--text-primary);
}
.stepper.has-qty .step-count { color: #fff; }

.sonderwunsch { display: flex; gap: 8px; align-items: center; }
.sonderwunsch > input[type="text"] {
  flex: 1; min-width: 0; background: var(--bg-dark); border: 1px solid var(--border);
  border-radius: 6px; color: var(--text-primary); padding: 8px 10px; font-family: inherit;
}

.person-karte .kosten {
  background: var(--bg-dark); border-radius: 6px; padding: 8px 10px;
  text-align: right; font-weight: 700; color: var(--text-primary);
}
.person-karte .kosten.offen { background: rgba(200, 16, 46, 0.14); color: var(--rot-schrift); }
/* Wer heute nichts hat, bleibt sichtbar (falls doch wer kommt), tritt aber
   zurueck - sonst sucht man zwischen 22 Karten die zehn, um die es geht. */
.person-karte.ruhig { opacity: 0.55; }
.person-karte.ruhig:hover, .person-karte.ruhig:focus-within { opacity: 1; }

/* Durchhak-Liste "Wer isst mit" - gleiche Machart wie der Einkaufszettel. */
.qr-box.esser { max-width: 460px; }
.esser-liste { list-style: none; margin: 12px 0; display: flex; flex-direction: column; }
.esser-liste li {
  display: flex; align-items: center; gap: 12px; cursor: pointer;
  padding: 11px 6px; border-bottom: 1px solid var(--border); font-size: 1.1em;
}
.esser-liste li:hover { background: var(--bg-hover); }
.esser-liste li.dabei { color: var(--text-primary); font-weight: 600; }
.esser-liste li:not(.dabei) { color: var(--text-secondary); }
.esser-liste .haken { font-size: 1.5em; line-height: 1; }

/* Guthaben: gruen statt rot - das ist keine Schuld, sondern das Gegenteil. */
.person-karte .kosten.guthaben { background: rgba(30, 158, 90, 0.16); color: #4fd18b; }
/* Wer heute auslegt, schuldet nichts und hat auch nichts gut - der Kasten
   soll also weder rot noch gruen sein, sondern nur ruhig dastehen. */
.person-karte .kosten.auslage { background: rgba(62, 138, 226, 0.14); color: var(--text-primary); }
.person-karte .kosten .heute {
  display: block; font-size: 0.75em; font-weight: 400; color: var(--text-secondary);
}

/* --- Ausdruck ------------------------------------------------------------
   Auf Papier zaehlt, dass alles auf ein Blatt passt und man mit dem Kuli
   nachtragen kann - deshalb eine schlichte Tabelle statt der Karten. */
.nur-druck { display: none; }
/* Ein Druckbild, das man auch am Bildschirm sehen soll. Die Klasse .nur-druck
   bleibt dran, weil saemtliche @media-print-Regeln darauf zeigen; die zweite
   Klasse hebt nur das Verstecken auf (0,2,0 schlaegt 0,1,0). Am Schirm
   bekommt es einen Blattrahmen, damit erkennbar ist: das IST das Papier. */
.nur-druck.auch-am-schirm {
  display: block;
  background: #fff;
  color: #222;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 18px;
  margin-top: 12px;
  overflow-x: auto;
}
.nur-druck.auch-am-schirm table { width: 100%; border-collapse: collapse; }
.nur-druck.auch-am-schirm th, .nur-druck.auch-am-schirm td {
  border-bottom: 1px solid #e2e6ea; padding: 5px 6px; text-align: left;
}
.nur-druck.auch-am-schirm .betrag { text-align: right; font-variant-numeric: tabular-nums; }
.nur-druck.auch-am-schirm td.leer { color: #999; letter-spacing: 1px; }
.nur-druck.auch-am-schirm tr.summe td { font-weight: bold; background: #f2f6fa; }
/* Die Farbe MUSS hier stehen. ".section h3" setzt sie direkt am Element, und
   eine direkt gesetzte Eigenschaft schlaegt die geerbte - der Titel stand
   sonst hell auf weissem Blatt und war praktisch unsichtbar. Genau derselbe
   Fehler wie 1.20 beim Gaeste-Aushang; im Code sieht man ihn nicht, im
   Screenshot sofort. */
.nur-druck.auch-am-schirm h3,
.nur-druck.auch-am-schirm h4,
.nur-druck.auch-am-schirm p,
.nur-druck.auch-am-schirm strong { color: #222; }
.nur-druck.auch-am-schirm h3 { margin: 0 0 4px; font-size: 1.05rem; }
.nur-druck.auch-am-schirm h4 { margin: 14px 0 4px; font-size: 0.95rem; }
.nur-druck.auch-am-schirm .unterschriften { display: flex; gap: 24px; margin-top: 22px; }
.nur-druck.auch-am-schirm .unterschriften > div { flex: 1; }
.nur-druck.auch-am-schirm .linie {
  display: block; border-bottom: 1px solid #999; height: 22px; margin-bottom: 3px;
}
@media print {
  body { background: #fff !important; color: #000; }
  /* Nicht mit visibility:hidden arbeiten - das laesst den Platz der Bildschirm-
     Ansicht stehen, und aus einer Seite werden vier, davon drei leer. Alles,
     was nicht aufs Blatt soll, kommt deshalb ganz aus dem Layout raus. */
  .header, .nav, .fusszeile { display: none !important; }
  .content { padding: 0; max-width: none; }
  .section { background: none; border: none; padding: 0; margin: 0; box-shadow: none; overflow: visible; }
  /* Der Farbbalken oben auf der Karte ist Bildschirm-Zierrat. Auf Papier war
     er ein rot-blauer Strich quer ueber den Blattrand - und Farbtinte. */
  .section::before { display: none !important; }

  /* Der Normalfall: die Brotzeitliste. Der Druckknopf setzt vorher
     "druck-liste" an den body - und ohne jede Druckklasse gilt sie auch,
     damit Strg+P das Richtige aufs Blatt bringt.
     Hier stand frueher eine Kette aus :not(.druck-qr):not(.druck-einkauf)...
     Die war eine Falle: jeder NEUE Druckmodus, den man zu ergaenzen vergisst,
     faellt in diese Regel - und dann ist alles ausgeblendet ausser .nur-druck,
     das es auf der Seite gar nicht gibt. Ergebnis: ein leeres Blatt. Genau so
     ist der Sammelbogen beim ersten Versuch leer aus dem Drucker gekommen.
     [class*="druck-"] deckt jeden kuenftigen Modus von selbst mit ab. */
  body.druck-liste .section > *:not(.nur-druck),
  body:not([class*="druck-"]) .section > *:not(.nur-druck) { display: none !important; }
  body.druck-liste .nur-druck,
  body:not([class*="druck-"]) .nur-druck { display: block; width: 100%; font-family: Arial, sans-serif; }

  /* Die Einkaufsliste: dasselbe Fenster wie am Bildschirm, nur gross und
     schwarz - der Zettel wandert mit in die Baeckerei. */
  body.druck-einkauf .section > *:not(.abrechnung) { display: none !important; }
  body.druck-einkauf .abrechnung > *:not(.overlay) { display: none !important; }
  body.druck-einkauf .overlay { position: static; background: none; padding: 0; display: block; }
  body.druck-einkauf .qr-box { border: none; box-shadow: none; max-height: none; width: 100%; background: none; overflow: visible; }
  body.druck-einkauf .qr-box, body.druck-einkauf .qr-box * { color: #000 !important; }
  body.druck-einkauf .karte-fuss { display: none !important; }
  /* Quer und zweispaltig: so passt der Zettel auf EIN Blatt, auch wenn 20 Leute
     bestellt haben - man will nicht mit zwei Blaettern in der Baeckerei stehen. */
  /* display:block ist noetig - auf einem Flex-Container wirkt column-count nicht. */
  body.druck-einkauf .qr-box.einkauf { max-width: none; }
  /* Der Zettel laeuft ueber beide Spalten durch, Abteilung fuer Abteilung -
     column-count auf der einzelnen Liste haette jede Abteilung fuer sich
     zweispaltig gesetzt, und dann steht das Obst an vier Stellen. */
  body.druck-einkauf .abteilungen-druck { display: block; column-count: 2; column-gap: 14mm; margin: 4mm 0; }
  body.druck-einkauf .abteilung h4 {
    position: static; background: none; font-size: 12pt; margin: 3mm 0 1mm;
    padding: 0 0 1mm; border-bottom: 1.2pt solid #000; break-after: avoid; break-inside: avoid;
  }
  body.druck-einkauf .abteilung:first-of-type h4 { margin-top: 0; }
  body.druck-einkauf .einkauf-liste { display: block; margin: 0; }
  body.druck-einkauf .einkauf-liste li {
    font-size: 13pt; padding: 0; border-bottom: 1px solid #999; break-inside: avoid;
  }
  body.druck-einkauf .einkauf-liste .zeile-haken { padding: 2mm 1mm; display: flex; }
  /* Auf Papier bleibt auch das Erledigte lesbar: der Zettel ist die
     Gedaechtnisstuetze, nicht das Protokoll. */
  body.druck-einkauf .einkauf-liste li.weg { text-decoration: none; opacity: 1; }
  body.druck-einkauf .einkauf-liste li.weg .ware { text-decoration: none; }
  body.druck-einkauf .einkauf-liste .mini,
  body.druck-einkauf .einkauf-liste .small-select,
  body.druck-einkauf .einkauf-liste em.herkunft { display: none !important; }
  body.druck-einkauf .qr-box h3 { font-size: 15pt; margin-bottom: 2mm; }
  body.druck-einkauf .nur-druck { display: none !important; }
  /* Die Bedienhinweise gehoeren auf den Bildschirm, nicht auf den Zettel -
     auf Papier tippt niemand etwas an. */
  body[class*="druck-"] .nur-bildschirm { display: none !important; }

  /* Der Aushang fuer die Wand: gross, schwarz, ohne Bedienelemente. */
  body.druck-aushang .section > *:not(.aushang) { display: none !important; }
  /* Die Verwaltungs-Box selbst ist nur der Rahmen am Bildschirm - auf Papier
     waere sie ein grosser grauer Kasten. */
  body.druck-aushang .aushang { background: none; border: none; padding: 0; margin: 0; }
  body.druck-aushang .aushang > *:not(.overlay) { display: none !important; }
  body.druck-aushang .overlay { position: static; background: none; padding: 0; display: block; }
  body.druck-aushang .qr-box { border: none; box-shadow: none; max-height: none; width: 100%; background: none; overflow: visible; }
  /* Frueher wurde hier ALLES auf Schwarz gesetzt. Das nimmt dem Blatt genau
     die zwei Farbtupfer, die es lesbar machen - der Balken oben und die
     Schrittziffern. Die Ausnahmen stehen bei den Regeln darunter. */
  body.druck-aushang .qr-box, body.druck-aushang .qr-box * { color: #000; }
  body.druck-aushang .blatt, body.druck-aushang .blatt * {
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  body.druck-aushang .karte-fuss { display: none !important; }

  /* --- Das Wappen auf dem Papier ------------------------------------------
     Am Bildschirm ist es auf den Druckblaettern ausgeblendet (die sieht man
     dort ohnehin nicht), hier kommt es zurueck. In MILLIMETER, nicht Pixel:
     ein Blatt hat feste Masse, und 18 mm sind bei 284 Bildpunkten immer noch
     400 dpi — das druckt jeder Drucker scharf.
     print-color-adjust MUSS dabeistehen, sonst wirft ein Browser im
     Sparmodus das Dunkelblau raus und uebrig bleibt ein weisses Dreieck auf
     weissem Papier. */
  .wappen.im-blatt,
  .wappen.im-balken {
    display: block;
    background: none;
    padding: 0;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .wappen.im-blatt { width: 18mm; margin: 0 0 3mm; }
  /* Im Balken des Gaeste-Aushangs sitzt es neben dem Schriftzug, nicht darueber. */
  .wappen.im-balken {
    display: inline-block; width: 14mm; vertical-align: -4.2mm; margin-right: 3.5mm;
  }
  /* Auf dem Blatt gilt Millimeter, nicht Pixel: ein QR-Code muss aus zwei
     Metern Entfernung noch scannbar sein, und der Rest ordnet sich dem unter. */
  body.druck-aushang .qr-box.aushang-zettel { max-width: none; margin: 0; }
  body.druck-aushang .blatt {
    border-radius: 0; padding: 0; border-top: 4mm solid #c8102e; padding-top: 8mm;
  }
  body.druck-aushang .blatt-kopf { padding-bottom: 4mm; margin-bottom: 8mm; }
  body.druck-aushang .blatt-marke { font-size: 16pt; color: #c8102e !important; }
  body.druck-aushang .blatt-wache { font-size: 10pt; color: #555 !important; }
  body.druck-aushang .blatt-titel { font-size: 40pt; margin-bottom: 3mm; }
  body.druck-aushang .blatt-unter { font-size: 14pt; margin-bottom: 9mm; }
  body.druck-aushang .blatt-qr { padding: 6mm; border-width: 1mm; }
  body.druck-aushang .blatt-qr .qr svg { width: 92mm; height: 92mm; max-width: none; }
  body.druck-aushang .blatt-schritte { margin-top: 10mm; max-width: 115mm; gap: 5mm; }
  body.druck-aushang .blatt-schritte li { font-size: 16pt; gap: 6mm; }
  body.druck-aushang .blatt-schritte .nr {
    width: 10mm; height: 10mm; font-size: 14pt;
    background: #1c69d4 !important; color: #fff !important;
  }
  body.druck-aushang .blatt-fuss { font-size: 10pt; margin-top: 9mm; padding-top: 4mm; }
  body.druck-aushang .hinweis { font-size: 12pt; }
  body.druck-aushang .nur-druck { display: none !important; }

  /* Die Beitragsliste zum Aushaengen. */
  body.druck-beitrag .section > *:not(.beitrag) { display: none !important; }
  body.druck-beitrag .beitrag > *:not(.nur-druck) { display: none !important; }
  body.druck-beitrag .beitrag .nur-druck { display: block !important; width: 100%; font-family: Arial, sans-serif; }

  /* Das Kassenjahr fuer den Ordner: dieselbe schlichte Tabelle. */
  body.druck-kassenjahr .section > *:not(.kassenjahr) { display: none !important; }
  body.druck-kassenjahr .kassenjahr > *:not(.nur-druck) { display: none !important; }
  body.druck-kassenjahr .kassenjahr .nur-druck { display: block !important; width: 100%; font-family: Arial, sans-serif; }
  body.druck-kassenjahr .kassenjahr-druck td { text-align: right; }
  body.druck-kassenjahr .kassenjahr-druck td.name,
  body.druck-kassenjahr .kassenjahr-druck td:nth-child(3) { text-align: left; }
  /* ... aber ein Geldbetrag steht IMMER rechts. In der Summenzeile ist das
     "Aus"-Feld wegen colSpan die dritte Zelle und rutschte sonst nach links. */
  body.druck-kassenjahr .kassenjahr-druck td.betrag { text-align: right; }
  body.druck-kassenjahr .kassenjahr-druck tr.summe td,
  body.druck-kassenjahr .kassenjahr-druck tr.uebertrag td { font-weight: bold; background: #f2f6fa !important; }

  /* Die Kassenuebergabe: ein Blatt fuer den Ordner, mit Feldern zum
     Nachzaehlen und zwei Unterschriften. */
  body.druck-uebergabe .section > *:not(.uebergabe) { display: none !important; }
  body.druck-uebergabe .uebergabe > *:not(.nur-druck) { display: none !important; }
  body.druck-uebergabe .uebergabe .nur-druck { display: block !important; width: 100%; font-family: Arial, sans-serif; }
  body.druck-uebergabe .uebergabe-druck td.betrag,
  body.druck-uebergabe .uebergabe-druck th.betrag { text-align: right; }
  body.druck-uebergabe .uebergabe-druck td.leer { color: #999; letter-spacing: 1px; }
  body.druck-uebergabe .uebergabe-druck tr.summe td { font-weight: bold; background: #f2f6fa !important; }
  body.druck-uebergabe .uebergabe-druck h4 { margin: 14px 0 4px; font-size: 11pt; }
  /* Zwei Unterschriftenfelder nebeneinander, mit genug Luft darueber - eine
     Linie direkt unter dem Text laesst sich nicht unterschreiben. */
  body.druck-uebergabe .unterschriften {
    display: flex; gap: 40px; margin-top: 48px; font-size: 9pt;
  }
  body.druck-uebergabe .unterschriften > div { flex: 1; }
  body.druck-uebergabe .unterschriften .linie {
    display: block; border-top: 1px solid #333; margin-bottom: 4px;
  }

  /* Die Esser-Liste: zum Abhaken mit dem Kuli, falls kein Handy zur Hand ist. */
  body.druck-esser .section > *:not(.abrechnung) { display: none !important; }
  body.druck-esser .abrechnung > *:not(.overlay) { display: none !important; }
  body.druck-esser .overlay { position: static; background: none; padding: 0; display: block; }
  /* overflow-y: auto steht am .qr-box fuers Handy (sonst rutscht der
     Schliessen-Knopf aus dem Bild). Beim Drucken macht es den Kasten zu einem
     Block, den der Browser nicht auf zwei Seiten aufteilen kann - die Liste
     rutschte deshalb komplett auf Seite 2 und Seite 1 war fast leer. */
  /* max-width: none nicht vergessen - .qr-box.esser ist am Bildschirm auf
     460 px begrenzt, und mit dieser Begrenzung quetschte sich die Liste auf dem
     Querformat in die linke Haelfte, waehrend die Namen umbrachen
     ("Praktikant / Jonas / (Gast)"). */
  body.druck-esser .qr-box {
    border: none; box-shadow: none; max-height: none; width: 100%; max-width: none;
    background: none; overflow: visible;
  }
  body.druck-esser .qr-box, body.druck-esser .qr-box * { color: #000 !important; }
  body.druck-esser .karte-fuss, body.druck-esser .form { display: none !important; }
  /* Quer ist Platz fuer drei Spalten - mit zweien blieb die rechte Haelfte des
     Blattes leer und die Liste brauchte trotzdem zwei Seiten. */
  body.druck-esser .esser-liste { display: block; column-count: 3; column-gap: 10mm; }
  body.druck-esser .esser-liste li { font-size: 13pt; padding: 2mm 1mm; border-bottom: 1px solid #999; break-inside: avoid; }
  body.druck-esser .nur-druck { display: none !important; }

  /* Die QR-Zettel - einzeln (druck-qr) und als Sammelbogen (druck-bogen).
     Beide zeigen dieselben .qr-karte-Kaertchen; nur die kommen aufs Blatt,
     alles andere aus dem Fenster (Ueberschrift, Erklaerungen, Knoepfe) bleibt
     am Bildschirm. Frueher wurde das Bildschirm-Fenster selbst gedruckt -
     daher der riesige Code und der halbe Text auf dem Blatt. */
  body.druck-qr .section > *:not(.overlay),
  body.druck-bogen .section > *:not(.overlay) { display: none !important; }
  body.druck-qr .overlay,
  body.druck-bogen .overlay { position: static; background: none; padding: 0; display: block; }
  body.druck-qr .qr-box,
  body.druck-bogen .qr-box {
    border: none; box-shadow: none; max-height: none; max-width: none;
    width: 100%; background: none; margin: 0; padding: 0; overflow: visible;
  }
  /* Nur der Bogen kommt aufs Papier. */
  body.druck-qr .qr-box > *:not(.qr-bogen),
  body.druck-bogen .qr-box > *:not(.qr-bogen) { display: none !important; }
  body.druck-qr .nur-druck,
  body.druck-bogen .nur-druck { display: none !important; }
  body.druck-qr .qr-bogen,
  body.druck-bogen .qr-bogen {
    display: grid !important;
    /* Zwei Spalten mal drei Reihen = sechs Karten auf ein A4 hochkant. */
    grid-template-columns: 1fr 1fr;
    grid-auto-rows: 88mm;
    gap: 0;
  }
  body.druck-qr .qr-karte,
  body.druck-bogen .qr-karte {
    /* Gestrichelt, damit man weiss, wo die Schere hin soll. */
    border: 1px dashed #999;
    padding: 5mm 4mm;
    display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
    text-align: center;
    break-inside: avoid; page-break-inside: avoid;
    color: #000 !important;
    background: none;
  }
  body.druck-qr .qr-karte *,
  body.druck-bogen .qr-karte * { color: #000 !important; background: none; }
  /* Der Name gehoert GANZ nach oben und muss von weitem lesbar sein - danach
     sucht man im Stapel. */
  body.druck-qr .qr-karte-name,
  body.druck-bogen .qr-karte-name {
    font-family: Arial, sans-serif; font-size: 15pt; font-weight: bold;
    letter-spacing: 0.02em; margin: 0 0 3mm; line-height: 1.1;
  }
  body.druck-qr .qr-karte .qr,
  body.druck-bogen .qr-karte .qr {
    padding: 0; margin: 0 0 3mm; background: #fff;
  }
  /* 45 mm ist gross genug, dass jedes Handy ihn aus 20 cm liest, und klein
     genug fuer sechs Stueck auf dem Blatt. */
  body.druck-qr .qr-karte .qr svg,
  body.druck-bogen .qr-karte .qr svg { width: 45mm; height: 45mm; max-width: 45mm; display: block; }
  body.druck-qr .qr-karte-fuss,
  body.druck-bogen .qr-karte-fuss {
    font-family: Arial, sans-serif; font-size: 7.5pt; line-height: 1.35; margin-top: auto;
  }
  body.druck-qr .qr-karte-wache,
  body.druck-bogen .qr-karte-wache {
    display: block; margin-top: 1.5mm; font-size: 6.5pt; letter-spacing: 0.06em; text-transform: uppercase;
  }
  /* Die Bildschirmfarben sind hell auf dunkel - auf Papier waere das fast
     unsichtbar. Darum wird hier alles hart auf Schwarz gesetzt. */
  .nur-druck, .nur-druck * { color: #000 !important; background: transparent; }

  /* Auf dem Ausdruck darf kein Element eine dunkle Flaeche haben, nur weil die
     Maus zufaellig darueber stand: in der Esserliste war ein Name schwarz
     hinterlegt mit weisser Schrift - auf Papier sieht das aus wie geschwaerzt.
     Ausgenommen bleibt, was Farbe TRAGEN soll (Tabellenkoepfe, der Zettel). */
  body[class*="druck-"] *:hover { background: none; }
  body[class*="druck-"] .esser-liste li,
  body[class*="druck-"] .einkauf-liste li { background: none !important; color: #000 !important; }
  .nur-druck h3 { font-size: 14pt; margin: 0 0 4mm; }
  /* table-layout: fixed ist hier kein Feinschliff, sondern Pflicht: mit dem
     Standard "auto" macht sich eine Tabelle so breit, wie ihr Inhalt es
     verlangt - und lief bei der Beitragsliste und beim Kassenjahr RECHTS UEBER
     DEN BLATTRAND hinaus. Die Spalte "bezahlt" fehlte auf dem Ausdruck einfach.
     Am Bildschirm sieht man davon nichts. */
  .nur-druck table {
    width: 100%; max-width: 100%;
    border-collapse: collapse; font-size: 9pt;
  }
  /* "fest" heisst: die Spaltenbreiten stehen in der colgroup und die Tabelle
     haelt sich daran. Ohne das macht sie sich so breit, wie der Inhalt es
     verlangt, und laeuft rechts vom Blatt. NUR fuer Tabellen mit colgroup:
     ohne Breitenangaben macht "fixed" alle Spalten gleich breit, und in der
     Brotzeitliste wurde die Namensspalte damit so schmal wie die Zaehlspalten -
     jeder Name brach um und die Liste brauchte plotzlich zwei Blaetter. */
  .nur-druck table.fest { table-layout: fixed; }
  .nur-druck th, .nur-druck td {
    border: 1px solid #333; padding: 3px 5px; text-align: center;
    overflow-wrap: anywhere;   /* ein langer Name sprengt die Spalte sonst wieder */
  }
  /* Geldbetraege nie umbrechen - "€ 10,20" auf zwei Zeilen liest sich wie zwei
     Zahlen. Lieber die Spalte etwas breiter. */
  .nur-druck td.betrag, .nur-druck th.betrag { white-space: nowrap; }

  /* Zwei Millimeter Luft rechts. Eine Tabelle mit width: 100% endet sonst GENAU
     auf der Randlinie - die rechte Rahmenlinie faellt dann aus dem druckbaren
     Bereich, und die letzte Spalte sieht abgeschnitten aus. Bei einem Drucker
     mit groesserem Rand waere sie es wirklich. */
  .nur-druck { padding-right: 2mm; }

  /* Die Brotzeitliste soll auf EIN Blatt. Mit 22 Namen plus Gaesten rutschten
     zuletzt zwei Zeilen auf Seite 2 - fuer zwei Zeilen ein zweites Blatt, das
     man am Klemmbrett prompt verliert. Enger gesetzt passen rund 30 Zeilen.
     Wird es doch laenger, wiederholt sich der Tabellenkopf auf jeder Seite. */
  body.druck-liste .nur-druck table,
  body:not([class*="druck-"]) .nur-druck table { font-size: 8.5pt; }
  body.druck-liste .nur-druck td,
  body:not([class*="druck-"]) .nur-druck td { padding: 2px 4px; }
  body.druck-liste .nur-druck thead,
  body:not([class*="druck-"]) .nur-druck thead { display: table-header-group; }
  body.druck-liste .nur-druck tr,
  body:not([class*="druck-"]) .nur-druck tr { break-inside: avoid; }
  .nur-druck th { background: #e8eef5 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .nur-druck td.name { text-align: left; font-weight: bold; }
  .nur-druck p { font-size: 8pt; margin: 3mm 0 0; }
  /* Hochkant ist die Vorgabe. Vorher stand hier pauschal "landscape" - damit
     kam auch ein QR-Zettel quer aus dem Drucker und war unnoetig gross.
     Quer braucht nur, was wirklich breit ist: der Einkaufszettel, die
     Esserliste und die Brotzeit-Tabelle. Das geht mit benannten Seiten. Kann
     ein Browser die nicht, bleibt alles hochkant - der harmlosere Fehler: ein
     QR-Zettel passt immer, eine Tabelle wird nur enger. */
  @page { size: portrait; margin: 10mm; }
  @page quer { size: landscape; margin: 10mm; }
  body.druck-liste, body.druck-einkauf, body.druck-esser,
  body:not([class*="druck-"]) { page: quer; }
}

@media (max-width: 600px) {
  .holer { flex-direction: column; align-items: flex-start; }
  .cards-brotzeit { grid-template-columns: 1fr; }
}

/* --- Schichttage ---------------------------------------------------------
   Die Wachgruppe hat nicht jeden Tag Dienst. Ist das eingerichtet, faerbt es
   den Kochplan, die Brotzeit und die Uebersicht. */
.schicht-einrichtung { margin: 18px 0; }
.schicht-einrichtung > h3 { margin-bottom: 4px; }
.schicht-einrichtung h4 { margin: 14px 0 6px; font-size: 0.95em; }

/* Die Tage im Zyklus zum Anklicken - ein Raster, das auch bei 30 Tagen noch
   aufs Handy passt. */
.zyklus-tage { display: flex; flex-wrap: wrap; gap: 5px; margin: 8px 0 12px; }
.zyklus-tag {
  width: 38px; height: 38px; border-radius: 8px; cursor: pointer;
  background: var(--bg-dark); border: 1px solid var(--border); color: var(--text-secondary);
  font-weight: bold; transition: transform 0.1s, background 0.15s;
}
.zyklus-tag:hover { transform: translateY(-1px); }
.zyklus-tag.dienst { background: var(--feuer-rot); border-color: var(--feuer-rot); color: #fff; }

/* Die Vorschau ist der eigentliche Beweis: sechs Wochen so, wie die App sie
   danach behandelt. Wer das mit dem Dienstplan vergleicht, sieht sofort, ob
   das Muster stimmt. */
.schicht-vorschau {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px;
  max-width: 340px; margin: 6px 0 12px;
}
.schicht-vorschau .kopf { text-align: center; font-size: 0.7em; color: var(--text-secondary); padding-bottom: 2px; }
.schicht-vorschau .vt {
  aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
  border-radius: 5px; font-size: 0.75em;
  background: var(--bg-dark); border: 1px solid var(--border); color: var(--text-secondary);
}
.schicht-vorschau .vt.dienst {
  background: rgba(214, 40, 40, 0.22); border-color: var(--feuer-rot); color: var(--text-primary); font-weight: bold;
}

/* Ein Kochtermin an einem dienstfreien Tag - das faellt sonst erst auf, wenn
   keiner kocht. */
.planzeile.kein-dienst { opacity: 0.75; }
.planzeile.kein-dienst .plantag { color: var(--feuer-rot); }
.marke.warn { color: var(--feuer-rot); }

/* "An dem Tag hat die Wachgruppe keinen Dienst" - ein Hinweis, keine Sperre:
   eintragen kann man trotzdem, falls doch jemand da ist. */
.meldung.frei {
  background: var(--bg-dark); border-left: 3px solid var(--text-secondary); color: var(--text-secondary);
}
.meldung.frei .link-btn { margin-left: 8px; }

.naechster.dienst { border-left: 3px solid var(--feuer-rot); }
.naechster.dienst.ich { border-left-color: var(--bmw-blau); }
.schicht-vorschau .vt { position: relative; }
.schicht-vorschau .vt .monat {
  position: absolute; top: -1px; left: 0; right: 0;
  font-size: 0.55em; letter-spacing: 0.04em; opacity: 0.75;
}
.schicht-vorschau .vt:has(.monat) { padding-top: 6px; }

/* --- Feiertage -----------------------------------------------------------
   Dieselbe Sache wie das Wochenende: einer kocht den ganzen Tag. */
.marke.fest { color: var(--warn-gelb, #e8a225); }
.planzeile.feiertag .plantag { color: var(--warn-gelb, #e8a225); }
.meldung.gut.feiertag { font-weight: bold; }
.feiertagsliste { margin: 8px 0 4px; }
.feiertagsliste .list-item { padding: 7px 10px; }

/* --- Kassenjahr und Jahreswahl ------------------------------------------- */
.kassenjahr { margin: 16px 0; }
.jahreswahl { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 8px 0 10px; }
.hinweis.klein.gut { color: var(--erfolg-gruen, #2d8a4e); }


/* ==========================================================================
   Handy: Daumen statt Mauszeiger
   ==========================================================================
   Die Wache tippt das um 6:45 mit einer Hand, oft im Halbschlaf. Was hier
   steht, kommt bewusst ganz am Ende der Datei: bei gleicher Spezifitaet
   gewinnt die letzte Regel, und weiter oben stehen aeltere Handy-Regeln, die
   sonst wirkungslos waeren. */
@media (max-width: 768px) {
  /* Kopf und Reiterleiste klebten mit zwei fest eingetragenen Abstaenden
     uebereinander (top: 0 und top: 85px). Am Handy ist der Kopf aber 117px
     hoch - die Reiter verschwanden also zur Haelfte dahinter und ueberdeckten
     nebenbei den Inhalt. Am Handy scrollt beides einfach mit: dann ist immer
     zu sehen, worauf man tippt. */
  .header { position: static; }
  .nav { position: static; }

  /* Von sieben Reitern waren drei rechts abgeschnitten, ohne dass irgendetwas
     darauf hinwies - "Kaffeekasse", "Mein Zugang" und "Verwaltung" gab es fuer
     den Benutzer schlicht nicht. Umbrechen statt seitwaerts schieben. */
  .nav { flex-wrap: wrap; overflow-x: visible; }
  .nav button { padding: 10px 14px; min-height: 44px; font-size: 0.92em; }

  /* 44 px ist die Groesse, die ein Daumen zuverlaessig trifft. Die +/- Knoepfe
     waren 26 px bei 6 px Abstand - und das ist der meistgetippte Knopf der
     ganzen App, bei dem ein Fehltipp Geld kostet. */
  .step-btn { width: 40px; height: 40px; font-size: 1.2em; }
  .stepper { min-height: 46px; }
  .stepper-reihe { gap: 10px; }
  .small-btn { min-height: 44px; }
  .mini { min-width: 40px; min-height: 40px; padding: 6px 10px; font-size: 1em; }
  .bezahlt-reihe { gap: 10px; }

  /* "Isst mit" hatte gar keine eigene Regel und bekam den Browser-Standard:
     16-px-Kaestchen, ohne Abstand an den Text geklebt, Zeile knapp 24 px hoch.
     Fuer die meisten ist das der einzige Tipp des Tages. */
  .toggle { display: flex; align-items: flex-start; gap: 10px; padding: 10px 0; min-height: 44px; }
  .toggle input[type="checkbox"] { width: 22px; height: 22px; flex-shrink: 0; margin: 0; }

  /* Ausgegraute Karten wurden nur beim Ueberfahren mit der Maus wieder hell -
     am Handy also nie. Der graue Text darin lag bei 2,6:1. */
  .person-karte.ruhig { opacity: 0.8; }

  /* In einer Zeile aus Betrag + Text + Knoepfen bleibt bei 430 px fuer den Text
     eine Buchstabensaeule uebrig ("2 Pfund / Kaffee / und / Filter"), und in der
     Einzahlungsliste schob sich die gruene Marke ueber den Namen. Der Text
     bekommt deshalb die ganze Breite, die Knoepfe ruecken darunter. */
  .list-item.zeile { row-gap: 8px; }
  .list-item.zeile > .wachsend { flex: 1 1 100%; min-width: 100%; }
  .list-item.zeile > .zelle-aktionen { margin-left: auto; }
  .list-item.zeile > .badge { flex-shrink: 0; }
}

/* Der native Dateiknopf ist 19 px hoch und heisst auf Englisch "Choose File" -
   das kleinste Ziel der App, mitten in einer deutschen Oberflaeche. Das echte
   Feld bleibt bedienbar, bekommt aber die Groesse des Kastens drumherum. */
.stern-legende { margin: 2px 0 6px; opacity: 0.75; }

/* --- Fusszeile und "Was wird gespeichert?" -------------------------------- */
.fuss-recht {
  display: block; margin-top: 4px; opacity: 0.8;
  display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; align-items: center;
}
.fuss-recht .link-btn { padding: 0; font-size: 1em; }

/* Der Text ist zum LESEN da, nicht zum Ueberfliegen: linksbuendig statt
   mittig wie der Rest der Fenster, und mit Luft zwischen den Absaetzen. */
.qr-box.datenschutz { text-align: left; max-width: 640px; }
.qr-box.datenschutz h3 { text-align: left; }
.qr-box.datenschutz h4 {
  margin: 18px 0 6px; font-size: 1em; color: var(--text-primary);
  letter-spacing: 0.02em;
}
.ds-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.ds-liste li {
  font-size: 0.9em; color: var(--text-secondary); line-height: 1.5;
  padding-left: 16px; position: relative;
}
.ds-liste li::before { content: '·'; position: absolute; left: 4px; color: var(--feuer-rot); font-weight: bold; }
.ds-liste li strong { color: var(--text-primary); }
.ds-fuss { margin-top: 20px; padding-top: 12px; border-top: 1px solid var(--border); }

/* Die eigene Datenauskunft. Sie kann lang werden - deshalb ein eigener
   Scrollbereich, sonst waechst das Fenster ueber den Schirm hinaus und der
   Schliessen-Knopf ist nicht mehr erreichbar. */
.meine-daten { margin-top: 20px; padding-top: 12px; border-top: 1px solid var(--border); }
.daten-block { margin: 12px 0; }
.daten-block > strong { display: block; font-size: 0.92em; color: var(--text-primary); margin-bottom: 4px; }
.daten-zeile {
  list-style: none; margin: 0 0 8px; padding: 8px 10px;
  background: var(--bg-dark); border: 1px solid var(--border); border-radius: 6px;
  display: flex; flex-direction: column; gap: 2px;
  font-size: 0.84em; color: var(--text-secondary); overflow-wrap: anywhere;
}
.daten-feld { color: var(--text-primary); font-weight: 600; margin-right: 4px; }

.feld input[type="file"] {
  width: 100%; padding: 12px; min-height: 48px;
  background: var(--bg-dark); border: 1px dashed var(--border);
  border-radius: 8px; color: var(--text-secondary); cursor: pointer;
}
.feld input[type="file"]::file-selector-button {
  padding: 10px 14px; margin-right: 12px; min-height: 40px;
  background: var(--bg-hover); border: 1px solid var(--border);
  border-radius: 6px; color: var(--text-primary); font-family: inherit; cursor: pointer;
}

/* --- Datei aussuchen ------------------------------------------------------
   Der Knopf des Browsers heisst "Choose File / No file chosen" und laesst sich
   nicht umbenennen. Er liegt deshalb unsichtbar unter unserem eigenen Knopf -
   unsichtbar, aber weiterhin mit der Tastatur erreichbar, sonst kaeme man ohne
   Maus nicht mehr ran. */
.datei-feld { cursor: pointer; }
.datei-reihe {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 6px; position: relative;
}
.datei-reihe input[type="file"] {
  position: absolute; width: 1px; height: 1px; opacity: 0; padding: 0; margin: 0;
}
.datei-taste {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  background: var(--karte, #202a36); color: var(--text, #eef3f8);
  border: 1px solid var(--rand, #2f3d4d); border-radius: 999px;
  padding: 10px 16px; font-weight: 600; font-size: 0.9rem; line-height: 1;
  min-height: 44px; box-sizing: border-box;
  transition: background .15s ease, border-color .15s ease;
}
.datei-reihe:hover .datei-taste { background: var(--karte-hell, #2a3543); }
.datei-reihe:focus-within .datei-taste { outline: 2px solid var(--blau, #1c69d4); outline-offset: 2px; }
.datei-name {
  font-size: 0.85rem; color: var(--grau, #8c9bab);
  overflow-wrap: anywhere; min-width: 0;
}
.datei-reihe.hat .datei-name { color: var(--gut, #35a85b); font-weight: 600; }

/* --- "Es gibt eine neuere Fassung" ----------------------------------------
   Unten quer, ueber allem, aber ohne die Seite zu verschieben. Laedt bewusst
   nicht von selbst neu: mitten im Bestellen waere das eine Frechheit. */
.neue-fassung {
  /* Ueber der Reiterleiste, nicht darunter: am Handy klebt die unten fest,
     und eine Meldung, die halb dahinter liegt, liest keiner. */
  position: fixed; left: 0; right: 0; bottom: var(--leiste-hoehe, 0px); z-index: 900;
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 12px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
  background: var(--blau, #1c69d4); color: #fff;
  box-shadow: 0 -4px 18px rgba(0, 0, 0, .35);
  font-size: 0.95rem;
  animation: fassung-rein .35s ease-out;
}
/* Steht die Leiste darunter, haelt SIE den Rand des Handys frei - sonst
   klafft hier ein zweites Mal derselbe Abstand. */
@media (max-width: 768px) {
  .app.mit-leiste .neue-fassung { padding-bottom: 12px; }
}
.neue-fassung .small-btn { background: #fff; color: var(--blau, #1c69d4); border: none; }
.neue-fassung .small-btn:hover { background: #e8eef6; }
@keyframes fassung-rein { from { transform: translateY(100%); } }
@media (prefers-reduced-motion: reduce) { .neue-fassung { animation: none; } }

/* --- Code fuer ein weiteres Geraet ---------------------------------------- */
.zweitcode {
  background: var(--karte, #1a222c); border: 1px solid var(--rand, #2a3644);
  border-radius: 12px; padding: 16px; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
}
.zweitcode-code {
  font-family: 'Bebas Neue', 'Arial Narrow', sans-serif;
  font-size: clamp(2rem, 11vw, 3rem); letter-spacing: 0.18em;
  margin: 0; color: var(--blau-hell, #3e8bf2);
  /* Abtippen vom anderen Handy: Ziffern gleich breit, damit nichts springt. */
  font-variant-numeric: tabular-nums;
}
.zweitcode .qr { max-width: 200px; }

/* --- "Als Naechstes - und keiner kocht" -----------------------------------
   Bis 1.25 hat die Uebersicht offene Termine stillschweigend uebersprungen und
   den naechsten MIT Namen gezeigt. Jetzt steht der offene da - und faellt auf,
   denn genau der ist der dringende. Kein Blinken: ein roter Rand, ein roter
   Grund und der fehlende Name in Rot reichen. */
.naechster.dringend {
  border-color: var(--feuer-rot);
  border-left-width: 5px;
  background: color-mix(in srgb, var(--feuer-rot) 9%, var(--bg-card));
}
.naechster.dringend h3 { color: var(--feuer-rot); }
.naechster.dringend .fehlt {
  color: var(--feuer-rot);
  font-style: italic;
}
/* Aeltere Browser ohne color-mix bekommen wenigstens den Rand. */
@supports not (background: color-mix(in srgb, red 9%, blue)) {
  .naechster.dringend { background: var(--bg-card); }
}

/* --- Die zwei Toepfe der Kasse -------------------------------------------
   Im Kassenbuch der Wache stehen PayPal und Kassette nebeneinander. Die Summe
   gross, die beiden Toepfe darunter - sonst rechnet jeder selber nach, ob das
   zusammenpasst. */
.kassenstand .toepfe {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 22px;
  margin: 6px 0 4px;
  font-size: 0.9rem; color: var(--text-secondary);
}
.kassenstand .toepfe b {
  color: var(--text-primary); font-variant-numeric: tabular-nums;
}

/* --- Der PayPal-Empfaenger unter der Liste -------------------------------
   Bis 1.27 stand der Name als Text da und musste abgetippt werden. */
.paypal-zeile { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 18px; }
.paypal-ziel { display: inline-flex; align-items: center; gap: 8px; }

/* --- Der Name im Kochplan wird nicht mehr abgeschnitten -------------------
   Auf dem Handy stehen zwei Monatskarten nebeneinander, also gut 200 px je
   Karte. Darin: Tag, Name und der Knopf "Ich koche". Weil .plankoch auf
   min-width: 0 stand, schrumpfte der Name auf "n…", statt dass der Knopf
   umbricht - genau falsch herum. Mit einer Mindestbreite bleibt der Name
   lesbar und der Knopf rutscht in die naechste Zeile. */
@media (max-width: 600px) {
  .planzeile .plankoch { min-width: 9ch; }
}
/* Unter 430 px ist nebeneinander nichts mehr zu lesen - dann untereinander. */
@media (max-width: 430px) {
  .monatsraster { grid-template-columns: 1fr; }
  .planzeile .plankoch { min-width: 0; }
}

/* --- Beitragsstufen: Erklaerung und halbe Jahre --------------------------- */
.stufentext {
  width: 100%; margin-top: 6px; resize: vertical;
  background: var(--bg-dark); color: var(--text-primary);
  border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 10px; font-family: inherit; font-size: 0.85rem; line-height: 1.45;
}
.stufentext:focus { outline: 2px solid var(--bmw-blau); outline-offset: 1px; }
.monatswahl { flex: none; font-size: 0.85rem; padding: 6px 8px; min-width: 6.5em; }

/* Die Beitragszeile traegt viel: Name, Stufe ("Viel Kaffee (96,00 € ·
   8,00/Mon.)"), Monate, Betrag und den Knopf. In EINER Reihe passt das auf
   kein Handy - die Zeile lief rechts aus dem Bild, und der Knopf war nicht
   mehr erreichbar. ".list-item.zeile" erzwingt row ohne Umbruch, deshalb wird
   das hier ausdruecklich aufgehoben. */
.beitrag-liste .list-item.zeile { flex-wrap: wrap; }
.beitrag-liste .list-item.zeile > select { min-width: 0; }
@media (max-width: 560px) {
  .beitrag-liste .list-item.zeile { align-items: flex-start; row-gap: 6px; }
  /* Der Name bekommt die ganze erste Zeile, darunter die Bedienelemente. */
  .beitrag-liste .list-item.zeile > strong.wachsend { flex: 1 0 100%; }
  .beitrag-liste .list-item.zeile > select:not(.monatswahl) { flex: 1 1 100%; }
  .beitrag-liste .list-item.zeile > .betrag { margin-left: auto; }
}

/* --- Gaeste, die noch offen sind ------------------------------------------
   Steht bei der Brotzeit, wo der Holer sowieso hinschaut. Roter Rand, weil es
   um Geld geht, das noch aussteht - aber ohne Flaeche: das ist kein Alarm. */
.gaeste-offen {
  margin-top: 18px; padding: 14px 16px;
  background: var(--bg-card); border: 1px solid var(--border);
  border-left: 4px solid var(--feuer-rot); border-radius: 8px;
}
.gaeste-offen h3 { margin: 0 0 4px; font-size: 1em; }
.gaeste-offen .list { margin-top: 10px; }

/* --- Jahresabschluss und Protokoll --------------------------------------- */
.abschluss { margin: 14px 0; display: flex; flex-direction: column; gap: 10px; }
.abschluss h4 { margin: 6px 0 0; font-size: 0.95em; }
.abschluss .protokoll .list-item { display: block; }
/* Die innere Zeile braucht ihr flex zurueck - sonst klebt der Name am Wort. */
.abschluss .protokoll .zeile {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
}

/* --- Spielwiese ------------------------------------------------------------
   Zwei Fenster nebeneinander sehen sonst gleich aus - und dann tippt man
   Testbuchungen in die echte Kasse. Das Band laeuft im normalen Fluss ganz
   oben (beim Aufmachen sieht man es also immer), und zusaetzlich bekommt die
   Kopfleiste ein Warnband statt des BMW-Verlaufs: das bleibt auch beim
   Scrollen sichtbar. */
.spielwiese-band {
  background: repeating-linear-gradient(45deg, #e8a33d 0 14px, #1b1b1b 14px 28px);
  color: #fff;
  text-align: center;
  font-weight: 700;
  letter-spacing: .04em;
  padding: 9px 16px;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .9), 0 0 10px rgba(0, 0, 0, .8);
}
body.spielwiese .header {
  border-image: repeating-linear-gradient(45deg, #e8a33d 0 12px, #1b1b1b 12px 24px) 1;
}

/* --- Unterreiter in der Verwaltung -----------------------------------------
   Die Verwaltung war eine lange Rolle. Jetzt liegt alles Verwaltende hier,
   aber hinter kleinen Reitern - flacher als die Hauptleiste oben, damit man
   die beiden nicht verwechselt. */
.unterreiter {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 4px 0 18px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.unterreiter button {
  background: var(--bg-hover);
  border: 1px solid var(--border);
  color: var(--text-primary);
  padding: 7px 12px;
  border-radius: 999px;
  cursor: pointer;
  font-size: .9rem;
  white-space: nowrap;
}
.unterreiter button:hover { border-color: var(--bmw-blau); }
.unterreiter button.active {
  background: var(--bmw-blau);
  border-color: var(--bmw-blau);
  color: #fff;
  font-weight: 600;
}

/* Zwei Absaetze hintereinander klebten aneinander und lasen sich wie einer -
   im Datenschutzfenster faellt das am meisten auf, weil dort viel Text steht. */
.datenschutz p.hinweis + p.hinweis { margin-top: 12px; }

/* Ein Emoji ist ein Zeichen - das Feld daneben braucht keine halbe Zeile. */
.emoji-feld { max-width: 4.5em; text-align: center; font-size: 1.2em; }

/* Damit ▲ ▼ Name ✕ in EINE Zeile passen - sonst rutscht das Loeschkreuz auf
   eine eigene und sieht aus, als gehoere es zur naechsten Abteilung. */
.abteilung-name { max-width: 8.5em; }

/* Schwebende Meldung: die Brotzeitseite ist mit 22 Karten laenger als jeder
   Bildschirm - wer unten etwas eintippt, saehe eine Meldung am Seitenanfang
   nie. Unter der Fassungsleiste (z-index 900), damit die bei einem Deploy
   weiterhin gewinnt. */
.meldung.schwebend {
  position: fixed; left: 12px; right: 12px; z-index: 880;
  bottom: calc(var(--leiste-hoehe, 0px) + 12px);
  margin: 0 auto; max-width: 560px;
  padding: 14px 16px calc(14px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 6px 24px rgba(0, 0, 0, .45);
  cursor: pointer;
  animation: meldung-rein .25s ease-out;
}
/* Deckend, nicht durchscheinend: darunter liegt die Liste, und durch eine
   halbtransparente Flaeche liest sich kein Satz. */
.meldung.schwebend.gut { background: #123524; }
.meldung.schwebend.fehler { background: #3a1513; }
@keyframes meldung-rein { from { transform: translateY(60%); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .meldung.schwebend { animation: none; } }
/* Auf dem Blatt hat eine Bildschirmmeldung nichts verloren. */
@media print { .meldung.schwebend { display: none !important; } }

/* Der Nebenweg an einem dienstfreien Tag. Sichtbar, aber nicht so laut wie
   "Zum nächsten Diensttag" - das ist fast immer das, was man will. */
.meldung.frei .link-btn.leise {
  color: var(--text-secondary); font-size: .9em; font-weight: normal; text-decoration: none;
}
.meldung.frei .link-btn.leise:hover { color: var(--text-primary); text-decoration: underline; }

/* ==========================================================================
   Reiterleiste unten (Handy) und das Menue hinter dem eigenen Namen
   ==========================================================================
   Stefans Beobachtung: die Leiste stand am Handy in DREI Zeilen und
   frass damit fast ein Drittel vom Bild, bevor irgendetwas Nuetzliches kam - und
   oben kommt der Daumen am schlechtesten hin.
   Also unten, fest, wie bei jeder Handy-App. Unten ist aber nur Platz fuer
   fuenf: "Mein Zugang" und "Verwaltung" liegen deshalb im Menue beim eigenen
   Namen. Am PC bleibt alles oben - eine Reiterleiste am unteren Bildschirmrand
   waere dort nur weit weg vom Zeiger. */

/* --- Das Menue beim eigenen Namen ---------------------------------------- */
.user-info { position: relative; }
.mein-knopf {
  display: flex; align-items: center; gap: 8px;
  background: var(--bg-hover) !important; color: var(--text-primary) !important;
  border: 1px solid var(--border) !important;
  padding: 7px 14px !important; border-radius: 999px !important;
  font-weight: 600 !important; text-transform: none !important;
  letter-spacing: 0 !important; font-size: 1em !important;
  cursor: pointer;
}
.mein-knopf:hover, .mein-knopf.offen { border-color: var(--bmw-blau) !important; }
.mein-knopf .pfeil { opacity: .6; font-size: .85em; }

.mein-menue {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 300;
  min-width: 230px;
  display: flex; flex-direction: column;
  background: var(--bg-card);
  border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 14px 38px rgba(0, 0, 0, .5);
  overflow: hidden;
}
.mein-menue button {
  display: flex; align-items: center; gap: 10px;
  background: none !important; color: var(--text-primary) !important;
  border: none !important; border-radius: 0 !important;
  padding: 14px 16px !important; text-align: left;
  font-size: .95em !important; font-weight: 500 !important;
  text-transform: none !important; letter-spacing: 0 !important;
  cursor: pointer;
}
.mein-menue button + button { border-top: 1px solid var(--border) !important; }
.mein-menue button:hover { background: var(--bg-hover) !important; }
.mein-menue button.gefahr { color: var(--rot-schrift) !important; }

/* --- Reiter: Symbol und Wort --------------------------------------------- */
/* Am PC nebeneinander wie bisher, und dort steht das lange Wort. */
.nav button { display: inline-flex; align-items: center; gap: 8px; }
.nav button .reiter-kurz { display: none; }

/* --- Am Handy: unten, fest ------------------------------------------------ */
/* Die Hoehe steht als Variable da, weil sich alles andere, was unten klebt
   (Fassungsleiste, schwebende Meldung, Fusszeile), daran ausrichten muss. */
:root { --leiste-hoehe: 0px; }

@media (max-width: 768px) {
  /* Nur wo es die Leiste wirklich gibt. Ein Gast sieht keine - der bekaeme
     sonst unten 62 Pixel Luft, hinter denen nichts ist. */
  .app.mit-leiste { --leiste-hoehe: calc(62px + env(safe-area-inset-bottom, 0px)); }

  .nav {
    position: fixed; top: auto; bottom: 0; left: 0; right: 0; z-index: 200;
    display: flex; gap: 0; padding: 0;
    padding: 0 4px env(safe-area-inset-bottom, 0px);
    overflow: visible;
    border-top: 1px solid var(--border); border-bottom: none;
    background: rgba(16, 21, 27, .97);
    backdrop-filter: blur(10px);
    box-shadow: 0 -4px 20px rgba(0, 0, 0, .35);
  }
  /* Fuenf gleich breite Flaechen - keine Pillen mehr: unten ist die Flaeche
     selbst der Knopf, und je groesser sie ist, desto sicherer trifft man. */
  .nav button {
    flex: 1 1 0; min-width: 0;
    flex-direction: column; gap: 2px;
    background: none; border: none; border-radius: 0;
    padding: 8px 2px 6px; min-height: 62px;
    font-size: .72em; font-weight: 600;
    color: var(--text-secondary);
  }
  .nav button:hover { transform: none; background: none; }
  .nav button .reiter-symbol { font-size: 1.45em; line-height: 1.1; }
  .nav button .reiter-wort { display: none; }
  .nav button .reiter-kurz {
    display: block;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .nav button.active {
    background: none; color: var(--bmw-blau-hell, #4a90e8); box-shadow: none;
  }
  /* Der Strich oben statt einer gefuellten Pille: er zeigt, wo man ist, ohne
     die Flaeche zuzukleistern. */
  .nav button.active::before {
    content: ''; position: absolute; top: 0; left: 22%; right: 22%;
    height: 3px; border-radius: 0 0 3px 3px; background: var(--bmw-blau);
  }
  .nav button { position: relative; }

  /* Luft unten, sonst liegt die Leiste auf der letzten Zeile und auf der
     Fusszeile. */
  .content { padding-bottom: calc(var(--leiste-hoehe) + 16px); }
  /* Ein paar Pixel Luft, sonst klebt die Fusszeile am Rand der Leiste. */
  .fusszeile { margin-bottom: calc(var(--leiste-hoehe) + 8px); }

  /* Die Kopfleiste braucht die zweite Zeile nicht mehr: im user-info steht
     jetzt ein einzelner Knopf. */
  /* Eine Zeile statt zwei: im user-info steht jetzt ein einzelner Knopf.
     Der Titel darf wachsen, der Name wird notfalls gekuerzt - "Zeilbeck"
     kennt jeder, "BMW WERKFEUERWEHR" ist das, was die Seite ausweist. */
  /* Nur die Vollansicht - der Gast hat kein Menue, sondern Name, Marke und
     "Fertig" nebeneinander. Dessen Kopfleiste bleibt, wie sie war. */
  .app.mit-leiste .header { flex-direction: row; align-items: center; gap: 10px; }
  .app.mit-leiste .header h1 { font-size: 1.1em; flex: 1 1 auto; min-width: 0; }
  .app.mit-leiste .user-info { width: auto; flex: 0 1 auto; min-width: 0; }
  .mein-knopf { max-width: 100%; padding: 7px 10px !important; }
  .mein-knopf > span:first-child {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .mein-knopf .badge { display: none; }
}

/* Ganz schmale Geraete: die Woerter werden sonst alle zu "Kaffee…". */
@media (max-width: 360px) {
  .nav button { font-size: .66em; }
  .nav button .reiter-symbol { font-size: 1.3em; }
}

/* Auf dem Blatt hat die Leiste nichts verloren. */
@media print {
  .nav, .mein-menue, .mein-knopf { display: none !important; }
  .content { padding-bottom: 0 !important; }
}

/* --- QR scannen und die App installieren --------------------------------- */
/* Der Scanner: das Kamerabild ist die Hauptsache, also bekommt es Platz und
   einen ruhigen Rahmen. Quadratisch, weil ein QR-Code quadratisch ist - und
   damit auf jedem Handy derselbe Ausschnitt zu sehen ist. */
.scanner-bild {
  position: relative; width: 100%; aspect-ratio: 1 / 1; max-width: 100%;
  margin: 10px 0; border-radius: 8px; overflow: hidden; background: #000;
}
.scanner-bild video { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Der Rahmen sagt ohne Worte, wohin der Code soll. */
.scanner-rahmen {
  position: absolute; inset: 12%;
  border: 3px solid var(--feuer-rot); border-radius: 10px;
  box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.35);
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .scanner-rahmen { animation: scanner-puls 1.8s ease-in-out infinite; }
}
@keyframes scanner-puls { 50% { opacity: 0.45; } }

/* Der Weg, den die meisten gehen sollen, sieht auch danach aus. */
.scan-knopf {
  width: 100%; padding: 12px; margin-top: 6px;
  font-size: 1em; font-weight: 600; border-radius: 8px;
  border: 1px solid var(--border); background: var(--bg-hover); color: inherit;
  cursor: pointer;
}
.scan-knopf:hover { background: var(--bg-card); }
.scan-knopf.leise { font-weight: 500; }

.app-holen { margin-top: 14px; }
.app-holen .schritte { margin: 8px 0 0; padding-left: 20px; text-align: left; }
.app-holen .schritte li { margin-bottom: 6px; }

/* ==========================================================================
   Bedienbar ohne Maus
   ==========================================================================
   Eingabefelder hatten laengst einen sichtbaren Fokus (blauer Rahmen), Knoepfe
   und Links nicht. Wer mit dem Tabulator durch die App geht - weil er keine
   Maus benutzen kann oder weil gerade die Handschuhe an sind - sah also nicht,
   wo er steht.

   :focus-visible statt :focus ist der ganze Trick: es greift bei Tastatur und
   bleibt beim Mausklick aus. Ein Rahmen, der nach jedem Klick am Knopf
   kleben bleibt, sieht nach Fehler aus - genau deshalb stand hier vorher
   nichts. */
button:focus-visible,
a:focus-visible,
[tabindex]:focus-visible,
summary:focus-visible {
  outline: 3px solid var(--bmw-blau);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Ein Formular, das gerade abschickt. Der Riegel sitzt im Javascript
   (siehe Form in app.jsx) - das hier macht ihn SICHTBAR. Ohne die Rueckmeldung
   tippt einer weiter, weil der Knopf ja normal aussieht, und wundert sich
   hinterher ueber zwei Buchungen. */
form[data-laeuft] button[type="submit"] {
  opacity: 0.55;
  cursor: progress;
  pointer-events: none;
}
form[data-laeuft] { cursor: progress; }

/* Kacheln und Zeilen, die man antippen kann, sind jetzt auch Knoepfe fuer die
   Tastatur. Sie sollen aber aussehen wie vorher. */
.wie-knopf {
  background: none; border: none; padding: 0; margin: 0;
  font: inherit; color: inherit; text-align: inherit; width: 100%;
  cursor: pointer; display: block;
}

/* ---- Wer hat bezahlt ----------------------------------------------------
   Zwei Zeilen je Person: oben Name und Summe, darunter die Knoepfe. Nicht
   alles in eine Zeile, weil bei "Brotzeit € 12,40" und "Abendessen € 5,00"
   nebeneinander auf einem 400er-Handy nichts mehr lesbar bleibt. */
.bezahlt-liste { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.bezahlt-liste li {
  background: var(--bg-dark); border: 1px solid var(--border); border-radius: 8px;
  padding: 10px; display: flex; flex-direction: column; gap: 8px;
}
.bz-kopf { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.bz-name { font-weight: 600; color: var(--text-primary); overflow-wrap: anywhere; }
.bz-summe { font-variant-numeric: tabular-nums; color: var(--rot-schrift); font-weight: 600; }
.bz-knoepfe { display: flex; flex-wrap: wrap; gap: 6px; }
.bz-knoepfe .small-btn { flex: 1 1 auto; }

/* Eine Karte, bei der man nichts eintragen darf (fremder Kollege, und man holt
   heute nicht). Ohne den Hinweis sieht sie aus wie eine abgerechnete, und man
   sucht den Fehler bei sich. */
.fremde-karte {
  margin: 0; background: var(--bg-dark); border: 1px dashed var(--border);
  border-radius: 8px; padding: 8px 10px;
}

/* ---- Sonderwunsch ------------------------------------------------------
   Das Feld sah gefuellt genauso aus wie leer - man musste hinsehen, um zu
   merken, dass da etwas steht. Jetzt hebt es sich ab, sobald Text drin ist,
   genau wie ein Zaehler mit Menge. */
.sonderwunsch.hat-text input[type="text"]:first-child {
  border-color: var(--bmw-blau);
  background: rgba(28, 105, 212, 0.10);
  color: var(--text-primary);
}

/* Wie der Text gelesen wird. Klein und ruhig - es ist eine Auskunft, keine
   Warnung. */
.wunsch-teile { margin: -4px 0 0; }
.wunsch-teile.leise { opacity: 0.75; }
.wunsch-teil {
  display: inline-block; margin: 2px 4px 0 0; padding: 1px 8px;
  background: var(--bg-dark); border: 1px solid var(--border);
  border-radius: 999px; color: var(--text-primary); font-size: 0.95em;
}
/* Die eine Stelle, an der es wirklich anders kommt als man denkt: mit Preis
   wird nie zerlegt, weil der Preis zur ganzen Zeile gehoert. */
/* Gedeckt, nicht alarmrot. Das hier ist eine Auskunft ("so wird es gelesen"),
   kein Fehler - und im Bild sprang ein dreizeiliger roter Block staerker ins
   Auge als der Preis darueber. Rot bleibt fuer das, was wirklich schiefgeht. */
.wunsch-warnung { color: var(--text-secondary); display: block; margin-top: 4px; }

/* ---- Schliessen-Knopf in jedem Fenster ---------------------------------
   Sitzt im Overlay-Bauteil, also in allen 22. Vorher stand "Fertig" oder
   "Schließen" am ENDE des Fensters - bei einem langen muss man dafuer erst
   durchscrollen, und zwei Fenster hatten gar keinen Knopf.

   position: sticky statt absolute: bei einem Fenster, in dem man scrollt,
   bleibt er so oben stehen und wandert nicht mit dem Inhalt weg. Der
   negative Rand zieht ihn in die Polsterung des Fensters hinein, damit er
   keine eigene Zeile verbraucht. */
[role="dialog"] { position: relative; }
.fenster-zu {
  position: sticky; top: 0; z-index: 3;
  float: right; margin: -12px -10px 0 8px;
  width: 40px; height: 40px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-dark); color: var(--text-secondary);
  border: 1px solid var(--border); border-radius: 999px;
  font-size: 1.05em; line-height: 1; cursor: pointer;
}
.fenster-zu:hover { background: var(--bg-hover); color: var(--text-primary); }
/* Auf einem Blatt, das gedruckt wird, hat er nichts verloren. */
@media print { .fenster-zu { display: none; } }

/* ==========================================================================
   Kein Hineinzoomen beim Antippen
   ==========================================================================
   iOS Safari zoomt automatisch in ein Eingabefeld hinein, wenn dessen Schrift
   KLEINER als 16px ist - und zoomt danach nicht von selbst wieder heraus. Man
   tippt einen Namen in die Suche und steht anschliessend in einer vergroesser-
   ten Seite, die man von Hand wieder zurechtruecken muss. Jeden Morgen.

   Gemessen waren es 6 von 9 Feldern: Suche und Sonderwunsch bei 13,3px, die
   Auswahllisten bei 15,2px.

   Die andere Loesung waere "maximum-scale=1" im viewport - damit sperrt man
   aber auch das ABSICHTLICHE Zoomen, und wer schlechte Augen hat, kommt nicht
   mehr naeher ran. Also lieber die Schrift gross genug.

   16px ist die Grenze, nicht der Wunsch: wo etwas kleiner aussehen soll,
   macht man das ueber Abstaende und Farbe, nicht ueber die Schriftgroesse
   eines Feldes, in das jemand tippen soll. */
input, select, textarea {
  font-size: max(16px, 1em);
}
/* Auch die, die ueber eine eigene Regel laufen. */
.form input, .form select, .form textarea,
.feld > input, .feld > select,
.brotzeit-filter input, .sonderwunsch input, .preiszeile input,
.stufentext, .artikelname {
  font-size: max(16px, 1em);
}

/* ---- Sonstiges: Knopf auf der Karte, Fenster zum Eintippen -------------
   Auf der Karte steht nur noch, WAS drinsteht. Getippt wird im Fenster -
   auf dem Handy schiebt die Tastatur sonst die Karte aus dem Bild, und man
   sieht weder den eigenen Text noch das Preisfeld daneben. */
.wunsch-knopf {
  display: flex; align-items: baseline; gap: 8px; width: 100%;
  text-align: left; font: inherit; cursor: pointer;
  background: var(--bg-dark); border: 1px dashed var(--border);
  border-radius: 8px; padding: 10px 12px; color: var(--text-secondary);
}
/* Steht etwas drin, ist es kein Vorschlag mehr, sondern eine Bestellung -
   also durchgezogener Rahmen und kraeftige Schrift. */
.wunsch-knopf:has(.wk-was) {
  border-style: solid; border-color: var(--bmw-blau);
  background: rgba(28, 105, 212, 0.10);
}
.wk-was { color: var(--text-primary); overflow-wrap: anywhere; flex: 1 1 auto; }
.wk-preis { font-variant-numeric: tabular-nums; color: var(--text-primary); }
.wk-aendern { font-size: 0.85em; opacity: 0.75; flex: 0 0 auto; }
.wk-leer { flex: 1 1 auto; }

/* .qr-box zentriert (fuer QR-Codes richtig) - in einem Formular ist das
   falsch: Beschriftungen gehoeren ueber ihr Feld, linksbuendig. */
.wunsch-fenster { text-align: left; }
.wunsch-fenster h3 { text-align: left; }
.wunsch-fenster .feld {
  display: flex; flex-direction: column; gap: 4px;
  text-align: left; color: var(--text-secondary); font-size: 0.9em;
}
/* Die drei Knoepfe unten in EINER Reihe und in ihrer Rangfolge: "Fertig"
   ist die Hauptsache, die beiden anderen sind Links. In .form bekommen
   link-btn sonst einen Kasten wie ein richtiger Knopf. */
.wunsch-fenster .karte-fuss {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.wunsch-fenster .karte-fuss button[type="submit"] { flex: 1 1 auto; }
.wunsch-fenster .karte-fuss .link-btn {
  background: none; border: none; padding: 0; box-shadow: none;
  width: auto; flex: 0 0 auto;
}
/* Hier standen bis 1.71 .wunsch-zahlen und .stueck-reihe - das Stueck-Feld
   neben dem Preis. Beides ist raus: die Stueckzahl steht wieder im Text. */

/* Sonstiges: eine Zeile je Sache, mit Kreuz zum Rauswerfen.
   Bis 1.73 war das EIN Textfeld mit allem drin - bei fuenf Sachen tippt man
   sich durch einen langen Satz, und um eine herauszunehmen, muss man das Wort
   UND ein Komma treffen. Auf dem Handy. */
.wunsch-liste { list-style: none; margin: 0 0 12px; padding: 0;
  display: flex; flex-direction: column; gap: 6px; }
.wunsch-zeile { display: flex; align-items: center; gap: 8px; }
.wunsch-zeile input { flex: 1 1 auto; min-width: 0; }
/* Das Kreuz muss man mit dem Daumen treffen, ohne die Zeile zu erwischen -
   44px ist das, was dafuer ueberall als Mindestmass gilt. */
/* Die Selektoren hier tragen .wunsch-fenster davor, und das ist kein Zierat:
   die Knoepfe stehen in einem <Form>, und `.form button` (Klasse + Element)
   ist spezifischer als `.wunsch-weg` allein. Im ersten Anlauf waren die Kreuze
   deshalb blaue Vollflaechen - dieselbe Falle wie bei den em-Regeln in 1.71,
   und wieder nur im Bild zu sehen.

   `.qr-box` statt `.wunsch-fenster`: das Kreuz sitzt inzwischen in zwei
   Fenstern (Sonstiges und Kassenzettel), und beide sind `.qr-box`. Mit dem
   engeren Selektor haette das zweite wieder blaue Kloetze bekommen - die
   Regel muss so weit reichen wie der Knopf.

   Zurueckhaltend, nicht alarmrot: bei fuenf Zeilen waeren fuenf rote Kaesten
   das Auffaelligste im Fenster, dabei geht es um das, was drinsteht. Rot wird
   es erst unter dem Finger. */
.qr-box .wunsch-weg {
  flex: 0 0 auto; width: 44px; height: 44px; padding: 0;
  background: transparent; border: 1px solid var(--border);
  color: var(--text-secondary); border-radius: 8px;
  font-size: 1.1em; line-height: 1; font-weight: normal; cursor: pointer;
}
.qr-box .wunsch-weg:hover:not(:disabled),
.qr-box .wunsch-weg:focus-visible {
  background: var(--rot-schrift); border-color: var(--rot-schrift); color: #fff;
}
.wunsch-dazu { display: flex; align-items: center; gap: 8px; }
.wunsch-dazu input { flex: 1 1 auto; min-width: 0; }
.wunsch-fenster .wunsch-plus {
  flex: 0 0 auto; width: 44px; height: 44px;
  font-size: 1.2em; line-height: 1; padding: 0;
}
.wunsch-gesamt {
  margin: 0; padding: 8px 10px; background: var(--bg-dark);
  border-radius: 8px; color: var(--text-primary);
}
.wunsch-fenster .karte-fuss { margin-top: 16px; }

/* ---- Korrekturen durch den Holer ---------------------------------------
   Wiener kommen im 8er-Pack. Wenn im Laden nicht aufgeht, was bestellt war,
   traegt der Holer ein, was wirklich verteilt wurde - und schreibt dazu,
   warum. Das Fenster dafuer, und der Hinweis auf der Karte des Betroffenen. */
.korr-zeilen { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.korr-zeile {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; border-radius: 8px; background: var(--bg-dark);
}
/* Nur die geaenderten Zeilen heben sich ab - bei sieben Artikeln soll man
   sehen, welche drei man angefasst hat, ohne sie zu suchen. */
.korr-zeile.anders { background: var(--bmw-blau-dunkel); }
.korr-name { flex: 1 1 auto; }
.korr-war { color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.korr-vorschau { margin: 0 0 12px; padding: 8px 10px; background: var(--bg-dark); border-radius: 8px; }

.korr-hinweis {
  margin: 8px 0; padding: 8px 10px; border-radius: 8px;
  background: var(--bg-dark); border-left: 3px solid var(--bmw-blau);
}
.korr-hinweis p { margin: 0 0 4px; font-size: 0.9em; }
.korr-hinweis p:last-child { margin-bottom: 0; }
.korr-grund { color: var(--text-secondary); }

/* "+ was anderes" im Korrektur-Fenster: zurueckgenommen.
   In einem <Form> greift .form button — der Knopf wurde damit ein breiter
   blauer Balken und stach staerker heraus als "Fertig". Die Gewichtung war
   verkehrt: der wichtige Knopf ist der, mit dem man fertig wird. */
.korr-fenster .mehr-artikel {
  align-self: flex-start;
  padding: 6px 12px;
  background: transparent;
  border: 1px solid var(--bmw-blau);
  color: var(--bmw-blau);
  font-weight: normal;
  margin-bottom: 12px;
}
.korr-fenster .mehr-artikel:hover:not(:disabled) { background: var(--bg-dark); }

/* ---- Kassenzettel vom Einkauf -------------------------------------------
   Der Holer fotografiert den Zettel; danach muss keiner mehr nachrechnen,
   was etwas gekostet hat. Mehrere je Tag sind normal (Baecker und Metzger). */
.bon-liste { list-style: none; margin: 0 0 16px; padding: 0;
  display: flex; flex-direction: column; gap: 6px; }
.bon-zeile { display: flex; align-items: center; gap: 8px; }
/* Die ganze Zeile ist der Knopf zum Ansehen - auf dem Handy trifft man eine
   Flaeche leichter als ein Woertchen "ansehen". */
.bon-fenster .bon-vorschau {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; border-radius: 8px;
  background: var(--bg-dark); border: 1px solid var(--border);
  color: var(--text-primary); font-weight: normal; text-align: left;
  cursor: pointer;
}
.bon-fenster .bon-vorschau:hover:not(:disabled) { border-color: var(--bmw-blau); }
.bon-laden { font-weight: 600; }
.bon-betrag { font-variant-numeric: tabular-nums; }
.bon-von { color: var(--text-secondary); font-size: 0.85em; margin-left: auto; }
.bon-felder { display: flex; gap: 12px; flex-wrap: wrap; }
.bon-felder .feld { flex: 1 1 140px; }
/* Das Bild soll man lesen koennen: volle Breite, und in der Hoehe so viel,
   wie der Schirm hergibt - ein Kassenzettel ist lang und schmal. */
.bon-bild { display: block; width: 100%; max-height: 70vh; object-fit: contain;
  border-radius: 8px; background: #fff; }

/* ---- Was kam zusammen ---------------------------------------------------
   Einmal sehen, was draufsteht, bevor man abrechnet - statt zweiundzwanzig
   Karten durchzublaettern und im Kopf zu addieren. Drei Spalten, mehr nicht:
   was, wie gerechnet, wie viel. */
.ab-tabelle { width: 100%; border-collapse: collapse; margin-bottom: 12px; }
.ab-tabelle td, .ab-tabelle th { padding: 8px 4px; text-align: left; }
.ab-tabelle .zahl, .ab-tabelle .ab-rechnung {
  text-align: right; font-variant-numeric: tabular-nums;
}
.ab-rechnung { color: var(--text-secondary); white-space: nowrap; }
.ab-tabelle tbody tr + tr td { border-top: 1px solid var(--border); }
.ab-tabelle tfoot th { border-top: 2px solid var(--border); padding-top: 10px; }
.ab-vergleich {
  margin: 0 0 12px; padding: 10px 12px; border-radius: 8px;
  background: var(--bg-dark); border-left: 3px solid var(--bmw-blau);
}
/* Ueber 50 Cent Unterschied ist kein Rundungsfehler mehr - meistens fehlt ein
   Preis bei einem Sonderwunsch. Das soll auffallen. */
.ab-vergleich.achtung { border-left-color: var(--rot-schrift); }

/* ---- Vom Zettel gelesen -------------------------------------------------
   Was die Texterkennung gefunden hat. Ein Vorschlag - eingetragen wird nur,
   was der Holer antippt. Bei Geld wird nicht geraten. */
.lese-liste { list-style: none; margin: 0 0 12px; padding: 0;
  display: flex; flex-direction: column; gap: 6px; max-height: 50vh; overflow-y: auto; }
/* Zwei Zeilen statt einer: nebeneinander nahm die Auswahl so viel Platz, dass
   vom Text nur "LEBERKA..." uebrigblieb - und der Betrag brach in zwei Zeilen
   um. Genau dafuer schaut man sich die Bilder an. Jetzt steht oben, was auf
   dem Zettel stand, und darunter die Auswahl. */
.lese-zeile {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
  padding: 10px; border-radius: 8px; background: var(--bg-dark);
}
.lese-was { flex: 1 1 60%; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.lese-betrag { flex: 0 0 auto; margin-left: auto;
  font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.lese-zeile select { flex: 1 1 100%; }
.bon-fenster .bon-lesen { flex: 0 0 auto; padding: 8px 12px; }
