@import url("/static/fonts/fonts.css");

/* ---------------------------------------------------------------------------
   Mittagessen – Design System
   Anthroposophisches Bild in Material-Struktur: warme, lasierte Erdpigmente,
   humanistische Schrift, keine rechten Winkel, weiche warme Elevation.
   Tokens 1:1 aus dem Design-System-Projekt „Mittagessen Design System".
   --------------------------------------------------------------------------- */

/* Baar Antropos (Lutz Baar, nach Steiners Formenlehre) – Display-Schrift.
   Nur ein Schnitt; Fett wird synthetisiert. Selbst gehostet, keine externen
   Dienste (siehe DATENSCHUTZ.md). */
@font-face {
  font-family: "Baar Antropos";
  src: url("/static/fonts/antropos.woff2") format("woff2"),
       url("/static/fonts/antropos.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* --- Farbe: warmer Grund, Kirchgrün, vier Lasur-Akzente --- */
:root {
  --green-800: #1f5238;
  --green-700: #2e6b4c;
  --green-600: #3f8060;
  --green-200: #a9cdb6;
  --green-100: #dfeee2;
  --green-050: #eef6ee;

  --ochre-800: #7d5a12;
  --ochre-600: #c08a25;
  --ochre-200: #e8cd92;
  --ochre-100: #f8ecce;

  --terra-800: #8e3a2b;
  --terra-700: #ab4835;
  --terra-200: #e0aa9c;
  --terra-100: #f8e2d9;

  --lapis-700: #3a5878;
  --lapis-200: #b8c8db;
  --lapis-100: #e3eaf2;

  --plum-700: #6a4664;
  --plum-100: #efe4ee;

  --paper-050: #f6f3ec;
  --paper-075: #f1ede4;
  --paper-100: #faf7f1;
  --paper-200: #ece6d9;
  --paper-300: #ded8ca;
  --paper-400: #c6bfad;
  --paper-500: #b4ac98;
  --white: #fffdf9;

  --ink-900: #231f1a;
  --ink-800: #2f2a24;
  --ink-700: #4a443b;
  --ink-600: #6f6759;
  --ink-500: #8b8375;

  /* --- Schrift --- */
  --font-display: "Baar Antropos", "Alegreya", "Palatino Linotype", Georgia, serif;
  --font-ui: "Alegreya Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: ui-monospace, monospace;

  --text-display: 2rem;
  --text-h1: 1.6rem;
  --text-h2: 1.2rem;
  --text-body: 1.05rem;
  --text-kassen: 1.2rem;
  --text-checkbox: 1.25rem;
  --text-muted: 0.95rem;
  --text-small: 0.875rem;
  --text-badge: 0.8rem;
  --text-hint: 0.78rem;

  --leading-tight: 1.2;
  --leading-body: 1.55;

  --weight-normal: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;
  --weight-display: 600;
  --tracking-display: 0;
  --tracking-code: 0.06em;

  /* --- Maß: rem-Brüche, kein 4px-Raster --- */
  --content-max: 900px;
  --narrow-max: 480px;
  --page-pad: 1rem;
  --card-pad: 1rem;

  /* --- Form: nichts hat rechte Winkel --- */
  --radius-xs: 8px;
  --radius-sm: 10px;
  --radius-md: 16px;
  --radius-lg: 24px;
  --radius-xl: 32px;
  --radius-pill: 999px;

  /* --- Elevation: Material-Stufen, Schatten warm-braun statt schwarz --- */
  --elevation-0: none;
  --elevation-1: 0 1px 2px rgba(47, 42, 36, .06), 0 1px 3px 1px rgba(47, 42, 36, .05);
  --elevation-2: 0 1px 2px rgba(47, 42, 36, .07), 0 2px 6px 2px rgba(47, 42, 36, .06);
  --elevation-3: 0 4px 8px 3px rgba(47, 42, 36, .07), 0 1px 3px rgba(47, 42, 36, .08);
  --elevation-4: 0 6px 10px 4px rgba(47, 42, 36, .08), 0 2px 3px rgba(47, 42, 36, .08);

  /* --- Bewegung: wächst und legt sich, nichts schnappt --- */
  --ease-standard: cubic-bezier(.2, 0, 0, 1);
  --dur-short: 150ms;
  --dur-medium: 250ms;

  /* --- Semantische Namen: diese in Komponenten benutzen --- */
  --surface-page: var(--paper-050);
  --surface-card: var(--white);
  --surface-inset: var(--paper-200);
  --surface-panel: var(--paper-100);
  --surface-brand: var(--green-700);

  --text-default: var(--ink-800);
  --text-subtle: var(--ink-600);
  --text-faint: var(--ink-500);
  --text-on-brand: var(--white);
  --text-nav-on-brand: var(--green-050);
  --text-link: var(--green-700);
  --text-link-hover: var(--green-800);
  --text-heading: var(--green-800);
  --text-positive: var(--green-700);
  --text-negative: var(--terra-700);

  --border-card: var(--paper-300);
  --border-field: var(--paper-400);
  --border-table: var(--paper-200);
  --border-cut: var(--ink-500);
  --border-focus: var(--green-600);

  --action-primary-bg: var(--green-700);
  --action-primary-fg: var(--white);
  --action-default-bg: var(--white);
  --action-default-border: var(--paper-400);
  --action-danger-fg: var(--terra-700);

  --state-layer-ink: rgba(47, 42, 36, .08);
  --state-layer-light: rgba(255, 253, 249, .14);

  --elevation-card: var(--elevation-1);
  --elevation-card-hover: var(--elevation-2);
  --elevation-bar: var(--elevation-2);
  --elevation-raised: var(--elevation-3);

  --status-ok-bg: var(--green-100);
  --status-ok-border: var(--green-200);
  --status-ok-fg: var(--green-800);
  --status-warn-bg: var(--ochre-100);
  --status-warn-border: var(--ochre-200);
  --status-warn-fg: var(--ochre-800);
  --status-error-bg: var(--terra-100);
  --status-error-border: var(--terra-200);
  --status-error-fg: var(--terra-800);
  --status-info-bg: var(--lapis-100);
  --status-info-border: var(--lapis-200);
  --status-info-fg: var(--lapis-700);
  --status-neutral-bg: var(--paper-200);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font-ui);
  font-size: var(--text-body);
  background: var(--surface-page);
  color: var(--text-default);
  line-height: var(--leading-body);
}

main {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: var(--page-pad);
}

/* Überschriften in der Display-Schrift, im dunklen Grün */
h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  letter-spacing: var(--tracking-display);
  line-height: var(--leading-tight);
  color: var(--text-heading);
}

h1 { font-size: var(--text-h1); margin: 0.9rem 0 0.8rem; }
h2 { font-size: var(--text-h2); margin: 0 0 0.5rem; }
h3 { font-size: var(--text-body); margin: 0 0 0.4rem; }

a { color: var(--text-link); text-decoration: none; }
a:hover { color: var(--text-link-hover); text-decoration: underline; }

:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }

/* --- Topbar: grünes Band mit Elevation, Marke in der Display-Schrift --- */
.topbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  background: var(--surface-brand);
  color: var(--text-on-brand);
  padding: 0.7rem 1.15rem;
  box-shadow: var(--elevation-bar);
  position: relative;
  z-index: 1;
}

.topbar .brand {
  color: var(--text-on-brand);
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--text-h1);
  letter-spacing: var(--tracking-display);
  line-height: var(--leading-tight);
  text-decoration: none;
}
.topbar .brand:hover { color: var(--text-on-brand); text-decoration: none; }

.topbar nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.9rem;
}

.topbar nav a { color: var(--text-nav-on-brand); text-decoration: none; }
.topbar nav a:hover { color: var(--text-nav-on-brand); text-decoration: underline; }

/* Trennt Alltag von Verwaltung, ohne eine Linie zu ziehen */
.topbar nav .nav-sep {
  width: 1px;
  height: 1.1rem;
  background: var(--state-layer-light);
}

/* --- Klappmenü der Küche ---
   Vier Oberkategorien statt zwölf gleichrangiger Links. Als <details>, damit es
   ohne JavaScript funktioniert; das name-Attribut macht daraus ein Akkordeon,
   bei dem sich die anderen schließen. */
