/* Kassenoberfläche.
 *
 * Ausgelegt auf einen Touchmonitor am Tresen, quer, ab 1024 px. Auf einem
 * Tablet hochkant stapeln sich die drei Spalten (siehe ganz unten).
 *
 * Zwei Entscheidungen bestimmen das Aussehen:
 *
 * 1. GROSSE FLÄCHEN. Jede Taste ist mindestens 48 px hoch. Am Tresen wird
 *    mit dem Finger getippt, oft in Eile, gelegentlich mit Handschuh. Eine
 *    Kachel, die man zweimal treffen muss, kostet mehr als der Platz, den
 *    sie spart.
 *
 * 2. WENIG FARBE, AUSSER WO ES ZÄHLT. Rot ist dem TSE-Ausfall und Fehlern
 *    vorbehalten, Grün dem Abschließen. Wäre die Oberfläche bunt, ginge
 *    der rote Balken darin unter — und genau der ist die eine Farbe, die
 *    jemand sehen muss.
 */

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

:root {
  --dunkel: #2d394b;
  --dunkler: #232d3c;
  --rand: #d7dce3;
  --grau: #6b7280;
  --hell: #f3f4f6;
  --rot: #b91c1c;
  --rot-hell: #fee2e2;
  --gruen: #047857;
  --gelb: #d97706;
  --gelb-hell: #fef3c7;
}

html, body { height: 100%; }

body {
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 15px;
  line-height: 1.4;
  color: #1f2937;
  background: var(--hell);
  display: flex;
  flex-direction: column;
  /* Textauswahl aus: Beim Tippen auf einer Touchfläche markiert man sonst
     dauernd Text, und die blaue Markierung bleibt stehen. */
  -webkit-user-select: none;
  user-select: none;
}

body.wartet { cursor: progress; }
body.wartet button { pointer-events: none; opacity: 0.6; }

/* ===================== Balken ===================== */

.modusbalken {
  background: var(--gelb-hell);
  border-bottom: 1px solid var(--gelb);
  color: #78350f;
  padding: 6px 14px;
  font-size: 13px;
  text-align: center;
}