.topbar .menue { position: relative; }
.topbar .menue > summary {
  list-style: none;
  cursor: pointer;
  color: var(--text-nav-on-brand);
  padding: 0.1rem 0.1rem;
  white-space: nowrap;
}
.topbar .menue > summary::-webkit-details-marker { display: none; }
/* Ein kleiner Winkel sagt „hier ist mehr“ – ohne eine Icon-Sprache zu erfinden */
.topbar .menue > summary::after {
  content: " ⌄";
  opacity: 0.7;
}
.topbar .menue[open] > summary { text-decoration: underline; }
.topbar .menue > summary:hover { text-decoration: underline; }

/* Der rote Punkt an „Familien“ und an „Meldungen der Eltern“: wie viele
   Meldungen auf eine Antwort warten.

   Mit Zahl darin, nicht als blanker Punkt. Der Unterschied zwischen einer
   wartenden Meldung und zwölf ist der zwischen „gleich erledigt“ und „dafür
   setze ich mich hin“ – und beim Blick aufs Menü ist das die Frage.

   Rot und rund genügen nicht allein: Wer Farben schlecht unterscheidet, sieht
   die Zahl, und das title-Attribut nennt sie im Klartext. */
.topbar .punkt,
.menue-inhalt .punkt {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.15rem;
  height: 1.15rem;
  margin-left: 0.35rem;
  padding: 0 0.3rem;
  border-radius: 999px;
  background: #b3261e;
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1;
  vertical-align: text-top;
}

.menue-inhalt {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 20;
  margin-top: 0.45rem;
  min-width: 12rem;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.5rem;
  background: var(--surface-card);
  border: 1px solid var(--border-card);
  border-radius: var(--radius-md);
  box-shadow: var(--elevation-raised);
}
/* .topbar nav a faerbt hellgruen fuer den gruenen Balken – im aufgeklappten
   Menue liegt der Text aber auf Weiss. Die Regel muss die Balken-Regel
   ueberbieten, sonst ist das Menue unlesbar: zwei Klassen gegen eine. */
.topbar .menue-inhalt a {
  color: var(--text-default);
  padding: 0.35rem 0.6rem;
  border-radius: var(--radius-xs);
  white-space: nowrap;
}
.topbar .menue-inhalt a:hover {
  background: var(--surface-inset);
  color: var(--text-link-hover);
  text-decoration: none;
}

/* --- Navigation auf schmalen Schirmen ---
   Vorher griff die Umstellung erst unter 700px. Dazwischen – und das ist die
   Breite eines quer gehaltenen Telefons oder eines schmalen Fensters – standen
   vier Klappmenüs in mehreren Zeilen, das aufgeklappte legte sich über die
   Seite, und weil die Kopfzeile ihre Kinder auseinanderschiebt, lagen die
   Punkte über die ganze Breite verstreut.

   Jetzt wird die Navigation unter 900px zu einer Liste: untereinander, volle
   Breite, nichts überlappt. Der Schalter „Menü“ hält sie zusammengeklappt –
   sichtbar nur, wenn JavaScript ihn zeigt (siehe header.ejs). */
.nav-schalter {
  display: none;
  background: none;
  border: 1px solid var(--state-layer-light);
  border-radius: var(--radius-xs);
  color: var(--text-on-brand);
  font: inherit;
  cursor: pointer;
  padding: 0.35rem 0.7rem;
}
.nav-schalter::after { content: " ⌄"; opacity: 0.7; }
.nav-schalter[aria-expanded='true']::after { content: " ⌃"; }

@media (max-width: 900px) {
  .topbar { align-items: center; }
  /* :not([hidden]) – sonst überbietet diese Regel das hidden-Merkmal, und der
     Schalter erschiene auch ohne JavaScript, ohne etwas tun zu können. */
  .nav-schalter:not([hidden]) { display: inline-flex; }

  .topbar[data-nav='zu'] nav { display: none; }
  .topbar nav {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    gap: 0;
    margin-top: 0.3rem;
  }
  /* Fingerbreite Ziele statt Textzeilen */
  .topbar nav > a,
  .topbar .menue > summary { padding: 0.6rem 0.15rem; }
  .topbar nav .nav-sep { width: 100%; height: 1px; margin: 0.35rem 0; }
  /* Der Abmelden-Knopf ist ein Knopf und stand deshalb um seine eigene
     Polsterung eingerückt – in einer Liste fällt das auf. */
  .topbar nav form.inline { padding: 0.45rem 0; }
  .topbar nav form.inline button.linklike { padding-left: 0; padding-right: 0; }

  /* Das Untermenü schiebt die Liste auseinander, statt sich darüberzulegen */
  .menue-inhalt {
    position: static;
    box-shadow: none;
    border: none;
    background: var(--state-layer-light);
    margin: 0.1rem 0 0.4rem;
  }
  .topbar .menue-inhalt a { color: var(--text-on-brand); padding: 0.55rem 0.7rem; }
  .topbar .menue-inhalt a:hover { background: var(--state-layer-light); color: var(--text-on-brand); }
}

/* --- Karte: die eine Fläche --- */
.card {
  background: var(--surface-card);
  border: 1px solid var(--border-card);
  border-radius: var(--radius-md);
  box-shadow: var(--elevation-card);
  padding: var(--card-pad);
  margin: 0 0 1rem;
  transition: box-shadow var(--dur-medium) var(--ease-standard);
}

.card.narrow, .narrow { max-width: var(--narrow-max); }

/* Anmelde-/Registrier-Panel: die größte Rundung im System */
.card.panel {
  border-radius: var(--radius-xl);
  padding: 1.5rem;
  margin-top: 1.5rem;
}

/* --- Formulare: Label über dem Feld, blockweise, keine Floating Labels --- */
label { display: block; margin: 0.6rem 0; }
label.inline { display: inline-block; margin-right: 0.8rem; }

input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="date"], input[type="time"], select {
  display: block;
  width: 100%;
  padding: 0.45rem 0.55rem;
  margin-top: 0.2rem;
  border: 1px solid var(--border-field);
  border-radius: var(--radius-sm);
  background: var(--surface-card);
  color: var(--text-default);
  font: inherit;
}

input:focus, select:focus { border-color: var(--border-focus); }

label.inline input[type="checkbox"] { display: inline; width: auto; }
input[type="checkbox"] { accent-color: var(--green-700); }

.row { display: flex; gap: 0.8rem; }
.row label { flex: 1; }

.row-form { display: flex; gap: 0.4rem; align-items: center; }
.row-form input { margin-top: 0; }

/* Die Betreuungstage beim Anlegen eines Kindes.
   Zwei Zeilen, in denen Mo bis Fr untereinander stehen müssen – sonst liest
   man sie nicht als dieselbe Woche. Ohne feste Breiten rutscht die zweite
   Zeile gegen die erste, weil „Nachmittagsbetreuung“ länger ist als
   „Kernzeit“; und .row label { flex: 1 } streckt die Häkchen zusätzlich. */
.tage-wunsch { border: 1px solid #e2e2e2; border-radius: 8px; padding: .8rem 1rem; margin: 1rem 0; }
.tage-wunsch legend { padding: 0 .4rem; font-weight: 600; }
.tage-wunsch .row { align-items: center; flex-wrap: wrap; gap: .4rem; margin: .5rem 0 .9rem; }
/* Der Name steht über seiner Zeile, nicht daneben. Daneben passte er in die
   schmale Karte nur, solange „Nachmittagsbetreuung“ kurz genug war – beim
   ersten Blick auf dem Telefon rutschte der Freitag in die nächste Zeile.
   Über der Zeile beginnen beide Wochen an derselben Kante. */
.tage-wunsch .tage-name { flex: 1 0 100%; font-weight: 600; }
.tage-wunsch .row label.inline { flex: 0 0 3.4rem; margin-right: 0; }

/* Dieselben Wochentage in der Verwaltung (Meldungen der Eltern). Dort ist die
   Karte breit, und .row label { flex: 1 } zieht fünf Häkchen über die ganze
   Zeile auseinander – Mo und Fr stehen dann handbreit voneinander entfernt und
   man zählt beim Lesen mit dem Finger. */
.tage-reihe { align-items: center; flex-wrap: wrap; gap: .4rem; }
.tage-reihe label.inline { flex: 0 0 3.4rem; margin-right: 0; }
.tage-reihe > .muted { flex: 0 0 9.5rem; }

/* Betreuungstage melden: je Kind ein Aufklapper, unter der Tabelle statt in
   einer Zelle. In der Zelle quetschte sich die Woche auf Spaltenbreite, der
   Freitag brach um und die Zeile wurde dreimal so hoch wie die übrigen. */
.tage-melden { margin-top: 1.2rem; }
.tage-melden h3 { margin-bottom: .2rem; }
.tage-melden details { border-top: 1px solid #ececec; padding: .5rem 0; }
.tage-melden summary { cursor: pointer; font-weight: 600; }
.tage-melden .tage-wunsch { max-width: 26rem; }
input.short { width: 9rem; }

/* --- Knöpfe: 10px Radius, warmer State-Layer, Elevation nur bei primary --- */
button {
  font: inherit;
  font-weight: var(--weight-medium);
  line-height: 1.2;
  padding: 0.5rem 1.1rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--action-default-border);
  background: var(--action-default-bg);
  color: var(--text-default);
  cursor: pointer;
  transition:
    box-shadow var(--dur-medium) var(--ease-standard),
    background-color var(--dur-short) var(--ease-standard),
    color var(--dur-short) var(--ease-standard);
}

button:hover { background-image: linear-gradient(var(--state-layer-ink), var(--state-layer-ink)); }

button.primary {
  background: var(--action-primary-bg);
  border-color: var(--action-primary-bg);
  color: var(--action-primary-fg);
  box-shadow: var(--elevation-1);
}
button.primary:hover {
  box-shadow: var(--elevation-card-hover);
  background-image: linear-gradient(var(--state-layer-light), var(--state-layer-light));
}
button.primary:active { box-shadow: var(--elevation-1); }

button.danger {
  border-color: var(--action-danger-fg);
  color: var(--action-danger-fg);
  background: var(--action-default-bg);
}
button.danger:hover { background: var(--status-error-bg); background-image: none; }

button.linklike {
  background: none;
  border: none;
  box-shadow: none;
  color: var(--text-nav-on-brand);
  padding: 0.25rem 0.35rem;
  text-decoration: none;
}
button.linklike:hover { background-image: none; text-decoration: underline; }

form.inline { display: inline-flex; gap: 0.4rem; align-items: center; }

/* --- Kassen-Tasten: ein Tipp in der Mittagsschlange --- */
.preset-row { display: inline-flex; flex-wrap: wrap; gap: 0.6rem; margin: 0.4rem 0.6rem 0.5rem 0; }

button.preset {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
  min-width: 6.5rem;
  padding: 0.7rem 1.1rem;
  /* Beträge stehen in der UI-Schrift – Antropos ist dafür zu unruhig
     und kennt kein Euro-Zeichen. */
  font-size: 1.3rem;
  font-weight: var(--weight-bold);
  background: var(--action-primary-bg);
  border-color: var(--action-primary-bg);
  color: var(--action-primary-fg);
  box-shadow: var(--elevation-1);
}
button.preset:hover {
  box-shadow: var(--elevation-card-hover);
  background-image: linear-gradient(var(--state-layer-light), var(--state-layer-light));
}
button.preset:active { box-shadow: var(--elevation-1); }

button.preset small {
  font-size: var(--text-hint);
  font-weight: var(--weight-normal);
  opacity: 0.85;
}

button.preset.preset-kaution {
  background: var(--surface-card);
  border-color: var(--action-default-border);
  color: var(--text-heading);
}
button.preset.preset-kaution:hover {
  background-image: linear-gradient(var(--state-layer-ink), var(--state-layer-ink));
}

/* --- Chips: Schnellauswahl in dichten Zeilen (8px, nicht Pille) --- */
.chip-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-top: 0.7rem; }

.chip {
  display: inline-block;
  padding: 0.3rem 0.8rem;
  border: 1px solid var(--green-200);
  border-radius: var(--radius-xs);
  background: var(--status-ok-bg);
  color: var(--status-ok-fg);
  text-decoration: none;
  transition: background-color var(--dur-short) var(--ease-standard), color var(--dur-short) var(--ease-standard);
}
.chip:hover { background: var(--surface-brand); color: var(--text-on-brand); text-decoration: none; }

/* --- Tabellen: nur Grundlinien, keine Zebras, keine Senkrechten --- */
table { width: 100%; border-collapse: collapse; }
th, td {
  text-align: left;
  padding: 0.4rem 0.5rem;
  border-bottom: 1px solid var(--border-table);
  vertical-align: middle;
}
th { font-weight: var(--weight-semibold); }
td.num, th.num { text-align: right; }
td.checkbox-cell { font-size: var(--text-checkbox); width: 2rem; }

/* --- Flash: die einzige Rückmeldung, einmal pro Seite --- */
.flash {
  padding: 0.8rem 1.1rem;
  border-radius: var(--radius-md);
  box-shadow: var(--elevation-card);
  margin-bottom: 1rem;
}
.flash-success { background: var(--status-ok-bg); border: 1px solid var(--status-ok-border); }
.flash-error { background: var(--status-error-bg); border: 1px solid var(--status-error-border); }
.flash-warn { background: var(--status-warn-bg); border: 1px solid var(--status-warn-border); }
.flash-info { background: var(--status-info-bg); border: 1px solid var(--status-info-border); }

/* --- Badges: Zustand als Wort, nicht als Zeichen --- */
.badge {
  display: inline-block;
  padding: 0.1rem 0.6rem;
  border-radius: var(--radius-pill);
  font-size: var(--text-badge);
  font-weight: var(--weight-medium);
  background: var(--status-neutral-bg);
  color: var(--text-default);
}
.badge-ok { background: var(--status-ok-bg); color: var(--status-ok-fg); }
.badge-warn { background: var(--status-warn-bg); color: var(--status-warn-fg); }
.badge-error { background: var(--status-error-bg); color: var(--status-error-fg); }
.badge-info { background: var(--status-info-bg); color: var(--status-info-fg); }

.muted { color: var(--text-subtle); font-size: var(--text-muted); }
.neg { color: var(--text-negative); }
.pos { color: var(--text-positive); }

/* --- Tag und Kind --- */
.day-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.7rem;
  margin-bottom: 0.4rem;
}
.day-head .menu { font-style: italic; }
.day.closed { opacity: 0.65; }

.child-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.25rem 0;
}
.child-name { min-width: 10rem; }


/* --- Kassen-Nummer: zum Vorzeigen und Vorlesen --- */
.kassen-nummer {
  font-family: var(--font-mono);
  font-size: var(--text-kassen);
  background: var(--surface-inset);
  padding: 0.1rem 0.5rem;
  border-radius: var(--radius-sm);
}

.kasse-forms { display: flex; flex-wrap: wrap; gap: 1.2rem; }

/* Breite Tabellen scrollen in sich, nie die ganze Seite */
.tabellenrahmen { overflow-x: auto; }

/* Zugangszettel zum Ausdrucken und Mitgeben */
.zettel { max-width: 15cm; }
.zettel th { width: 12rem; color: var(--text-subtle); font-weight: var(--weight-normal); }
.zettel .zugang-wert { font-weight: var(--weight-semibold); }
.zettel table { margin: 0.6rem 0; }

/* --- Aufklappbares: alles Seltene liegt dahinter --- */
details { margin: 0.4rem 0; }
details summary { cursor: pointer; padding: 0.2rem 0; color: var(--text-link); }
details summary:hover { text-decoration: underline; }
details form { margin: 0.4rem 0 0.8rem; padding-left: 0.4rem; border-left: 3px solid var(--border-card); }

fieldset {
  border: 1px solid var(--border-card);
  border-radius: var(--radius-sm);
  margin: 0.5rem 0;
}
legend { color: var(--text-subtle); font-size: var(--text-muted); }

.list-head { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; }

.footer {
  text-align: center;
  color: var(--text-faint);
  font-size: var(--text-small);
  padding: 1.5rem 0 2rem;
}
.footer a { color: var(--text-faint); text-decoration: underline; }
.footer a:hover { color: var(--text-link-hover); }

/* --- Gutschein-Druck: gestrichelte Schnittkante bleibt --- */
.voucher-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.6rem;
}