.tse-balken {
  padding: 10px 14px;
  font-weight: 600;
  text-align: center;
  background: var(--rot);
  color: #fff;
}
.tse-balken.simulation { background: #4c1d95; }
.tse-balken[hidden] { display: none; }

/* ===================== Kopf ===================== */

.kopf {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  background: var(--dunkel);
  color: #fff;
  padding: 9px 14px;
}

.kopf-links, .kopf-rechts { display: flex; align-items: center; gap: 12px; }
.kassenname { font-weight: 600; }
.seriennr, .bediener { font-size: 12px; opacity: 0.75; }

/* --- Firmenlogo ------------------------------------------------------
   Feste Kachel, immer gleich groß, ob mit Bild oder ohne. Damit sitzt
   der Rest der Kopfzeile an derselben Stelle, sobald ein Betrieb sein
   Logo hinterlegt — und die Kachel nimmt jedes Seitenverhältnis auf,
   ohne das Bild zu verzerren (`object-fit: contain`).                  */
.firmenzeichen {
  flex: none;
  /* Feste Höhe, wachsende Breite: Ein Logo ist meist breiter als hoch,
     und in einer quadratischen Kachel bliebe davon ein Briefmarkenbild
     übrig. Die Höhe bleibt fest, damit die Kopfzeile nicht springt. */
  height: 40px;
  min-width: 40px;
  max-width: 150px;
  padding: 2px 4px;
  border-radius: 6px;
  /* Weiß hinter dem Logo: Die meisten Logos sind für hellen Grund
     gezeichnet und verschwinden sonst im dunklen Kopfbalken. */
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
/* Die Höhe führt, die Breite folgt dem Seitenverhältnis. Über
   `max-height` allein käme ein SVG ohne width/height-Attribute nicht
   heraus: Es hat keine eigene Größe, nur ein Verhältnis — und in einer
   Kachel, deren Breite sich erst aus dem Inhalt ergibt, fiele es auf
   Briefmarkengröße zusammen. */
.firmenzeichen img {
  height: 100%;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  display: block;
}

/* Der Platzhalter, solange kein Logo hinterlegt ist: der
   Anfangsbuchstabe des Betriebs auf gestricheltem Rahmen. Gestrichelt,
   weil es eine offene Stelle ist und nicht das Ergebnis. */
.firmenzeichen.leer {
  width: 40px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px dashed rgba(255, 255, 255, 0.45);
  color: #fff;
  font-weight: 700;
  font-size: 18px;
}

.kopf-namen {
  display: flex;
  flex-direction: column;
  justify-content: center;
  line-height: 1.25;
  min-width: 0;
}
.firmenname {
  font-weight: 600;
  font-size: 15px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kassenzeile { display: flex; align-items: baseline; gap: 8px; font-size: 12px; }
.kassenzeile .kassenname { font-size: 12px; opacity: 0.85; }

/* ===================== Raster ===================== */

.raster {
  flex: 1;
  display: grid;
  /* Bon | Artikel | Tastenfeld. Der Bon links, weil dort der Blick
     zuerst hinfällt und weil der Kunde von der Seite mitliest. */
  grid-template-columns: 340px 1fr 220px;
  gap: 10px;
  padding: 10px;
  min-height: 0;
}

.raster > section {
  background: #fff;
  border: 1px solid var(--rand);
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  /* Beide Nullen sind nötig: Ein Rasterfeld ist von sich aus so breit
     wie sein längster Inhalt und läuft sonst über die Spalte hinaus —
     die Artikelkacheln schöben sich unter die Nachbarspalte. */
  min-height: 0;
  min-width: 0;
}

/* ===================== Bon ===================== */

.bonkopf {
  display: flex;
  justify-content: space-between;
  padding: 10px 12px;
  border-bottom: 1px solid var(--rand);
  font-weight: 600;
}
#bon-status { font-weight: 400; font-size: 12px; color: var(--grau); }

.positionen {
  flex: 1;
  overflow-y: auto;
  list-style: none;
  padding: 4px 0;
  min-height: 0;
}

.position {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 7px 12px;
  border-bottom: 1px solid #f0f2f5;
  background: transparent;
  transition: background-color 0.8s ease-out;
}

/* Kurzes Aufleuchten der zuletzt gebuchten Zeile, gesetzt von
   bonZeichnen() in kasse.js. Der Bon scrollt bei jeder Buchung ans
   Ende; ohne dieses Zeichen fällt die neue Zeile in einer langen Liste
   trotzdem nicht auf. */
.position.frisch { background: #fff7d6; transition: none; }

@media (prefers-reduced-motion: reduce) {
  .position { transition: none; }
}
.pos-links { flex: 1; min-width: 0; }
.pos-name { font-weight: 500; }
.pos-detail { font-size: 12px; color: var(--grau); }
.pos-rabatt { font-size: 12px; color: var(--gruen); }
.pos-betrag { font-variant-numeric: tabular-nums; font-weight: 600; }

/* Mengenänderung an der Zeile: [−] 2 [+] */
.pos-menge {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-top: 4px;
}

.mengentaste {
  /* Dieselben 32 px wie beim ×. Zwischen Minus und Plus liegt der
     Mengenstand, sonst wären zwei gleich aussehende Tasten direkt
     nebeneinander — und ein Fehlgriff ändert die Menge in die falsche
     Richtung, ohne dass es auffällt. */
  width: 32px;
  height: 32px;
  border: 1px solid var(--rand);
  border-radius: 6px;
  background: #fff;
  color: inherit;
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
}
.mengentaste:hover { background: var(--hell); }
.mengentaste:active { background: #e4e7eb; }

.mengenstand {
  min-width: 44px;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.pos-weg {
  border: none;
  background: none;
  color: var(--grau);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  /* 32 px Trefferfläche — kleiner lässt sich das × am Tresen nicht
     zuverlässig treffen, und danebentippen entfernt die falsche Zeile. */
  width: 32px;
  height: 32px;
}
.pos-weg:hover { color: var(--rot); }

.bonsumme {
  display: flex;
  justify-content: space-between;
  padding: 12px;
  border-top: 2px solid var(--dunkel);
  font-size: 22px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.zahlungen { padding: 0 12px; }
.zahlung {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 0;
  font-size: 14px;
  color: var(--grau);
  font-variant-numeric: tabular-nums;
}

.offen, .rueckgeld {
  display: flex;
  justify-content: space-between;
  padding: 10px 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.offen { background: var(--gelb-hell); color: #78350f; }
.rueckgeld { background: #d1fae5; color: #065f46; font-size: 19px; }

/* Ein `display` im Stylesheet sticht das `hidden`-Attribut — deshalb
   steht in dieser Datei zu jedem versteckbaren Element eine eigene
   Regel (siehe .tse-balken, .bondrucker, .overlay).
   HIER FEHLTE SIE BIS 1.88: `bonZeichnen()` setzt beide Zeilen brav auf
   `hidden`, und sichtbar blieben sie trotzdem. Am Tresen stand damit
   dauerhaft „Noch offen 0,00 €" und „Rückgeld 0,00 €" unter jedem Bon —
   zwei Zahlen, die nur dann etwas bedeuten, wenn sie NICHT null sind. */
.offen[hidden], .rueckgeld[hidden] { display: none; }

/* ===================== Artikel ===================== */

.suchzeile {
  display: flex;
  gap: 6px;
  padding: 10px;
  border-bottom: 1px solid var(--rand);
}
#suche {
  flex: 1;
  font: inherit;
  font-size: 16px; /* 16px verhindert das Hineinzoomen auf iOS. */
  padding: 10px 12px;
  border: 1px solid var(--rand);
  border-radius: 5px;
  -webkit-user-select: text;
  user-select: text;
}
#suche:focus { outline: 2px solid var(--dunkel); outline-offset: -1px; }

.warengruppen {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding: 8px 10px;
  border-bottom: 1px solid var(--rand);
}
.wg {
  font: inherit;
  white-space: nowrap;
  padding: 7px 13px;
  border: 1px solid var(--rand);
  border-bottom: 3px solid var(--rand);
  border-radius: 5px;
  background: #fff;
  cursor: pointer;
}
.wg.aktiv { background: var(--dunkel); color: #fff; border-color: var(--dunkel); }

.artikelraster {
  flex: 1;
  overflow-y: auto;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: 8px;
  padding: 10px;
  align-content: start;
  min-height: 0;
}

.kachel {
  font: inherit;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 6px;
  /* 78 px: hoch genug für zwei Zeilen Name plus Preis, ohne dass das
     Raster auf einem 1024er-Monitor scrollt. */
  min-height: 78px;
  padding: 9px 10px;
  text-align: left;
  border: 1px solid var(--rand);
  border-top: 3px solid var(--dunkel);
  border-radius: 6px;
  background: #fff;
  cursor: pointer;
}
.kachel:active { background: var(--hell); }
.kachel-bild {
  width: 100%;
  height: 40px;
  object-fit: cover;
  border-radius: 4px;
}
.kachel-name { font-weight: 600; font-size: 14px; }
.kachel-preis {
  font-size: 13px;
  color: var(--grau);
  font-variant-numeric: tabular-nums;
}

.leer { padding: 20px; color: var(--grau); text-align: center; }

/* ===================== Aktionen ===================== */

.aktionsspalte { padding: 10px; gap: 10px; }

.mengenfeld { display: flex; align-items: center; gap: 8px; }
.mengenfeld label { font-size: 13px; color: var(--grau); }
#menge {
  flex: 1;
  /* min-width: 0 gegen die Voreinstellung `auto` für Flex-Kinder: Ein
     <input> bringt eine Eigenbreite von rund 20 Zeichen mit, und mit
     `auto` darf es darunter nicht schrumpfen. Es ragte dadurch über die
     Spalte hinaus — und weil die Zahl rechtsbündig steht, stand die
     eingegebene Menge außerhalb des sichtbaren Bereichs. Das Feld sah
     leer aus, obwohl der Wert drin war. */
  min-width: 0;
  font: inherit;
  font-size: 20px;
  font-weight: 600;
  text-align: right;
  padding: 8px 10px;
  border: 1px solid var(--rand);
  border-radius: 5px;
  font-variant-numeric: tabular-nums;
  -webkit-user-select: text;
  user-select: text;
}

.tastenfeld {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 5px;
}
.tastenfeld button {
  font: inherit;
  font-size: 19px;
  padding: 12px 0;
  border: 1px solid var(--rand);
  border-radius: 5px;
  background: #fff;
  cursor: pointer;
}
.tastenfeld button:active { background: var(--hell); }

.aktionen { display: flex; flex-direction: column; gap: 7px; margin-top: auto; }

.knopf {
  font: inherit;
  padding: 11px 14px;
  border: 1px solid var(--dunkel);
  border-radius: 5px;
  background: #fff;
  color: var(--dunkel);
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  display: inline-block;
}
.knopf:hover { background: var(--hell); }
.knopf:disabled { opacity: 0.4; cursor: not-allowed; }
.knopf.schmal { padding: 5px 10px; font-size: 13px; border-color: rgba(255,255,255,0.35); color: #fff; background: transparent; }
.knopf.schmal:hover { background: rgba(255,255,255,0.12); }

.knopf.gross { padding: 15px; font-size: 17px; font-weight: 600; }
.knopf.bar { background: var(--dunkel); color: #fff; }
.knopf.karte { background: var(--dunkler); color: #fff; border-color: var(--dunkler); }
.knopf.fertig { background: var(--gruen); color: #fff; border-color: var(--gruen); }
.knopf.abbruch { border-color: var(--rot); color: var(--rot); }

/* „Bestellung senden“.

   Ruhend ein normaler Knopf, und sobald etwas offen ist, gelb umrandet
   mit gelbem Grund: Das ist die Farbe, die in dieser Oberfläche
   „unerledigt“ heisst (siehe .meldung.hinweis), und sie muss über die
   ganze Bonspalte hinweg auffallen — der Knopf ist die einzige Stelle,
   an der sichtbar wird, dass die Küche noch nichts hat. */
.knopf.bestellung.wartet-druck {
  background: var(--gelb-hell);
  border-color: var(--gelb);
  color: #7c4a03;
  font-weight: 600;
}
.knopf.bestellung.wartet-druck:hover { background: #fde9b0; }

/* ===================== Meldungen ===================== */

.meldungen {
  position: fixed;
  right: 12px;
  bottom: 12px;
  width: min(420px, calc(100vw - 24px));
  display: flex;
  flex-direction: column;
  gap: 7px;
  z-index: 50;
}

.meldung {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 11px 13px;
  border-radius: 6px;
  border-left: 4px solid;
  background: #fff;
  box-shadow: 0 3px 10px rgba(0,0,0,0.14);
  font-size: 14px;
  -webkit-user-select: text;
  user-select: text;
}
.meldung span { flex: 1; }
.meldung.fehler  { border-color: var(--rot);   background: var(--rot-hell); }
.meldung.hinweis { border-color: var(--gelb);  background: var(--gelb-hell); }
.meldung.erfolg  { border-color: var(--gruen); background: #d1fae5; }

.meldung-zu {
  border: none;
  background: none;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  color: inherit;
  opacity: 0.6;
  width: 24px;
}

/* ===================== Virtueller Bondruck =====================
   Nur in Schulung und Entwicklung sichtbar (siehe kasse/index.php).

   Die Bahn liegt ÜBER der Oberfläche und schiebt sie nicht zur Seite:
   Wer sie zumacht, soll dieselbe Kasse wiederfinden, die er vorher
   hatte — ohne dass Artikelraster und Tastenfeld zwischendurch die
   Breite gewechselt haben.                                            */

.bondrucker {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(360px, 92vw);
  background: var(--dunkler);
  display: flex;
  flex-direction: column;
  /* Über den Meldungen (50), unter den Dialogen (100): Eine
     Kartenzahlung darf nicht hinter der Papierbahn verschwinden. */
  z-index: 60;
  box-shadow: -6px 0 18px rgba(0, 0, 0, 0.28);
}
.bondrucker[hidden] { display: none; }

/* Solange die Bahn offen ist, rückt ALLES aus ihrem Weg.
   Der erste Versuch ließ das Raster stehen, damit es seine
   Spaltenbreiten nicht wechselt — dahinter lag dann die Aktionsspalte
   mit „Bar", „Karte" und „Abschließen". Eine Kasse, an der man mit
   offener Papierbahn nicht kassieren kann, ist der schlechtere Tausch:
   Die Artikelkacheln brechen um, das ist alles. */
body.bondruck-offen .meldungen { right: calc(min(360px, 92vw) + 12px); }
body.bondruck-offen .kopf,
body.bondruck-offen .modusbalken,
body.bondruck-offen .tse-balken,
body.bondruck-offen .raster { padding-right: calc(min(360px, 92vw) + 14px); }

.bondrucker-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 10px;
  color: #fff;
  font-size: 13px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.15);
}
.bondrucker-modus {
  margin-left: 6px;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.7;
}
.bondrucker-knoepfe { display: flex; gap: 6px; }
.bondrucker-kopf .knopf {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.28);
  color: #fff;
}

.bondrucker-papier {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.bondrucker-leer {
  color: rgba(255, 255, 255, 0.6);
  font-size: 13px;
  line-height: 1.5;
}

/* Ein Abzug: Kopfzeile, der Beleg selbst, darunter die Abrisskante. */
.bon-abzug {
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}
.bon-abzug.neu { animation: einlaufen 0.35s ease-out; }
@keyframes einlaufen {
  from { transform: translateY(-14px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .bon-abzug.neu { animation: none; }
}

.abzug-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  padding: 5px 8px;
  border-bottom: 1px dotted #9aa2ad;
  font-size: 12px;
  color: var(--grau);
}
/* Hier NICHT `.schmal`: Das ist die Fassung für den dunklen Kopfbalken
   (weiße Schrift auf durchsichtigem Grund) und wäre auf dem weißen
   Papier unsichtbar. */
.abzug-kopf .knopf { padding: 3px 8px; font-size: 11px; }
.abzug-knoepfe { display: flex; gap: 5px; flex: none; }

/* Der Umschalter im Kopfbalken zeigt an, ob die Bahn Papier bekommt. */
.knopf.schmal.gewaehlt {
  background: rgba(255, 255, 255, 0.18);
  border-color: #fff;
  font-weight: 600;
}

/* Der Beleg selbst, in genau der Fassung, die auch der Drucker bekommt.
   Die Höhe setzt kasse.js nach dem Laden — ein Bon ist mal zehn und mal
   sechzig Zeilen lang, und ein Rollbalken im Rollbalken ist unlesbar. */
.bon-abzug iframe {
  display: block;
  width: 100%;
  border: 0;
  background: #fff;
}

/* Die Abrisskante. Weiße Zacken auf dunklem Grund — das Papier endet
   gezackt, wie an der Abrisskante des Bondruckers. */
.abzug-kante {
  height: 6px;
  background-image:
    linear-gradient(45deg, transparent 50%, #fff 50%),
    linear-gradient(-45deg, transparent 50%, #fff 50%);
  background-size: 8px 6px;
  background-repeat: repeat-x;
}

/* ===================== Overlays ===================== */

.overlay {
  position: fixed;
  inset: 0;
  background: rgba(17, 24, 39, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 16px;
}
.overlay[hidden] { display: none; }

.overlay-kasten {
  background: #fff;
  border-radius: 8px;
  padding: 24px;
  width: min(440px, 100%);
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.overlay-kasten h2 { font-size: 17px; }
.overlay-kasten p { color: var(--grau); font-size: 14px; }
.overlay-kasten .gross {
  font-size: 26px;
  font-weight: 700;
  color: #1f2937;
  font-variant-numeric: tabular-nums;
}

.overlay-kasten input {
  font: inherit;
  font-size: 18px;
  padding: 11px 12px;
  border: 1px solid var(--rand);
  border-radius: 5px;
  -webkit-user-select: text;
  user-select: text;
}

.dialog-knoepfe { display: flex; gap: 8px; }
.dialog-knoepfe .knopf { flex: 1; }

/* --- Das Zahlungsstatus-Fenster -------------------------------------
   Die wichtigste Zahl gross und allein in der Mitte. Am Tresen wird sie
   aus zwei Metern Abstand gelesen, oft im Vorbeigehen — 44 px ist die
   Groesse, bei der das ohne Hinsehen geht.

   Der farbige Streifen oben traegt die Bedeutung doppelt: Gruen heisst
   fertig, Gelb heisst „hier ist noch etwas zu tun". Farbe allein
   genuegt nicht, deshalb steht es zusaetzlich als Text darunter.       */
.zahlstatus { gap: 6px; }

.zahlstatus h2 { font-size: 15px; color: var(--grau); font-weight: 500; }
.zahlstatus > p { margin: 0; }

.zahlstatus-hauptzahl {
  font-size: 44px;
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
}

.zahlstatus-hauptzahl-text {
  font-size: 15px !important;
  font-weight: 600;
  color: #1f2937 !important;
}

.zahlstatus.rueckgeld .zahlstatus-hauptzahl { color: var(--gelb); }
.zahlstatus.offen     .zahlstatus-hauptzahl { color: var(--gelb); }
.zahlstatus.fertig    .zahlstatus-hauptzahl { color: var(--gruen); }

/* Der Streifen sitzt am Kasten, nicht an der Zahl: Er soll den ganzen
   Zustand faerben und nicht nur eine Zeile. */
.zahlstatus { border-top: 5px solid var(--rand); }
.zahlstatus.rueckgeld { border-top-color: var(--gelb); }
.zahlstatus.offen     { border-top-color: var(--gelb); }
.zahlstatus.fertig    { border-top-color: var(--gruen); }

.zahlstatus-zeilen {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 3px 12px;
  margin: 8px 0 2px;
  font-size: 14px;
  text-align: left;
}
.zahlstatus-zeilen dt { color: var(--grau); }
.zahlstatus-zeilen dd {
  margin: 0;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.zahlstatus-zeilen:empty { display: none; }

/* Dieselbe Größe wie `.knopf.gross`, aber ohne dessen Namen — siehe den
   Kommentar am Knopf in index.php. */
.zahlstatus-weiter {
  padding: 15px;
  font-size: 17px;
  font-weight: 600;
  margin-top: 6px;
}

/* --- Kartendialog ---------------------------------------------------
   Die Kartenart als Knopfreihe, nicht als Ausklappliste: Am Tresen wird
   getippt, und eine Auswahlliste braucht auf einem Touchgeraet zwei
   Beruehrungen statt einer.                                            */
.overlay-kasten label {
  font-size: 13px;
  color: var(--grau);
  text-align: left;
}

/* Die Knopfreihe der Kartenarten (.markenwahl, #karte-marken, .knopf.marke)
   ist mit 1.17 entfallen. Am Tresen wird die Kartenart nicht mehr gewaehlt
   — sie kommt aus dem Terminal. Siehe KARTEN_MARKEN in lib/kasse.php.     */

#karte-grundfeld {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
#karte-grundfeld[hidden] { display: none; }
#karte-grundfeld input { width: 100%; box-sizing: border-box; }

/* --- Bardialog --------------------------------------------------------
   Die Kacheln in einem 2×2-Raster: „Passend" dunkel hervorgehoben (die
   Farbe des Bar-Knopfs, den man gerade gedrückt hat), die Scheine
   darüber neutral. Zwei Zeilen mit dem offenen Betrag als Nebenzahl
   reichen, um den Griff ohne Nachdenken zu treffen — mehr Text auf der
   Kachel läse am Tresen ohnehin niemand. */
.bar-kasten { text-align: left; }
.bar-kasten h2, .bar-kasten > p { text-align: center; }

.bar-kacheln {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

.bar-kachel {
  font: inherit;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 14px 8px;
  border: 1px solid var(--dunkel);
  border-radius: 6px;
  background: #fff;
  color: var(--dunkel);
  cursor: pointer;
}
.bar-kachel:hover { background: var(--hell); }
.bar-kachel:active { background: #e4e7eb; }

.bar-kachel-betrag {
  font-size: 20px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.bar-kachel-neben {
  font-size: 12px;
  color: var(--grau);
}

.bar-kachel.passend {
  background: var(--dunkel);
  color: #fff;
}
.bar-kachel.passend:hover { background: var(--dunkler); }
.bar-kachel.passend .bar-kachel-neben { color: rgba(255, 255, 255, 0.75); }

#bar-form label { display: block; margin-top: 4px; }
#bar-form input { width: 100%; box-sizing: border-box; margin-top: 4px; }

/* Eine ohne Terminal erfasste Zahlung wird am Bon hervorgehoben. */
.zahlung .manuell { color: var(--rot); }

.spinner {
  width: 34px;
  height: 34px;
  margin: 0 auto;
  border: 3px solid var(--rand);
  border-top-color: var(--dunkel);
  border-radius: 50%;
  animation: dreh 0.9s linear infinite;
}
@keyframes dreh { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 3s; }
}

/* ===================== Einrichtungsseite ===================== */

body.einrichtung { display: block; padding: 30px 16px; }
.hinweisblatt {
  max-width: 680px;
  margin: 0 auto;
  background: #fff;
  border: 1px solid var(--rand);
  border-radius: 6px;
  padding: 26px 30px;
}
.hinweisblatt h1 { font-size: 20px; margin-bottom: 10px; }
.hinweisblatt p { margin-bottom: 12px; }
.hinweisblatt ul { margin: 0 0 14px 18px; }
.hinweisblatt li { margin-bottom: 7px; }
.hinweisblatt li.stufe-pflicht { color: var(--rot); font-weight: 600; }
.hinweisblatt li.stufe-wichtig { color: #78350f; }

/* ===================== Schmale Bildschirme ===================== */

/* Unter 1100 px wandert das Tastenfeld unter den Bon: Auf einem Tablet
   quer ist sonst keine Spalte mehr breit genug, um lesbar zu bleiben.

   =====================================================================
   WARUM HIER `.raster > .aktionsspalte` STEHT UND NICHT `.aktionsspalte`
   =====================================================================

   Weiter oben steht `.raster > section { flex-direction: column }`.
   Das ist ein Klassenname PLUS ein Elementname und damit spezifischer
   als ein Klassenname allein — `.aktionsspalte { flex-direction: row }`
   verlor gegen diese Regel, ohne dass irgendetwas gemeldet hätte.

   Die Folge, am 14.08.2026 bei 900 px gemessen: Die Aktionsspalte blieb
   senkrecht, behielt aber das `flex-wrap: wrap` dieser Querlage. In
   einer Spalte heißt `wrap` nicht „Zeilen umbrechen", sondern SPALTEN
   umbrechen — Mengenfeld, Tastenfeld und Aktionen standen deshalb
   nebeneinander statt untereinander, und für das Tastenfeld blieben
   138 px übrig: sechs Zifferntasten zu je 19 px, bei einem eigenen
   Mindestmaß von 48 px (§ 11). Das war der Grund, warum die Kasse
   unter 1100 px nicht bedienbar war — nicht das Tastenfeld selbst. */
@media (max-width: 1100px) {
  .raster {
    grid-template-columns: 300px 1fr;
    grid-template-rows: 1fr auto;
  }
  .raster > .aktionsspalte {
    grid-column: 1 / -1;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
  }

  /* Zwei Zeilen statt einer: oben Menge und Ziffern, darunter die
     Knöpfe über die volle Breite. In EINER Zeile passt beides nur auf
     einem breiten Tablet — bei 900 px blieben je Knopf 47 px und je
     Zifferntaste 42, beides unter dem eigenen Mindestmaß von 48 px.
     Die `flex-basis`-Werte sind die Umbruchstellen: Sobald Menge und
     Tastenfeld zusammen nicht mehr nebeneinander passen, rutscht das
     Tastenfeld eine Zeile tiefer, statt sich zusammenzuquetschen.

     `min-width: 0` überall, weil Flex-Kinder von sich aus nicht unter
     ihre Inhaltsbreite schrumpfen dürfen — sonst nimmt sich die
     Knopfreihe, was ihre Beschriftungen brauchen, und das Tastenfeld
     bekommt den Rest, auch wenn davon nichts übrig ist. */
  .mengenfeld { flex: 1 1 200px; min-width: 0; }
  .tastenfeld {
    grid-template-columns: repeat(6, 1fr);
    flex: 3 1 380px;
    min-width: 0;
  }
  .aktionen { flex-direction: row; margin-top: 0; flex: 1 1 100%; min-width: 0; }
  .aktionen .knopf { flex: 1; min-width: 0; }
  .tastenfeld button, .aktionen .knopf { min-height: 48px; }

  /* Unter 1100 px ist für die Papierbahn NEBEN der Kasse kein Platz
     mehr: Bliebe sie am Rand, quetschte sie das Artikelraster auf ein
     paar Zentimeter. Sie legt sich deshalb über die ganze Fläche — wer
     sie zumacht, hat die Kasse unverändert wieder. */
  .bondrucker { width: 100%; }
  body.bondruck-offen .meldungen { right: 12px; }
  body.bondruck-offen .kopf,
  body.bondruck-offen .modusbalken,
  body.bondruck-offen .tse-balken,
  body.bondruck-offen .raster { padding-right: 10px; }
  body.bondruck-offen .kopf { padding-right: 14px; }
}

/* =====================================================================
   Unter 780 px: die schmale Ansicht (Handgerät)
   =====================================================================

   ACHTUNG BEIM ÄNDERN: Dieser Abschnitt muss NEHMEN, was der 1100er
   oben gegeben hat. Der legt die Aktionsspalte quer — sechs
   Zifferntasten nebeneinander, die Aktionsknöpfe in einer Reihe. Das
   ist richtig auf einem breiten Tablet; in einer Spalte von Handybreite
   wären es 19 px je Taste (eigener Mindestwert für Touch: 48 px).

   BIS 1.88 STAND HIER ALLES UNTEREINANDER — Bon, Artikel, Bedienfeld,
   und das Ganze scrollte als eine Strecke. Auf 375 × 812 gemessen: 1005
   px Inhalt in einem Fenster von 505, davor 307 px Banner und Kopfzeile.
   Für jede Bestellrunde hieß das: hoch zum Bon, runter zum Bezahlen.

   Jetzt ist es eine Anwendung mit festem Rahmen: Kopf oben, Leiste
   unten, dazwischen ZWEI Tafeln, von denen eine sichtbar ist. Umgeräumt
   wird das von handyEinrichten() in kasse.js — dort steht, welches
   Element wohin wandert und warum. Ohne `body.handy` (also wenn das
   Skript nicht lief) greifen die Regeln nicht, und es bleibt beim
   Untereinander von vorher. */
@media (max-width: 780px) {

  /* --- Der Rahmen ---------------------------------------------------
     Feste Höhe statt mitwachsender Seite: Eine Kasse, deren Zahlknöpfe
     erst nach dem Scrollen erscheinen, ist am Tisch nicht bedienbar.
     `100dvh` statt `100vh`, weil die Adressleiste des Handybrowsers
     sonst die unterste Knopfreihe abschneidet. */
  html, body { height: 100%; overflow: hidden; }
  body.handy { height: 100dvh; }

  /* Die Banner sind Pflichtangaben und bleiben — aber sie bekommen die
     Zeilenhöhe eines Hinweises und nicht die eines Absatzes. Auf einer
     produktiven Kasse mit laufender TSE steht hier ohnehin keiner. */
  body.handy .modusbalken,
  body.handy .tse-balken { padding: 5px 10px; font-size: 12px; line-height: 1.3; }

  /* --- Die Kopfzeile wird eine Anwendungsleiste ----------------------
     Firmenname, Kassenname, Seriennummer und Bediener stehen auf dem
     Tischplan, der im Gastrobetrieb der Ruhezustand ist. Hier kosten sie
     drei Zeilen, die die Artikeltafel braucht — 154 px gemessen, für
     Angaben, die sich nicht ändern. */
  body.handy .kopf { flex-wrap: nowrap; padding: 6px 10px; gap: 8px; }
  body.handy .kopf-namen,
  body.handy .kopf-rechts .bediener,
  body.handy .kopf-rechts .knopf.schmal { display: none; }
  /* Nur das Zeichen in der Kopfzeile — der Tischplan hat ein zweites,
     und das ist dort das einzige Merkmal des Betriebs. */
  body.handy .kopf .firmenzeichen { width: 34px; height: 34px; }
  body.handy .kopf-rechts { margin-left: auto; gap: 6px; }

  /* Der Menüknopf sitzt jetzt in der Kopfzeile (siehe
     handyEinrichten). Dort ist er weiß auf dunkel wie seine Nachbarn. */
  body.handy .kopf-rechts .menuknopf {
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.35);
    color: #fff;
    min-height: 40px;
    padding: 0 10px;
  }
  body.handy .kopf-rechts .menuknopf svg { stroke: #fff; }

  /* --- Drei Zeilen: Bonkopf, Tafel, Leiste --------------------------- */
  body.handy .raster {
    grid-template-columns: 1fr;
    grid-template-rows: auto minmax(0, 1fr) auto;
    grid-template-areas: "bonkopf" "tafel" "leiste";
    overflow: hidden;
    padding: 8px;
    gap: 8px;
  }

  /* Der Bonkopf ist aus der Bonspalte herausgewandert: Tischname und
     Umschalter gehören zu beiden Tafeln. */
  body.handy .bonkopf {
    grid-area: bonkopf;
    align-items: center;
    gap: 8px;
    padding: 0;
    border-bottom: none;
    min-height: 0;
  }
  body.handy #bon-nummer, body.handy #bon-status { display: none; }
  body.handy .tischplanknopf {
    flex: 1;
    min-width: 0;
    margin: 0;
    min-height: 44px;
    text-align: left;
  }

  /* Beide Tafeln liegen im selben Feld; sichtbar ist die gewählte. */
  body.handy .bonspalte,
  body.handy .artikelspalte {
    grid-area: tafel;
    max-height: none;
    min-height: 0;
    overflow-y: auto;
  }
  body.handy .bonspalte { display: none; }
  body.handy.tafel-bon .bonspalte { display: flex; }
  body.handy.tafel-bon .artikelspalte { display: none; }

  /* Die Aktionsspalte ist leergeräumt — ihre Kinder stehen jetzt in den
     Tafeln und in der Leiste. */
  body.handy .aktionsspalte,
  body.handy .bonfuss { display: none; }

  /* DAS ZIFFERNTASTENFELD ENTFÄLLT. Es ist die Eingabe einer Menge, und
     ein Handy hat dafür eine Tastatur — das Mengenfeld ruft sie auf.
     271 px nachgebaute Tasten neben einer echten Tastatur wären genau
     der Platz, den die Artikel brauchen. */
  body.handy .tastenfeld { display: none; }

  body.handy .mengenfeld {
    flex: none;
    padding: 8px 10px 0;
  }
  body.handy .mengenfeld input { min-height: 44px; }

  /* Die übrigen Knöpfe stehen am Ende der Bontafel, zu zweit
     nebeneinander: Abbrechen, Teilen, Kunde, Bonus, Storno,
     Ein-/Auszahlung, Rechnung. */
  body.handy .aktionen {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 7px;
    margin: 0;
    padding: 10px;
    flex: none;
  }

  /* --- Die Leiste unten ---------------------------------------------- */
  .handy-leiste {
    grid-area: leiste;
    display: flex;
    flex-direction: column;
    gap: 8px;
  }

  .handy-geld > * { margin: 0; }
  .handy-geld .bonsumme { font-size: 20px; }

  .handy-knoepfe { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 7px; }
  .handy-knoepfe.einzeln { grid-template-columns: 1fr; }
  .handy-knoepfe .knopf { min-height: 52px; margin: 0; }

  /* Die Meldungen liegen fest am unteren Rand — dort steht jetzt die
     Leiste. „Bestellung gesendet." verdeckte damit genau die drei
     Knöpfe, zu denen man danach greift. Sie rücken über die Leiste;
     `position: sticky` ginge nicht, weil sie außerhalb des Rasters
     hängen und über allem liegen müssen. */
  body.handy .meldungen {
    left: 8px;
    right: 8px;
    bottom: 8px;
    width: auto;
    /* Die Höhe der Leiste ist nicht fest — sie hat mit „Bestellung
       senden" eine Zeile mehr. Der Abstand kommt deshalb aus einer
       Variablen, die handyEinrichten() nachmisst. */
    margin-bottom: var(--leiste-hoehe, 0px);
  }

  /* --- Der Umschalter ------------------------------------------------
     Ein Schalter mit zwei Feldern, kein Reiterband: Bei zwei Tafeln ist
     der ausgewählte Zustand die ganze Aussage, und ein Schalter zeigt
     ihn ohne Rand und Zunge. */
  .handy-reiter {
    flex: none;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 3px;
    padding: 3px;
    background: var(--hell);
    border: 1px solid var(--rand);
    border-radius: 7px;
  }
  .handy-reiter button {
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    min-height: 38px;
    padding: 0 12px;
    border: none;
    border-radius: 5px;
    background: transparent;
    color: var(--grau);
    cursor: pointer;
    white-space: nowrap;
  }
  .handy-reiter button.aktiv { background: #fff; color: var(--dunkel); box-shadow: 0 1px 2px rgba(0,0,0,0.12); }

  /* Die Zahl der Positionen. In der Artikeltafel ist sie die einzige
     Rückmeldung, dass eine Buchung angekommen ist — die Liste steht
     dann hinter dem anderen Feld. */
  .handy-zahl {
    display: inline-block;
    min-width: 20px;
    padding: 1px 5px;
    margin-left: 4px;
    border-radius: 10px;
    background: var(--dunkel);
    color: #fff;
    font-size: 12px;
  }
  /* Wie bei .offen und .rueckgeld: ohne diese Regel stünde dauerhaft
     eine „0" am Reiter, obwohl das Skript sie versteckt. */
  .handy-zahl[hidden] { display: none; }

  /* Das Mindestmaß, das sich die Kasse selbst gibt: Was mit dem Finger
     getroffen werden muss, ist mindestens 48 px hoch. Es steht hier und
     nicht oben, weil auf einem Zeigergerät die kleinere Fläche genügt
     und mehr Zeilen aufs Blatt passen. */
  .aktionen .knopf,
  .warengruppen .wg { min-height: 48px; }

  /* --- Ohne das Skript: der Stand von vor 1.88 -----------------------
     Greift nur, wenn handyEinrichten() NICHT gelaufen ist. Dann steht
     alles untereinander und scrollt als eine Strecke — unbequem, aber
     vollständig bedienbar. Eine Kasse, die ohne ihr Umbauskript gar
     nichts mehr anzeigt, wäre der schlechtere Tausch. */
  body:not(.handy) .raster {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto auto;
    overflow-y: auto;
    padding: 8px;
    gap: 8px;
  }
  body:not(.handy) .bonspalte { max-height: 32vh; }
  body:not(.handy) .raster > .artikelspalte { min-height: 55vh; }
  body:not(.handy) .raster > .aktionsspalte {
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
  }
  body:not(.handy) .mengenfeld { flex: 0 0 auto; }
  body:not(.handy) .kopf { flex-wrap: wrap; row-gap: 8px; padding: 8px 10px; }
  body:not(.handy) .kopf-links,
  body:not(.handy) .kopf-rechts { flex-wrap: wrap; gap: 8px; min-width: 0; }
  body:not(.handy) .kopf-rechts { margin-left: auto; }
  body:not(.handy) .tastenfeld { grid-template-columns: repeat(3, 1fr); flex: none; }
  body:not(.handy) .aktionen {
    display: grid;
    grid-template-columns: 1fr 1fr;
    flex: none;
    margin-top: 0;
    gap: 7px;
  }
  body:not(.handy) .tastenfeld button,
  body:not(.handy) .kopf .knopf { min-height: 48px; }
}

/* --- Die Trefferliste der Kundensuche -------------------------------
   Ein Knopf je Treffer, nicht eine Liste mit einem Knopf daneben: Am
   Tresen ist die ganze Zeile das Ziel, und ein Treffbereich von 44 px
   ist der, bei dem auch mit nassen Fingern nichts danebengeht.

   Die Liste scrollt in sich. Ohne die feste Hoehe waechst der Dialog
   bei zwanzig Treffern ueber den Bildschirm hinaus, und die Knoepfe
   „Schliessen" und „Zuordnung aufheben" waeren nicht mehr erreichbar. */
.trefferliste {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 40vh;
  overflow-y: auto;
  text-align: left;
}

.trefferliste .hinweis {
  color: var(--grau);
  font-size: 14px;
  padding: 8px 2px;
}

.treffer {
  font: inherit;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 44px;
  padding: 8px 10px;
  border: 1px solid var(--rand);
  border-radius: 5px;
  background: #fff;
  text-align: left;
  cursor: pointer;
}
.treffer:hover  { background: #f9fafb; }
.treffer:active { background: #f3f4f6; }

.treffer-name   { font-weight: 600; }
.treffer-zusatz { font-size: 13px; color: var(--grau); }

/* =====================================================================
   Die Blätter — Menü, Einstellungen, Statistik
   =====================================================================

   Drei Menüs, ein Aussehen. Warum es sie gibt, steht im Kopf des
   Abschnitts „Die Blätter" in kasse.js; hier geht es nur darum, wie sie
   aussehen — und das folgt denselben zwei Regeln wie der Rest der
   Kasse (§ 1 und § 2 ganz oben in dieser Datei):

   GROSSE FLÄCHEN. Eine Kachel ist mindestens 88 px hoch und trägt ihr
   Sinnbild über der Beschriftung. Ein Menü, in dem man zielen muss, ist
   am Tresen kein Menü, sondern eine Fehlerquelle.

   WENIG FARBE. Die Kacheln sind weiß auf hellgrauem Blatt, die
   Sinnbilder in der Hausfarbe. Farbige Kacheln wären auf einem
   Tresenmonitor gut zu sehen, nähmen aber der einen Farbe die Wirkung,
   auf die es hier ankommt — Rot für den TSE-Ausfall. Statt Farbe trägt
   hier die Fläche.                                                      */

/* --- Die Sinnbildknöpfe im Kopf -------------------------------------- */

.sinnbildknopf {
  font: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 6px;
  background: transparent;
  color: #fff;
  cursor: pointer;
}
.sinnbildknopf:hover { background: rgba(255, 255, 255, 0.12); }
.sinnbildknopf[aria-expanded="true"] {
  background: #fff;
  color: var(--dunkel);
  border-color: #fff;
}

/* Strichzeichnungen, keine Flächen: Ein gefülltes Sinnbild müsste für
   hellen und dunklen Grund je eine Fassung haben. */
.sinnbildknopf svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --- Der Menüknopf unter dem Bon ------------------------------------- */

.bonfuss {
  padding: 8px;
  border-top: 1px solid var(--rand);
}

.menuknopf {
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  width: 100%;
  min-height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 10px 14px;
  border: 1px solid var(--dunkel);
  border-radius: 6px;
  background: var(--dunkel);
  color: #fff;
  cursor: pointer;
}
.menuknopf:hover  { background: var(--dunkler); }
.menuknopf:active { background: #1b2431; }
.menuknopf[aria-expanded="true"] { background: var(--dunkler); }

.menuknopf svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

/* --- Die Fläche hinter dem Blatt ------------------------------------- */

.blatt-overlay {
  position: fixed;
  inset: 0;
  z-index: 120;
  background: rgba(17, 24, 39, 0.5);
  display: flex;
}
.blatt-overlay[hidden] { display: none; }

/* Zwei Lagen, ein Bauteil:

   `lage-unten`  — das Menü fährt von unten über die volle Breite ein,
                   dort, wo der Knopf steht, der es aufgezogen hat.
   `lage-seite`  — Einstellungen und Statistik als hohe Spalte am linken
                   Rand. Genau wie in der Vorlage, und aus demselben
                   Grund: Diese Listen sind lang, und eine lange Liste
                   liest sich in einer Spalte besser als in einem Feld,
                   das über den halben Bildschirm geht.                  */
.blatt {
  background: var(--hell);
  display: flex;
  flex-direction: column;
  min-height: 0;
  box-shadow: 0 -2px 24px rgba(0, 0, 0, 0.35);
}

.blatt.lage-unten {
  margin-top: auto;
  width: 100%;
  max-height: 80vh;
  border-top: 1px solid var(--rand);
}

.blatt.lage-seite {
  width: min(460px, 100%);
  height: 100%;
  border-right: 1px solid var(--rand);
}

.blatt-kopf {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  background: var(--dunkel);
  color: #fff;
}
.blatt-kopf h2 { font-size: 17px; font-weight: 600; }

.blatt-zu {
  font: inherit;
  font-size: 15px;
  min-height: 44px;
  padding: 8px 16px;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 6px;
  background: transparent;
  color: #fff;
  cursor: pointer;
}
.blatt-zu:hover { background: rgba(255, 255, 255, 0.12); }

.blatt-inhalt {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* --- Die Gruppen ------------------------------------------------------
   Die Gliederung trägt eine Überschrift UND einen eigenen Kasten. Nur
   Abstände dazwischen genügen nicht: Auf einem 15-Zoll-Tresenmonitor
   verschwimmen sie beim Überfliegen, und die Gruppen laufen ineinander.
   Die erste Gruppe kommt ohne Überschrift aus — dort steht der eine
   Punkt, der ganz oben stehen soll (Kasse sperren, Zwischenstand).      */
.blatt-gruppe {
  background: #fff;
  border: 1px solid var(--rand);
  border-radius: 8px;
  padding: 10px;
}

.blatt-gruppe h3 {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--grau);
  margin-bottom: 8px;
}

/* `auto-fill` mit einer festen Untergrenze statt einer festen
   Spaltenzahl: Das Menü unten ist über die ganze Breite offen und
   bekommt sechs Spalten, die Schublade links zwei — ohne eigene Regel
   je Lage. */
.blatt-raster {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 8px;
}

.blatt-kachel {
  font: inherit;
  min-height: 88px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px 8px;
  border: 1px solid var(--rand);
  border-radius: 8px;
  background: #fff;
  color: #1f2937;
  text-align: center;
  cursor: pointer;
}
.blatt-kachel:hover  { background: var(--hell); border-color: var(--dunkel); }
.blatt-kachel:active { background: #e5e7eb; }

/* Ein Eintrag, der über die ganze Zeile geht — für den einen Punkt, der
   sich von den anderen abheben soll. */
.blatt-kachel.breit { grid-column: 1 / -1; }

.blatt-kachel svg {
  flex: none;
  width: 26px;
  height: 26px;
  fill: none;
  stroke: var(--dunkel);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.kachel-texte {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.kachel-titel { font-weight: 600; font-size: 15px; }
.kachel-unter { font-size: 12px; color: var(--grau); line-height: 1.25; }

/* Gesperrt heißt hier nicht „darf nicht", sondern „geht gerade nicht" —
   kein Beleg gedruckt, kein Bon offen, mit PIN angemeldet. Der Grund
   steht in der Unterzeile, deshalb bleibt die lesbar, während der Rest
   zurücktritt. */
.blatt-kachel:disabled {
  cursor: not-allowed;
  background: #fbfbfc;
  border-style: dashed;
}
.blatt-kachel:disabled .kachel-titel { color: var(--grau); }
.blatt-kachel:disabled svg { stroke: #9ca3af; }

.blatt-leer {
  color: var(--grau);
  font-size: 14px;
  padding: 12px;
}

/* --- Die Belegliste --------------------------------------------------- */

.belegliste { width: min(640px, 100%); }

.belegsuche { display: flex; gap: 8px; }
.belegsuche input { flex: 1; min-width: 0; }

.belegzeile {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 48px;
  padding: 8px 10px;
  border: 1px solid var(--rand);
  border-radius: 5px;
  background: #fff;
}

.belegzeile-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.belegzeile-kopf  { font-weight: 600; }
.belegzeile-unter {
  font-size: 13px;
  color: var(--grau);
  font-variant-numeric: tabular-nums;
}
.belegzeile-knoepfe { display: flex; gap: 6px; flex: none; }

.belegblaettern {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 13px;
  color: var(--grau);
}

/* Kleine Knöpfe auf hellem Grund. NICHT `.knopf.schmal` nehmen: Die
   Klasse ist für den dunklen Kopfbalken gemacht und schreibt weiße
   Schrift auf durchsichtigem Grund — in einer weißen Liste wäre sie
   unsichtbar. */
.knopf.klein {
  padding: 7px 12px;
  font-size: 13px;
  min-height: 40px;
}
.knopf.klein.rot { border-color: var(--rot); color: var(--rot); }
.knopf.klein.rot:hover { background: var(--rot-hell); }

.preis-zahl {
  flex: none;
  font-weight: 700;
  font-size: 17px;
  font-variant-numeric: tabular-nums;
}

/* --- Schmale Bildschirme ---------------------------------------------
   Auf einem Handy wird aus der seitlichen Schublade dasselbe Blatt von
   unten: 460 px Spalte neben 375 px Bildschirm ergäbe eine Schublade,
   die den Bildschirm ganz ausfüllt und trotzdem seitlich angeschlagen
   ist — mit einem Schatten dort, wo nichts mehr ist. */
@media (max-width: 780px) {
  .blatt.lage-seite {
    margin-top: auto;
    width: 100%;
    height: auto;
    max-height: 85vh;
    border-right: none;
    border-top: 1px solid var(--rand);
  }
  .blatt-raster { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }

  /* Das Mindestmaß für Touch (§ 11) gilt auch für die zwei
     Sinnbildknöpfe im Kopf. Sie sind sonst 40 px — auf einem
     Zeigergerät genug, unter dem Finger nicht. */
  .kopf .sinnbildknopf { width: 48px; height: 48px; }

  /* Die Zeile bricht um, statt die Knöpfe aus dem Bild zu schieben. */
  .belegzeile { flex-wrap: wrap; }
}

/* =====================================================================
   Der Tischplan
   =====================================================================

   Kein Dialog, sondern der Ruhezustand der Oberfläche im Gastrobetrieb:
   Er liegt beim Öffnen der Kasse über allem und geht zu, sobald ein
   Tisch angetippt ist. Deshalb `inset: 0` und kein Kasten in der Mitte.

   Die Kacheln sind für den Daumen gebaut, nicht für die Maus: Ein
   belegter Tisch trägt Nummer, Betrag und Dauer übereinander, und die
   Farbe sagt den Zustand schon aus zwei Metern Entfernung. */

.tischplan {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  background: var(--hell);
}

/* `[hidden]` gegen ein eigenes `display` — dieselbe Stelle, an der die
   Kasse schon dreimal nachlegen musste (.overlay[hidden], .blatt-overlay
   [hidden], .bondrucker[hidden]). Das Attribut setzt `display: none` nur
   im Vorgabestil des Browsers; jede eigene `display`-Angabe gewinnt
   dagegen. Ohne diese vier Zeilen bleibt der Tischplan beim Schliessen
   stehen und „Zum Bon" ist sichtbar, obwohl kein Bon laeuft. */
.tischplan[hidden],
.tischplan-flaeche[hidden],
.tischplan-liste[hidden],
.tischplan .knopf[hidden] { display: none; }

.tischplan-kopf {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tischplan-marke { display: flex; justify-content: center; }

/* Das Firmenzeichen ist für den dunklen Kopfbalken gebaut (weißer
   Kasten, weißer Platzhaltertext). Auf der hellen Tischplan-Fläche
   (--hell) braucht der Kasten einen sichtbaren Rand, und der
   Platzhalterbuchstabe dunkle statt weißer Farbe — sonst verschwindet
   beides auf hellem Grund. Dieselbe Umkehr gilt für den Zahnradknopf
   (`.sinnbildknopf`) unten in den Werkzeugen, der sonst weiß auf weiß
   wäre. */
.tischplan-kopf .firmenzeichen {
  border: 1px solid #e5e7eb;
}
.tischplan-kopf .firmenzeichen.leer {
  background: #fff;
  border: 1px dashed var(--grau);
  color: var(--dunkel);
}
.tischplan-kopf .sinnbildknopf {
  color: var(--dunkel);
  border-color: #d1d5db;
}
.tischplan-kopf .sinnbildknopf:hover { background: rgba(0, 0, 0, 0.05); }
.tischplan-kopf .sinnbildknopf[aria-expanded="true"] {
  background: var(--dunkel);
  color: #fff;
  border-color: var(--dunkel);
}

.tischplan-werkzeugzeile {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.tischplan-reiter { display: flex; flex-wrap: wrap; gap: 6px; flex: 1; }

.tischplan-reiter-knopf {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  font-size: 15px;
}

.tischplan-reiter-knopf.aktiv { background: var(--dunkel); color: #fff; }

.tischplan-reiter-zahl {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border-radius: 10px;
  background: var(--gelb);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
}

.tischplan-stand { font-size: 15px; font-weight: 600; color: var(--dunkel); }
.tischplan-werkzeuge { display: flex; gap: 6px; }

/* Die Fläche. Wie im Editor: Seitenverhältnis aus dem Raster, Höhe über
   die Breite begrenzt — mit `max-height` gewönne die Breite, und eine
   Rastereinheit wäre kein Quadrat mehr. */
.tischplan-flaeche {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  overflow: auto;
}

/* Die Obergrenze der Breite setzt kasse.js aus der TATSAECHLICHEN Hoehe
   des Platzes darueber (`tischplanEinpassen`) und nicht als `vh`: Kopf-
   und Fusszeile nehmen sich, was sie brauchen, und wie viel das ist,
   haengt an der Zahl der Bereichsreiter. Mit einem festen `vh`-Anteil
   lief die Buehne unten aus dem Bild — gemessen 648 px hoch bei 411 px
   Platz. */
.tischplan-buehne {
  position: relative;
  width: 100%;
  min-width: 240px;
  background-color: #fff;
  background-image:
    repeating-linear-gradient(to right,
      var(--rand) 0 1px, transparent 1px calc(100% / var(--spalten))),
    repeating-linear-gradient(to bottom,
      var(--rand) 0 1px, transparent 1px calc(100% / var(--zeilen)));
  border: 2px solid var(--dunkel);
  border-radius: 8px;
}

.tischplan-objekt {
  position: absolute;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  margin: 0;
  padding: 0;
  border: 2px solid var(--grau);
  border-radius: 5px;
  background: #e5e7eb;
  font-family: inherit;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.05;
  color: var(--dunkel);
  overflow: hidden;
}

.tischplan-objekt.rund { border-radius: 50%; }

.tischplan-objekt.art-tresen { background: #fde68a; border-color: #b45309; }
.tischplan-objekt.art-wand   { background: var(--dunkel); border-color: var(--dunkel); }
.tischplan-objekt.art-tuer   { background: #fff; border-color: var(--dunkel); border-style: dashed; }
.tischplan-objekt.art-flaeche{ background: #d1fae5; border-color: #047857; }
.tischplan-objekt.art-text {
  background: transparent;
  border-color: transparent;
  color: var(--grau);
  font-weight: 700;
}

/* Frei, belegt, liegengeblieben — die drei Zustände, um die es geht.
   Nicht nur über die Farbe: Wer rot-grün nicht unterscheidet, liest den
   Betrag und die Randstärke (2px frei, 3px belegt) — der Betrag steht
   auf einem freien Tisch gar nicht erst da. Volle statt blasser Füllung,
   damit Grün/Rot auch quer durch den Raum zu erkennen sind — dafür
   Schrift in Weiß statt --dunkel, sonst verschwindet sie auf der
   satten Fläche. */
.tischplan-objekt.frei {
  background: var(--gruen);
  border-color: #065f46;
  color: #fff;
  cursor: pointer;
}

.tischplan-objekt.frei .tischplan-plaetze { color: rgba(255, 255, 255, 0.85); }

.tischplan-objekt.belegt {
  background: var(--rot);
  border-color: #7f1d1d;
  border-width: 3px;
  color: #fff;
  cursor: pointer;
}

.tischplan-objekt.belegt .tischplan-zeit { color: rgba(255, 255, 255, 0.85); }

/* Liegengeblieben überschreibt Grün/Rot mit Gelb und muss darum auch
   die Schriftfarbe zurückdrehen — sonst bliebe sie vom .belegt-Weiß
   auf der blassen --gelb-hell-Fläche kaum lesbar. */
.tischplan-objekt.liegt {
  background: var(--gelb-hell);
  border-color: var(--gelb);
  color: var(--dunkel);
}

.tischplan-objekt.liegt .tischplan-zeit { color: var(--grau); }

/* Der Tisch, dessen Bon gerade offen in der Bonspalte steht. */
.tischplan-objekt.aktiv { outline: 4px solid var(--gruen); outline-offset: 2px; }

.tischplan-objekt.frei:active,
.tischplan-objekt.belegt:active { transform: scale(0.97); }

.tischplan-objekt:focus-visible { outline: 4px solid var(--gelb); outline-offset: 2px; }

.tischplan-nummer  { font-size: 17px; }
.tischplan-betrag  { font-size: 13px; font-weight: 600; }
.tischplan-zeit    { font-size: 11px; font-weight: 400; color: var(--grau); }
.tischplan-plaetze { font-size: 11px; font-weight: 400; color: var(--grau); }
.tischplan-text    { pointer-events: none; }

.tischplan-leer {
  max-width: 460px;
  margin: auto;
  padding: 20px;
  text-align: center;
  color: var(--grau);
}

/* Die Liste — auf dem Handy die Vorgabe. */
.tischplan-liste {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.tischplan-zeile {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  padding: 12px 14px;
  border: 2px solid var(--rand);
  border-radius: 8px;
  background: #fff;
  font-family: inherit;
  font-size: 15px;
  text-align: left;
  cursor: pointer;
}

.tischplan-zeile.belegt { border-color: var(--rot); background: var(--rot-hell); }

.tischplan-zeile-links,
.tischplan-zeile-rechts { display: flex; flex-direction: column; gap: 2px; }
.tischplan-zeile-rechts { align-items: flex-end; }

.tischplan-zeile-nummer { font-weight: 700; font-size: 16px; }
.tischplan-zeile-bereich { font-size: 12px; color: var(--grau); }
.tischplan-zeile-betrag { font-weight: 700; font-size: 16px; }
.tischplan-zeile-zeit { font-size: 12px; color: var(--grau); }
.tischplan-zeile-frei { font-size: 14px; color: var(--grau); }

.tischplan-fuss { font-size: 12px; color: var(--grau); text-align: center; }

/* Der Weg zurück auf die Fläche, über dem Bon. */
.tischplanknopf {
  width: 100%;
  margin-bottom: 8px;
  padding: 10px;
  font-size: 15px;
  font-weight: 600;
  background: var(--dunkel);
  color: #fff;
  border-color: var(--dunkel);
}

@media (max-width: 780px) {
  .tischplan { padding: 8px; gap: 8px; }
  .tischplan-fuss { display: none; }
}

/* =====================================================================
   Rechnung teilen
   =====================================================================

   Zwei Spalten nebeneinander, auf schmalen Geräten untereinander. Eine
   Fläche und kein Dialog: Bei acht Positionen wäre ein Kasten in der
   Mitte entweder zu klein zum Treffen oder so groß, dass er ohnehin die
   Seite füllt. */

.teilen {
  position: fixed;
  inset: 0;
  z-index: 95;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  background: var(--hell);
}

.teilen[hidden] { display: none; }

.teilen-kopf { display: flex; align-items: center; gap: 8px; }
.teilen-kopf h2 { flex: 1; font-size: 18px; }

.teilen-spalten {
  flex: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  min-height: 0;
}

.teilen-spalte {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: #fff;
  border: 2px solid var(--rand);
  border-radius: 8px;
  overflow: hidden;
}

.teilen-spalte h3 {
  padding: 8px 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--grau);
  background: var(--hell);
  border-bottom: 1px solid var(--rand);
}

.teilen-liste {
  flex: 1;
  overflow-y: auto;
  list-style: none;
  margin: 0;
  padding: 6px;
}

.teilen-zeile { display: flex; gap: 6px; margin-bottom: 6px; }

/* Die ganze Zeile ist der Knopf — am Tresen wird mit dem Daumen
   getroffen, nicht mit dem Mauszeiger. */
.teilen-nehmen {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px;
  border: 1px solid var(--rand);
  border-radius: 6px;
  background: #fff;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.teilen-nehmen:hover { background: var(--hell); }
.teilen-nehmen:active { transform: scale(0.99); }

.teilen-text { flex: 1; }
.teilen-betrag { font-weight: 600; white-space: nowrap; }

/* Der Mengensteller. Nur da, wo mehr als eines auf der Zeile steht. */
.teilen-einzeln {
  width: 52px;
  border: 1px solid var(--dunkel);
  border-radius: 6px;
  background: #fff;
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

.teilen-einzeln:hover { background: var(--hell); }

.teilen-leer {
  padding: 14px 12px;
  color: var(--grau);
  font-size: 13px;
}

.teilen-summe {
  display: flex;
  justify-content: space-between;
  padding: 10px 12px;
  border-top: 2px solid var(--rand);
  font-size: 16px;
  font-weight: 600;
}

.teilen-summe.stark { background: var(--dunkel); color: #fff; font-size: 18px; }

.teilen-fuss { display: flex; align-items: center; gap: 12px; }
.teilen-fuss p { flex: 1; font-size: 13px; color: var(--grau); }
.teilen-fuss .knopf { min-width: 200px; }

@media (max-width: 780px) {
  .teilen-spalten { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
  .teilen-fuss { flex-direction: column; align-items: stretch; }
  .teilen-fuss .knopf { min-width: 0; }
}