.voucher {
  border: 1px dashed var(--border-cut);
  border-radius: var(--radius-sm);
  padding: 0.7rem;
  text-align: center;
  background: var(--surface-card);
  page-break-inside: avoid;
  break-inside: avoid;
  /* Text links, Prüf-QR rechts – der QR braucht Ruhe um sich, sonst liest
     ihn die Kamera schlecht. */
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.voucher-haupt { flex: 1 1 auto; }
.voucher-pruefung { flex: 0 0 5.4rem; }
.voucher-pruefung svg.qr { display: block; width: 100%; height: auto; }
.voucher-pruefung .voucher-hint { margin-top: 0.15rem; }

.voucher-title { font-weight: var(--weight-medium); }
.voucher-value {
  font-size: 1.3rem;
  font-weight: var(--weight-bold);
  margin: 0.2rem 0;
}
.voucher-code {
  font-family: var(--font-mono);
  font-size: 1.05rem;
  letter-spacing: var(--tracking-code);
}
.voucher-hint { font-size: var(--text-hint); color: var(--text-subtle); margin-top: 0.3rem; }

/* ---------------------------------------------------------------------------
   Der Monatsplan
   Eine Kreuztabelle: links die Essenstage, rechts je Kind eine Spalte. Die
   Regel für die Farbe ist eng: Grün heißt „isst mit“ – sonst nichts. Die Form
   sagt, wer entschieden hat: Quadrat die Eltern, Kreis das Nachmi-Abo.
   --------------------------------------------------------------------------- */

.zeile-guthaben {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 1.5rem;
  align-items: baseline;
  margin: 0;
}
.zeile-guthaben b { font-size: 1.15rem; color: var(--ink-900); }
.zeile-guthaben .klein { font-size: var(--text-muted); color: var(--text-subtle); }

/* Zeitraumwahl: Monat blättern oder auf die laufende Woche springen */
.zeitraum {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.9rem;
  padding: 0.6rem 0.9rem;
  margin-bottom: 1rem;
  background: var(--surface-panel);
  border: 1px solid var(--border-card);
  border-radius: var(--radius-md);
}
.zeitraum .monat {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-display);
  font-size: var(--text-h2);
  color: var(--text-heading);
}
.zeitraum .pfeil {
  width: 2rem;
  height: 2rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--action-default-border);
  border-radius: var(--radius-pill);
  background: var(--surface-card);
  color: var(--text-default);
  text-decoration: none;
  line-height: 1;
}
.zeitraum .pfeil:hover { background: var(--surface-inset); text-decoration: none; }
.zeitraum .chips { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.zeitraum .chip {
  border: 1px solid var(--action-default-border);
  background: var(--surface-card);
  color: var(--text-default);
  border-radius: var(--radius-pill);
  font-size: var(--text-muted);
}
.zeitraum .chip:hover { background: var(--surface-inset); color: var(--text-default); }
.zeitraum .chip[aria-current="page"] {
  background: var(--status-ok-bg);
  border-color: var(--status-ok-border);
  color: var(--status-ok-fg);
  font-weight: var(--weight-semibold);
}
.zeitraum .grenze { margin-left: auto; font-size: var(--text-small); color: var(--text-faint); }
.zeitraum.kindwahl { margin-top: -0.6rem; }

.plan-rahmen {
  border: 1px solid var(--border-card);
  border-radius: var(--radius-md);
  background: var(--surface-card);
  overflow-x: auto;
  box-shadow: var(--elevation-card);
}
table.plan { font-size: var(--text-body); }
table.plan th, table.plan td { border-bottom: none; }
table.plan thead th {
  background: var(--surface-panel);
  border-bottom: 1px solid var(--border-card);
  font-size: var(--text-hint);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-subtle);
  vertical-align: bottom;
}
table.plan thead th.kind { text-align: center; width: 7.5rem; }
table.plan thead th.kind b {
  display: block;
  font-size: var(--text-body);
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-900);
}
table.plan thead th.kind i {
  display: block;
  font-style: normal;
  font-size: var(--text-hint);
  font-weight: var(--weight-normal);
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-faint);
}
table.plan tr.woche th, table.plan tr.woche td {
  background: var(--paper-075);
  border-top: 1px solid var(--border-card);
  border-bottom: 1px solid var(--border-table);
  padding: 0.3rem 0.5rem;
}
table.plan tr.woche th {
  font-size: var(--text-hint);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
}
table.plan tr.woche td { text-align: center; }
button.alle {
  font-size: var(--text-hint);
  color: var(--text-link);
  background: none;
  border: none;
  box-shadow: none;
  padding: 0.1rem 0.3rem;
  text-decoration: underline;
  min-height: 0;
}
button.alle:hover { background: none; color: var(--text-link-hover); }
table.plan tr.tag { border-top: 1px solid var(--border-table); }
table.plan tr.tag:hover { background: var(--paper-100); }
table.plan td.datum { white-space: nowrap; }
table.plan td.menu { color: var(--text-default); }
table.plan td.zelle { text-align: center; padding: 0.25rem; }
table.plan tr.heute { background: rgba(248, 236, 206, 0.45); }
table.plan tr.heute td.datum b { color: var(--ochre-800); }
table.plan tr.heute td.datum::after {
  content: "heute";
  display: block;
  font-size: var(--text-hint);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ochre-800);
}
table.plan tr.abgesagt td.menu s { color: var(--text-faint); }
table.plan tr.abgesagt td.menu .grund {
  display: inline-block;
  margin-left: 0.4rem;
  font-size: var(--text-badge);
  background: var(--status-error-bg);
  border: 1px solid var(--status-error-border);
  color: var(--status-error-fg);
  border-radius: var(--radius-pill);
  padding: 0 0.55rem;
}
/* Zwei Speisepläne, zwei Reiter. Der gewählte trägt den Rahmen der Tabelle
   weiter, damit er wie ein Reiter an einer Mappe wirkt und nicht wie ein
   zweiter Knopf. */
.plan-reiter {
  display: flex;
  gap: 0.3rem;
  margin-bottom: -1px;
}
.plan-reiter .reiter {
  padding: 0.5rem 0.9rem;
  border: 1px solid var(--border-card);
  border-bottom-color: transparent;
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  background: var(--surface-inset);
  color: var(--text-subtle);
  font-size: var(--text-muted);
  text-decoration: none;
}
.plan-reiter .reiter:hover { background: var(--surface-card); }
.plan-reiter .reiter[aria-selected='true'] {
  background: var(--surface-card);
  border-bottom-color: var(--surface-card);
  color: var(--text-default);
  font-weight: var(--weight-medium);
}
.plan-reiter .reiter-preis {
  margin-left: 0.4rem;
  font-size: var(--text-hint);
  color: var(--text-faint);
}

/* Gericht und Allergene sind eine Angabe, nicht zwei Spalten: nebeneinander,
   solange Platz ist, darunter auf dem Telefon. */
.menu-felder { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.menu-felder .menufeld { flex: 1 1 12rem; }
input.allergenfeld {
  flex: 0 1 7rem;
  font-size: var(--text-muted);
}
input.preisfeld { width: 4.5rem; text-align: right; }
/* „sichern“ steht in der Zeile, weil der offene Plan kein ⋯-Menü hat. Klein:
   die Eingabetaste tut dasselbe. */
button.zeile-speichern {
  margin-left: 0.4rem;
  padding: 0.2rem 0.5rem;
  font-size: var(--text-hint);
}

.strich { color: var(--paper-500); }

/* Die Marke: eine gewöhnliche Checkbox, selbst gezeichnet. Der Haken ist ein
   eingebettetes SVG – kein externer Dienst, keine Ikonenschrift. */
input.mark {
  appearance: none;
  -webkit-appearance: none;
  width: 2.1rem;
  height: 2.1rem;
  margin: 0;
  padding: 0;
  vertical-align: middle;
  border: 1.5px solid var(--action-default-border);
  background: var(--surface-card);
  cursor: pointer;
  transition: background-color var(--dur-short) var(--ease-standard),
    border-color var(--dur-short) var(--ease-standard),
    transform var(--dur-short) var(--ease-standard);
}
input.mark--kernzeit { border-radius: 6px; }
input.mark--abo { border-radius: 50%; border-width: 2.5px; border-color: var(--paper-500); }
input.mark:checked {
  background-color: var(--action-primary-bg);
  border-color: var(--action-primary-bg);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 8.5l3.2 3.2L13 4.8' fill='none' stroke='%23fffdf9' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 1.05rem;
}
/* Der Abo-Kreis bekommt innen einen Rand: gesetzt, aber nicht von Hand.
   Ohne ihn sind Kreis und Quadrat bei dieser Größe kaum zu unterscheiden. */
input.mark--abo:checked { box-shadow: inset 0 0 0 2.5px var(--white); }

/* Der Rückweg auf dem Anwesenheitsbogen: ein sichtbarer Löschknopf, der einen
   versehentlich gesetzten Haken zurücknimmt. Er ersetzt das frühere leere
   Radiofeld, das wie eine vierte Antwort aussah. Bewusst unauffällig – grau und
   gestrichelt, mit Wort und Undo-Zeichen (↺), damit klar ist: „damit lösche ich
   meinen Eintrag“. */
.zuruecknehmen {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
  width: 100%;
  padding: 0.25rem 0.15rem;
  border: 1px dashed var(--paper-500);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-subtle);
  font-size: var(--text-hint);
  line-height: 1.1;
  cursor: pointer;
  transition: background-color var(--dur-short) var(--ease-standard),
    border-color var(--dur-short) var(--ease-standard),
    color var(--dur-short) var(--ease-standard);
}
.zuruecknehmen .zuruecknehmen-icon { font-size: 1.15em; line-height: 1; }
.zuruecknehmen:hover {
  background: var(--surface-panel);
  border-color: var(--action-default-border);
  color: var(--ink-700);
}
.zuruecknehmen:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }

/* „Wird noch gebucht“ gegen „ist abgerechnet“.
   Grün bleibt Grün – die Regel „isst mit“ wird nicht angetastet. Was sich
   ändert, ist die Fläche: schräg gestreift heißt, das Geld ist noch nicht
   bewegt. Die Automatik bucht erst zum Anmeldeschluss. */
input.mark--kommt:checked {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 8.5l3.2 3.2L13 4.8' fill='none' stroke='%23fffdf9' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"),
    repeating-linear-gradient(135deg,
      rgba(255, 253, 249, .00) 0, rgba(255, 253, 249, .00) 4px,
      rgba(255, 253, 249, .42) 4px, rgba(255, 253, 249, .42) 8px);
  background-repeat: no-repeat, repeat;
  background-position: center, center;
  background-size: 1.05rem, auto;
}
input.mark:hover:not(:disabled) { transform: scale(1.06); }
input.mark:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }
input.mark:disabled { cursor: default; opacity: 0.45; border-style: dashed; }
input.mark.geaendert { box-shadow: 0 0 0 3px var(--ochre-200); }
input.mark--abo.geaendert:checked { box-shadow: inset 0 0 0 2.5px var(--white), 0 0 0 3px var(--ochre-200); }

/* Die Leiste bleibt am unteren Rand stehen, damit „speichern“ nicht wegscrollt */
.aktionsleiste {
  position: sticky;
  bottom: 0;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1.2rem;
  margin-top: 1rem;
  padding: 0.7rem 1rem;
  border-radius: var(--radius-md);
  background: var(--surface-panel);
  border: 1px solid var(--border-card);
  color: var(--text-subtle);
  box-shadow: var(--elevation-bar);
}
.aktionsleiste .bilanz { font-size: var(--text-muted); }
.aktionsleiste .knoepfe { margin-left: auto; display: flex; gap: 0.5rem; align-items: center; }
.aktionsleiste.leiste--offen {
  background: var(--green-800);
  border-color: var(--green-800);
  color: var(--green-050);
}
.aktionsleiste.leiste--offen .bilanz { color: var(--white); }
.knopf {
  border-radius: var(--radius-pill);
  padding: 0.45rem 1.2rem;
}
.knopf--haupt { background: var(--action-primary-bg); color: var(--action-primary-fg); border-color: var(--action-primary-bg); }
.leiste--offen .knopf--haupt { background: var(--white); color: var(--green-800); border-color: var(--white); }
.knopf--still { background: transparent; border-color: var(--action-default-border); }
.leiste--offen .knopf--still { color: var(--green-100); border-color: rgba(255, 253, 249, 0.35); }

/* Küchenansicht: dieselbe Monatsform, statt der Kinder die Zahlen.
   Der Rahmen darf hier nicht clippen – sonst schneidet er die ⋯-Klappe ab. */
.plan-rahmen.offen { overflow: visible; }
table.plan.tage td.menu { width: 100%; }
input.menufeld {
  width: 100%;
  border: 1px solid transparent;
  border-radius: var(--radius-xs);
  background: var(--surface-panel);
  padding: 0.2rem 0.45rem;
  font-size: var(--text-muted);
  box-shadow: none;
}
input.menufeld:hover { border-color: var(--border-field); }
input.menufeld:focus { background: var(--surface-card); border-color: var(--border-focus); }
/* „sichern“ und ⋯ stehen nebeneinander, nicht übereinander: gestapelt macht
   der Knopf jede Zeile der Tabelle um eine Zeilenhöhe länger, und bei
   zwanzig Essenstagen im Monat ist das ein Bildschirm mehr zum Scrollen. */
.mehr-spalte {
  width: 6.5rem;
  position: relative;
  white-space: nowrap;
  text-align: right;
}
.mehr-spalte > details.mehr { display: inline-block; vertical-align: middle; }
.mehr-spalte > button.zeile-speichern { vertical-align: middle; }
details.mehr > summary {
  list-style: none;
  cursor: pointer;
  color: var(--text-subtle);
  padding: 0 0.4rem;
  border-radius: var(--radius-xs);
}
details.mehr > summary::-webkit-details-marker { display: none; }
details.mehr > summary:hover { background: var(--surface-inset); }
.mehr-inhalt {
  position: absolute;
  right: 0;
  z-index: 10;
  width: min(22rem, calc(100vw - 3rem));
  /* Die Zelle darüber steht auf nowrap, damit „sichern“ und ⋯ nebeneinander
     bleiben. Ohne diese Zeile erbt der Aufklapper das: Kein Text bricht mehr
     um, die Breite oben wird wirkungslos, und der Kasten schiebt sich über den
     rechten Rand der Seite hinaus. */
  white-space: normal;
  margin-top: 0.3rem;
  padding: 0.9rem;
  text-align: left;
  background: var(--surface-card);
  border: 1px solid var(--border-card);
  border-radius: var(--radius-md);
  box-shadow: var(--elevation-raised);
}
.mehr-inhalt hr { border: none; border-top: 1px solid var(--border-table); margin: 0.8rem 0; }
.mehr-inhalt form { margin-bottom: 0.6rem; }
.mehr-inhalt .muted { font-size: var(--text-hint); }

/* Die Ausnahme: eingeklappt und nicht einladend. Sie soll gefunden werden, wenn
   man sie sucht – nicht ins Auge fallen, wenn man die Liste liest. */
.card.ausnahme { border-color: var(--ochre-200); }
.card.ausnahme > details > summary {
  cursor: pointer;
  color: var(--ochre-800);
  font-size: var(--text-muted);
}
.card.ausnahme > details[open] > summary { margin-bottom: 0.8rem; }
.grund-text { display: block; font-size: var(--text-hint); font-style: italic; }
.ausnahmen-liste { margin: 0.5rem 0 0; padding-left: 1.2rem; font-size: var(--text-muted); }
.ausnahmen-liste li { margin: 0.2rem 0; }

/* --- Add-on Betreuung: Mitteilungen --- */
.hinweis-tage { display: grid; gap: 0.35rem; }
.hinweis-tag { padding: 0.3rem 0.5rem; border-radius: var(--radius-xs); }
.hinweis-tag.heute { background: rgba(248, 236, 206, 0.5); }
.hinweis-tag > label {
  display: grid;
  gap: 0.2rem 0.8rem;
  grid-template-columns: 1fr;
  align-items: center;
  margin: 0;
}
@media (min-width: 640px) {
  .hinweis-tag > label { grid-template-columns: 13rem 1fr; }
}
.hinweis-datum {
  display: flex;
  gap: 0.4rem;
  align-items: baseline;
  flex-wrap: wrap;
  font-size: var(--text-muted);
}
.hinweis-datum .muted { font-size: var(--text-hint); }
.hinweis-quelle { display: block; font-size: var(--text-hint); padding-left: 0.5rem; }
/* Auf der Tagesliste: die Mitteilung ist der wichtigste Text der Zeile, nicht
   eine Randnotiz – die Betreuung liest sie im Vorbeigehen. */
.hinweis-text {
  display: block;
  font-size: var(--text-muted);
  color: var(--lapis-700);
  font-style: italic;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Zwei Flex-Elemente je Zeile: das Zeichen und der Text. Der Text muss in ein
   eigenes span – sonst wird jedes <strong> darin zu einem eigenen Element und
   die Zeile fällt in Spalten auseinander. */
.legende p {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  margin: 0.5rem 0;
  font-size: var(--text-muted);
  color: var(--text-subtle);
}
.legende p > span:last-child { flex: 1 1 auto; }
/* Erläuterungen ohne Zeichen davor sind gewöhnlicher Fließtext – im Flex-Fluss
   würde ihr <strong> zum eigenen Element und die Zeile in Spalten zerfallen. */
.legende p.muted { display: block; }
/* In der Legende sind die Marken Schaubilder, keine gesperrten Felder. Die
   Abblendung für :disabled würde genau das unsichtbar machen, worum es geht –
   die Streifung. */
.legende input.mark:disabled {
  opacity: 1;
  border-style: solid;
  cursor: default;
}
/* Im Flex-Fluss würde die Marke sonst zum Oval gequetscht */
.legende .mark { flex: 0 0 auto; }
.legende .strich { flex: 0 0 2.1rem; text-align: center; font-size: 1.3rem; }
.legende .mark-legende-form {
  flex: 0 0 2.1rem;
  text-align: center;
  font-size: 1.1rem;
  color: var(--text-faint);
  white-space: nowrap;
}

@media (max-width: 600px) {
  table.plan td.menu { font-size: var(--text-small); }
  table.plan thead th.kind { width: 4.5rem; }
  .zeitraum .grenze { margin-left: 0; width: 100%; }
}

/* --- Anwesenheit: derselbe Bogen auf Papier und auf dem Schirm ---
   Der Ausdruck muss allein als Nachweis taugen. Deshalb hat er Kästchen zum
   Ankreuzen, eine Linie für die Uhrzeit und einen Kopf mit Datum und
   Unterschrift. Wer digital abhakt, druckt denselben Bogen ausgefüllt. */
.print-only { display: none; }
table.anwesenheit th.spalte-status, table.anwesenheit td.spalte-status {
  text-align: center;
  width: 4.5rem;
}
/* Die Löschknopf-Spalte braucht etwas mehr Breite als ein Kästchen: das Wort
   „zurücknehmen“ soll nicht zerbrechen. */
table.anwesenheit th.spalte-zurueck, table.anwesenheit td.spalte-zurueck { width: 5.5rem; }
table.anwesenheit th.spalte-ging, table.anwesenheit td.spalte-ging { width: 8rem; }
/* Kreuz und Uhrzeit gehören zusammen: „ging um 13:20“ ist eine Angabe, nicht
   zwei. Untereinander sähen sie aus wie zwei getrennte Fragen. */
.ging-paar { display: inline-flex; align-items: center; gap: 0.35rem; }
table.anwesenheit .zeitfeld { width: 4.2rem; text-align: center; font-size: var(--text-muted); }
table.anwesenheit input[type='radio'].mark { width: 1.6rem; height: 1.6rem; }
table.anwesenheit input[type='radio'].mark:checked {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 8.5l3.2 3.2L13 4.8' fill='none' stroke='%23fffdf9' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 0.9rem;
}
table.anwesenheit td .essen-marke { font-size: var(--text-hint); display: block; }
/* „kein Essen“ ist die Auskunft, die der Betreuung bisher fehlte – sie muss
   ins Auge fallen, ohne wie ein Fehler auszusehen. */
table.anwesenheit td .essen-marke--ohne { color: var(--ochre-800); font-weight: var(--weight-medium); }
.bogen-meta { width: 100%; margin-bottom: 0.6rem; }
.bogen-meta td { border: none; padding: 0.2rem 0.5rem 0.2rem 0; }
.linie {
  display: inline-block;
  min-width: 9rem;
  border-bottom: 1px solid var(--ink-700);
}

/* Beleg zur Bar-Aufladung – schmal wie ein Kassenbon, am Schirm gerahmt, auf
   dem Papier ohne Rahmen oben auf dem Blatt (siehe @media print). */
.beleg {
  max-width: 22rem;
  margin: 1rem 0;
  padding: 1.1rem 1.3rem;
  border: 1px solid var(--border-card);
  border-radius: var(--radius-md);
  background: var(--surface-card);
}
.beleg-kopf { display: flex; flex-direction: column; gap: 0.2rem; margin-bottom: 0.9rem; }
.beleg-kopf strong { font-size: 1.05rem; }
.beleg-zeilen { width: 100%; border-collapse: collapse; }
.beleg-zeilen th {
  text-align: left;
  font-weight: var(--weight-regular, normal);
  color: var(--text-subtle);
  padding: 0.35rem 0.6rem 0.35rem 0;
  white-space: nowrap;
  vertical-align: top;
  border: none;
}
.beleg-zeilen td { padding: 0.35rem 0; text-align: right; border: none; }
.beleg-fuss { margin-top: 1rem; font-size: var(--text-hint); line-height: 1.4; }

/* Der Beleg druckt als 80-mm-Kassenbon (Thermo-Bondrucker). Eigene benannte
   Seite, damit Anmeldezettel und Anwesenheitsbogen weiter auf normalem Papier
   bleiben. Greift die Regel nicht (z. B. Safari), gibt der auf 80 mm gestellte
   Bondrucker die Breite vor und der schmale Inhalt passt trotzdem. */
@page bon { size: 80mm auto; margin: 3mm; }

@media print {
  .topbar, .footer, .no-print, .flash { display: none !important; }
  /* Nur der Beleg – als schmaler Bon, oben auf dem Papier. */
  .beleg {
    page: bon;
    width: 72mm;
    margin: 0 auto;
    padding: 0;
    border: none;
    background: none;
    font-size: 11px;
    line-height: 1.35;
  }
  .beleg-kopf { text-align: center; margin-bottom: 0.5rem; }
  .beleg-kopf strong { font-size: 12px; }
  .beleg-zeilen th, .beleg-zeilen td { padding: 0.15rem 0; font-size: 11px; }
  .beleg-fuss { font-size: 9px; margin-top: 0.5rem; line-height: 1.3; }
  body { background: #fff; color: var(--ink-900); }
  .card { border: none; box-shadow: none; padding: 0.3rem 0; }
  main { max-width: none; padding: 0; }
  .voucher { box-shadow: none; }

  /* Der Bogen */
  .print-only { display: revert; }
  .bogen-kopf h1 { font-size: 1.3rem; margin: 0 0 0.4rem; }
  table.anwesenheit { font-size: 0.9rem; }
  table.anwesenheit th, table.anwesenheit td {
    border-bottom: 1px solid var(--ink-500);
    padding: 0.45rem 0.4rem;
  }
  /* Kästchen zum Ankreuzen – groß genug für einen Kugelschreiber */
  .kaestchen {
    display: inline-block;
    width: 1.1rem;
    height: 1.1rem;
    border: 1.2px solid var(--ink-800);
    text-align: center;
    line-height: 1;
    font-weight: var(--weight-bold);
  }
  .zeit-linie, .bem-linie {
    display: inline-block;
    min-width: 3.5rem;
    border-bottom: 1px solid var(--ink-500);
  }
  .bem-linie { min-width: 11rem; }
  .bogen-fuss { margin-top: 0.8rem; font-size: 0.8rem; }
  /* Jede Gruppe auf ein eigenes Blatt: die Pavillons sind zwei Orte.
     Leere Gruppen gar nicht drucken - ein Blatt "Keine Kinder" ist Verschwendung. */
  .card.bogen { break-before: page; }
  .card.bogen:first-of-type { break-before: auto; }
  .card.bogen--leer { display: none; }

  /* Kontostände-Sicherung: die Liste kann über mehrere Blätter laufen. Die
     Kopfzeile wiederholt sich, keine Familie wird an der Blattkante zerschnitten. */
  .kontostaende h1 { font-size: 1.3rem; margin: 0 0 0.3rem; }
  .kontostaende thead { display: table-header-group; }
  .kontostaende tr { break-inside: avoid; }
}

@media (max-width: 600px) {
  .row { flex-direction: column; gap: 0; }
  .child-name { min-width: 7rem; }
  .voucher-grid { grid-template-columns: 1fr; }
  .preset-row { display: flex; }
  button.preset { flex: 1; min-width: 5rem; }
}

/* Mitteilungen im Auftrag: kompakte Kreuztabelle Kind × Tag. Am Telefon zählt
   Übersicht, nicht Vollständigkeit – die nächsten drei Tage genügen. */
table.hinweis-tabelle { table-layout: fixed; }
table.hinweis-tabelle th { font-size: var(--text-small); }
table.hinweis-tabelle td input[type='text'] { width: 100%; font-size: var(--text-muted); }
table.hinweis-tabelle td:first-child, table.hinweis-tabelle th:first-child { width: 8rem; }

/* --- Startseite der Verwaltung: dieselben vier Bereiche wie im Klappmenü --- */
.heute-zahl { font-size: var(--text-h2); margin: 0.2rem 0 0.4rem; }
.heute-zahl strong { font-size: 1.6rem; color: var(--green-800); }
.bereiche { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 720px) { .bereiche { grid-template-columns: 1fr 1fr; } }
.card.bereich ul { margin: 0.4rem 0 0; padding-left: 1.1rem; }
.card.bereich li { margin: 0.3rem 0; font-size: var(--text-muted); }
.card.bereich li a { font-weight: var(--weight-semibold); }

/* --- Prüfkamera für Gutscheinkarten --- */
.pruef-video { width: 100%; max-width: 28rem; border-radius: var(--radius-md); margin-top: 0.6rem; }
.pruef-liste { display: grid; gap: 0.4rem; }
.pruef-zeile {
  padding: 0.6rem 0.9rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-card);
  background: var(--surface-card);
  font-weight: var(--weight-semibold);
}
.pruef-offen { background: var(--status-ok-bg); border-color: var(--status-ok-border); color: var(--status-ok-fg); }
.pruef-eingeloest { background: var(--surface-inset); color: var(--text-subtle); }
.pruef-gesperrt { background: var(--status-error-bg); border-color: var(--status-error-border); color: var(--status-error-fg); }
.pruef-unbekannt { background: var(--status-warn-bg); border-color: var(--status-warn-border); color: var(--status-warn-fg); }

/* --- Anmeldezettel: fürs Papier gestaltet, am Schirm eine Vorschau --- */
.zettel-bogen {
  background: var(--surface-card);
  border: 1px solid var(--border-card);
  border-radius: var(--radius-md);
  padding: 1.4rem;
  max-width: 46rem;
}
.zettel-kopf h1 { margin: 0 0 0.1rem; font-size: 1.35rem; }
.zettel-kopf p { margin: 0 0 0.9rem; color: var(--text-subtle); font-size: var(--text-small); }
table.zettel-felder { width: 100%; margin: 0.4rem 0; }
table.zettel-felder td { border-bottom: none; padding: 0.45rem 0.5rem 0.45rem 0; vertical-align: bottom; }
table.zettel-felder .feldname { white-space: nowrap; width: 1%; font-weight: var(--weight-semibold); }
table.zettel-felder .schmal { width: 8rem; }
.schreib-linie {
  display: inline-block;
  width: 100%;
  min-width: 6rem;
  border-bottom: 1px solid var(--ink-700);
  height: 1.3rem;
}
.schreib-linie.kurz { width: 6rem; min-width: 6rem; }
.ankreuz {
  display: inline-block;
  width: 1rem;
  height: 1rem;
  border: 1.2px solid var(--ink-800);
  vertical-align: text-bottom;
}
.zettel-hinweis { font-size: var(--text-hint); color: var(--text-subtle); margin: 0.3rem 0 0.8rem; }
.zettel-buero {
  border: 1px solid var(--border-card);
  border-radius: var(--radius-xs);
  background: var(--surface-panel);
  padding: 0.5rem 0.7rem;
  font-size: var(--text-small);
  margin: 0.6rem 0;
}
.zettel-schnitt {
  color: var(--text-faint);
  margin: 0.9rem 0;
  white-space: nowrap;
  overflow: hidden;
  font-size: var(--text-small);
}
.zettel-eltern h2 { font-size: 1.05rem; }
.zettel-eltern ul { margin: 0.4rem 0; padding-left: 1.2rem; }
.zettel-eltern li { margin: 0.35rem 0; font-size: var(--text-muted); }

@media print {
  .zettel-bogen { border: none; padding: 0; max-width: none; }
}

/* --- Essensausgabe: Zähler, Scanner-Feld, Liste --- */
.ausgabe-zaehler { display: flex; gap: 2rem; flex-wrap: wrap; margin-bottom: 0.4rem; }
.zaehler { display: flex; flex-direction: column; align-items: flex-start; }
.zaehler strong { font-size: 1.9rem; line-height: 1.1; }
.zaehler span { font-size: var(--text-small); color: var(--text-subtle); }
.zaehler--bereit strong { color: var(--green-800); }
.ausgabe-scan { display: flex; gap: 0.6rem; align-items: flex-end; flex-wrap: wrap; }
.ausgabe-scan .scan-feld { flex: 1; min-width: 12rem; margin: 0; }
.ausgabe-scan input[name='code'] {
  font-size: 1.25rem;
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
}
.ausgabe-suche { display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap; margin-bottom: 0.8rem; }
.ausgabe-suche input[type='search'] { flex: 1; min-width: 12rem; }
.nummer-zelle { font-variant-numeric: tabular-nums; white-space: nowrap; font-weight: var(--weight-semibold); }

/* --- Essenskarten: Scheckkartenformat, mehrere je Blatt --- */
.karten-bogen {
  display: grid;
  gap: 0.8rem;
  grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr));
}
.essenskarte {
  display: flex;
  gap: 0.8rem;
  align-items: center;
  justify-content: space-between;
  border: 1px solid var(--ink-700);
  border-radius: var(--radius-md);
  background: var(--surface-card);
  padding: 0.8rem 1rem;
  break-inside: avoid;
}
.essenskarte-text { display: flex; flex-direction: column; min-width: 0; }
.essenskarte-schule { font-size: var(--text-hint); color: var(--text-subtle); }
.essenskarte-name { font-size: 1.15rem; margin: 0.15rem 0 0; }
.essenskarte-klasse { font-size: var(--text-small); color: var(--text-subtle); }
.essenskarte-code {
  font-size: 1.3rem;
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  margin-top: 0.3rem;
}
.essenskarte-qr svg.qr { width: 6.5rem; height: 6.5rem; display: block; }

@media print {
  /* Scheckkartennähe: zwei Spalten, feste Kartenhöhe, Schnittkanten sichtbar */
  .karten-bogen { grid-template-columns: 1fr 1fr; gap: 0; }
  .essenskarte {
    border: 1px dashed var(--ink-500);
    border-radius: 0;
    height: 5.4cm;
    padding: 0.5cm;
  }
}

/* Untergeordneter Schalter in den Einstellungen (gehört zum Punkt darüber) */
.eingezogen { margin-left: 1.6rem; }

/* --- Einstellungen: ein Formular, in benannte Abschnitte geteilt ---
   Die Seite war schmal (die Karte trug „narrow“) und sehr lang. Jetzt nutzt sie
   die volle Inhaltsbreite und ist in Abschnitte mit Sprungmarken gegliedert. */

/* Schnellzugriff: Anker zu den Abschnitten, robust ohne JavaScript */
.sprungmenue {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 1rem;
  padding: 0.7rem 0.9rem;
  background: var(--surface-panel);
  border: 1px solid var(--border-card);
  border-radius: var(--radius-md);
}
.sprungmenue a {
  display: inline-block;
  padding: 0.3rem 0.85rem;
  border: 1px solid var(--green-200);
  border-radius: var(--radius-pill);
  background: var(--status-ok-bg);
  color: var(--status-ok-fg);
  font-size: var(--text-muted);
  text-decoration: none;
  transition: background-color var(--dur-short) var(--ease-standard), color var(--dur-short) var(--ease-standard);
}
.sprungmenue a:hover { background: var(--surface-brand); color: var(--text-on-brand); text-decoration: none; }

/* Ein Abschnitt: Überschrift plus Felder, durch eine dünne Linie abgesetzt.
   scroll-margin gibt der Sprungmarke etwas Luft nach oben. */
.einst-abschnitt {
  padding-bottom: 0.6rem;
  margin-top: 1.6rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--border-table);
  scroll-margin-top: 0.8rem;
}
.einst-abschnitt:first-of-type { margin-top: 0.4rem; padding-top: 0; border-top: none; }
.einst-abschnitt > h2 { margin-top: 0; }

/* Auf der breiten Seite müssen kurze Felder (Preis, Uhrzeit, Zahl) nicht die
   volle Zeile einnehmen; die Erläuterung daneben bleibt so besser lesbar. */
.einst-abschnitt input[type="text"],
.einst-abschnitt input[type="number"],
.einst-abschnitt input[type="time"] { max-width: 24rem; }

/* Die Allergen-Legende ist das einzige mehrzeilige Feld – hier bekommt das
   Textfeld dieselbe Anmutung wie die einzeiligen Eingaben. */
.einstellungen textarea {
  display: block;
  width: 100%;
  padding: 0.45rem 0.55rem;
  margin-top: 0.2rem;
  border: 1px solid var(--border-field);
  border-radius: var(--radius-sm);
  background: var(--surface-card);
  color: var(--text-default);
  font: inherit;
  line-height: var(--leading-body);
}
.einstellungen textarea:focus { border-color: var(--border-focus); }

/* Klasse auf dem Anmeldezettel: einkreisen statt schreiben */
.klassen-reihe { display: flex; flex-wrap: wrap; gap: 0.45rem; align-items: center; }
.klassen-zahl {
  display: inline-block;
  min-width: 1.7rem;
  padding: 0.15rem 0.3rem;
  border: 1px solid var(--ink-500);
  border-radius: 999px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  font-size: var(--text-small);
}
.klassen-zahl--wort { min-width: 0; padding: 0.15rem 0.7rem; }
/* Klassenzeile: das Label mittig zu den (ggf. zwei) Zeilen der Auswahl */
table.zettel-felder tr.klassen-zeile td { vertical-align: middle; }
/* Kästchen und Text bleiben zusammen, auch wenn die Zeile umbricht */
.ankreuz-reihe { display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; align-items: baseline; }
.ankreuz-reihe .wahl { white-space: nowrap; }

/* Name des Kindes berichtigen: Feld und Knopf in einer Zeile */
.namensform { display: flex; gap: 0.4rem; align-items: center; }
.namensform input[type='text'] { width: 9rem; min-width: 5rem; }
.namensform button { white-space: nowrap; }
.klasse-zelle { white-space: nowrap; }

/* Sicherheitsnetz gegen seitwärts laufende Seiten: Auf schmalen Schirmen
   scrollt eine breite Tabelle in sich, nicht die ganze Seite. Gilt nur dort –
   am Schreibtisch bleibt das Tabellenlayout unberührt. Wo schon ein
   .tabellenrahmen steht, ändert sich nichts. */
@media (max-width: 700px) {
  .card > table,
  .card > form > table { display: block; overflow-x: auto; }
}

/* Ein Knopf, der wie ein Verweis aussieht. Für Vorgänge, die in einer
   Tabellenzeile stehen und dort keinen Kasten gebrauchen können – „berichtigen“
   an der Kassenzeile, „bestätigen“ bei den Klassenmeldungen. Es bleibt ein
   Knopf: Er sendet ein Formular, und das gehört nicht in einen <a>. */
button.link-knopf {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: var(--text-link);
  text-decoration: underline;
  cursor: pointer;
  min-height: 0;
}
button.link-knopf:hover { color: var(--text-link-hover); }
button.link-knopf:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }


/* Der Anwesenheitsbogen hat eine Spalte mehr bekommen („muss gehen um“).
   Klasse und Uhrzeit dürfen deshalb nicht umbrechen: „2.“ über „Klasse“ ist
   auf einem Blatt, das im Vorbeigehen gelesen wird, schlicht unleserlich. */
table.anwesenheit td:nth-child(2),
table.anwesenheit .muss-gehen { white-space: nowrap; }
table.anwesenheit .muss-gehen { text-align: center; font-variant-numeric: tabular-nums; }

/* Öffentlicher Speiseplan (/speiseplan). Eine eigenständige, schlanke Seite –
   sie wird auf der Schul-Website in einen Rahmen gesetzt und trägt darum keine
   Navigation. Alle Stile stehen hier, weil die CSP keine style-Attribute und
   kein <style> im Dokument erlaubt. */
body.speiseplan-seite { background: #fff; }
.speiseplan { max-width: 40rem; margin: 0 auto; padding: 1rem 1.1rem 1.5rem; }
.speiseplan h1 { font-size: 1.35rem; margin: 0 0 1rem; }
.speiseplan-woche { margin-bottom: 1.4rem; }
.speiseplan-woche h2 { font-size: .95rem; margin: 0 0 .4rem; color: #4a6b3a; text-transform: uppercase; letter-spacing: .03em; }
/* Ein Tag als Block: oben der Wochentag, darunter die zwei Pläne nebeneinander.
   Auf schmalen Schirmen (Einbettung im iframe) brechen die Pläne untereinander. */
.sp-eintrag { border-top: 1px solid #ececec; padding: .55rem 0; }
.sp-kopf { margin-bottom: .35rem; }
.sp-tag { font-weight: 600; }
.sp-datum { font-size: .82rem; color: #999; font-weight: 400; margin-left: .5rem; }
.sp-preis { font-size: .8rem; color: #888; white-space: nowrap; margin-left: auto; }

/* Zwei Reiter ohne JavaScript: die Radio-Felder liegen unsichtbar vor den
   Knöpfen, der Geschwister-Selektor schaltet um. Unsichtbar heißt hier
   „für das Auge weg, für die Tastatur da“ – mit display:none wären sie nicht
   mehr anspringbar, und die Seite ließe sich ohne Maus nicht umschalten. */
.sp-radio {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}
/* Der Kontrast war zu schwach, um die Reiter überhaupt als Reiter zu
   erkennen: offen war weiß (#fff), geschlossen fast weiß (#f6f6f4), der Rand
   ein Hauch (#e2e2e2). Zwei oder drei Familien haben der Schulküche gemeldet,
   dass sie den zweiten Plan nie gesehen haben – auf der Schul-Website steht
   diese Seite in einem Rahmen, und wer den zweiten Reiter nicht sieht, hält
   den allgemeinen Plan für den einzigen.

   Jetzt trägt die Leiste eine durchgehende grüne Linie, der offene Reiter
   sitzt gefüllt darauf und der geschlossene daneben ist deutlich abgesetzt.
   Die Linie ist das Stück, das aus zwei Kästchen eine Reiterleiste macht. */
/* Umbrechen statt quetschen: Auf einem schmalen Telefon passen „Speiseplan“
   und „Mittagstisch Klasse 1–4“ nicht nebeneinander. Ohne wrap schrumpfen
   beide, bis der Text in sich umbricht – zwei zerrissene Laschen. */
.sp-knoepfe { display: flex; flex-wrap: wrap; gap: .25rem; border-bottom: 3px solid #4a6b3a; }
.sp-knoepfe label {
  padding: .55rem 1.1rem;
  border: 1px solid #b9c3ab;
  border-bottom: none;
  border-radius: 7px 7px 0 0;
  background: #e4e8dd;
  color: #3f4a37;
  font-size: .95rem;
  font-weight: 600;
  cursor: pointer;
}
.sp-knoepfe label:hover { background: #d6dccb; }
.sp-tafel { display: none; padding-top: 1rem; }
/* Welcher Reiter offen ist, entscheidet allein das angehakte Radio-Feld. */
#sp-tab-0:checked ~ .sp-knoepfe label[for="sp-tab-0"],
#sp-tab-1:checked ~ .sp-knoepfe label[for="sp-tab-1"] {
  background: #4a6b3a;
  border-color: #4a6b3a;
  color: #fff;
}
#sp-tab-0:checked ~ .sp-knoepfe label[for="sp-tab-0"]:hover,
#sp-tab-1:checked ~ .sp-knoepfe label[for="sp-tab-1"]:hover { background: #4a6b3a; }
#sp-tab-0:checked ~ .sp-tafel-0,
#sp-tab-1:checked ~ .sp-tafel-1 { display: block; }
/* Sichtbar, wohin die Tastatur gerade zeigt. */
.sp-radio:focus-visible ~ .sp-knoepfe label[for="sp-tab-0"],
.sp-radio:focus-visible ~ .sp-knoepfe label[for="sp-tab-1"] { outline: 2px solid #4a6b3a; outline-offset: 2px; }
.sp-eintrag .sp-kopf { display: flex; align-items: baseline; gap: .35rem; }
.sp-offen { color: #aaa; font-style: italic; }
.sp-allergene { display: block; font-size: .76rem; color: #b0b0b0; font-weight: 400; margin-top: .1rem; }
.ist-heute { background: #f3f7ee; }
/* Ein abgesagter Tag: die Gerichte bleiben lesbar (man will wissen, was
   ausfällt), aber sie sind erkennbar nicht das Angebot. */
.ist-abgesagt .sp-gericht { text-decoration: line-through; color: #999; }
.ist-abgesagt .sp-preis { text-decoration: line-through; }
.sp-abgesagt {
  margin-left: .5rem;
  padding: 0 .45rem;
  border-radius: 999px;
  background: #f7e7e4;
  border: 1px solid #e6c9c3;
  color: #8a3527;
  font-size: .76rem;
  font-weight: 600;
}
.speiseplan-legende { margin-top: 1.2rem; padding-top: 1rem; border-top: 1px solid #ececec; font-size: .88rem; color: #555; }
.speiseplan-legende h2 { font-size: .9rem; margin: 0 0 .35rem; }
.speiseplan-legende p { margin: 0; white-space: pre-line; }
.speiseplan-stand { margin-top: 1.4rem; font-size: .78rem; color: #b0b0b0; }
