:root {
  --color-bg: #f7f6f4;
  --color-surface: #ffffff;
  --color-border: #e0ddd8;
  --color-text: #2b2a28;
  --color-text-muted: #6b6862;
  --color-primary: #7a6a58;
  --color-primary-dark: #5f5343;
  --color-danger: #b3432b;
  --color-danger-bg: #fbe9e5;
  --color-warning: #a5760f;
  --color-warning-bg: #fbf1de;
  --radius: 10px;
  font-size: 18px;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: 'Segoe UI', Roboto, Arial, sans-serif;
  background: var(--color-bg);
  color: var(--color-text);
  line-height: 1.5;
}

a {
  color: var(--color-primary-dark);
}

.topnav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  padding: 0.75rem 1.5rem;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.topnav-links {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex-wrap: wrap;
}

.topnav .brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 600;
  font-size: 1.15rem;
  text-decoration: none;
  color: var(--color-text);
}

.topnav .brand-logo {
  max-height: 2rem;
  max-width: 9rem;
  object-fit: contain;
}

/* --- Benutzermenue oben rechts ------------------------------------------- */

.benutzermenue {
  position: relative;
}

.benutzermenue > summary {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.9rem;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  cursor: pointer;
  background: var(--color-surface);
  font-weight: 500;
  list-style: none;
}

.benutzermenue > summary::-webkit-details-marker {
  display: none;
}

.benutzermenue[open] > summary {
  background: var(--color-bg);
}

.benutzer-punkt {
  width: 0.75rem;
  height: 0.75rem;
  border-radius: 50%;
  flex: 0 0 auto;
}

.benutzermenue .pfeil {
  color: var(--color-text-muted);
  font-size: 0.8rem;
}

.benutzermenue-inhalt {
  position: absolute;
  right: 0;
  top: calc(100% + 0.35rem);
  z-index: 20;
  min-width: 14rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
  padding: 0.35rem;
  display: flex;
  flex-direction: column;
}

.benutzermenue-inhalt a,
.benutzermenue-inhalt button {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.65rem 0.85rem;
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--color-text);
  background: none;
  border: none;
  font: inherit;
  cursor: pointer;
}

.benutzermenue-inhalt a:hover,
.benutzermenue-inhalt button:hover {
  background: var(--color-bg);
}

.benutzermenue-inhalt form {
  border-top: 1px solid var(--color-border);
  margin-top: 0.35rem;
  padding-top: 0.35rem;
}

.topnav nav {
  display: flex;
  gap: 0.25rem;
  flex-wrap: wrap;
}

.topnav nav a {
  padding: 0.6rem 1rem;
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--color-text);
  font-weight: 500;
}

.topnav nav a:hover,
.topnav nav a.active {
  background: var(--color-primary-soft);
  color: var(--color-primary-dark);
}

/* Unterreiter innerhalb eines Hauptbereichs (z.B. Inventar). */
.unternavigation {
  display: flex;
  gap: 0.25rem;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--color-border);
  margin-bottom: 1.25rem;
}

.unternavigation a {
  padding: 0.6rem 1.1rem;
  text-decoration: none;
  color: var(--color-text-muted);
  font-weight: 500;
  border-bottom: 3px solid transparent;
  margin-bottom: -1px;
}

.unternavigation a:hover {
  color: var(--color-text);
}

.unternavigation a.active {
  color: var(--color-primary-dark);
  border-bottom-color: var(--color-primary);
}

.topnav .session {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  color: var(--color-text-muted);
}

/* Zwei Seitenbreiten. Welche Ansicht welche bekommt, steht an einer Stelle:
   src/layout.js. Hier stehen nur die Masse. */
main {
  margin: 0 auto;
  padding: 1.5rem;
}

/* SCHMAL: Formulare, Detailansichten, Fliesstext. Ueber diese Breite hinaus
   wird Lesen anstrengend, weil das Auge den naechsten Zeilenanfang sucht –
   und ein einzelnes Eingabefeld ueber einen ganzen 27-Zoll-Schirm wirkt
   verloren. */
main.schmal {
  max-width: 1100px;
}

/* BREIT: Listen und Tabellen. Sie nutzen die Fensterbreite mit etwas Abstand
   zum Rand, statt waagerecht zu scrollen, obwohl links und rechts Platz frei
   ist. Dieselbe Breite wie der Kalender. */
main.breit {
  max-width: none;
  padding-left: 2rem;
  padding-right: 2rem;
}

@media (max-width: 700px) {
  main.breit {
    padding-left: 1rem;
    padding-right: 1rem;
  }
}

h1 {
  font-size: 1.7rem;
  margin-top: 0;
}

h2 {
  font-size: 1.3rem;
}

.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 1.25rem;
  margin-bottom: 1.25rem;
}

.btn {
  display: inline-block;
  padding: 0.75rem 1.4rem;
  border-radius: var(--radius);
  border: none;
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  text-align: center;
}

.btn:hover {
  background: var(--color-primary-dark);
}

.btn.secondary {
  background: var(--color-surface);
  color: var(--color-text);
  border: 1px solid var(--color-border);
}

.btn.danger {
  background: var(--color-danger);
}

.btn-row {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}

form.inline {
  display: inline;
}

label {
  display: block;
  font-weight: 600;
  margin: 1rem 0 0.35rem;
}

input[type='text'],
input[type='password'],
input[type='email'],
input[type='tel'],
input[type='date'],
input[type='datetime-local'],
input[type='number'],
input[type='search'],
select,
textarea {
  width: 100%;
  padding: 0.65rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  font-size: 1rem;
  font-family: inherit;
  background: var(--color-surface);
  color: var(--color-text);
}

textarea {
  min-height: 5rem;
  resize: vertical;
}

.field-hint {
  color: var(--color-text-muted);
  font-size: 0.9rem;
  margin-top: 0.25rem;
}

.grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 1.5rem;
}

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

/* Tabellen bekommen einen Wrapper, der bei Platzmangel horizontal scrollt.
   Ohne ihn sprengt eine breite Tabelle die Karte, statt sich einzupassen. */
.tabelle-scroll {
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  /* Auf Touch-Geraeten mit Schwung scrollen */
  -webkit-overflow-scrolling: touch;
}

table {
  width: 100%;
  border-collapse: collapse;
  /* Bewusst KEIN min-width: max-content – sonst wuerde die Tabelle immer
     scrollen, auch wenn Umbrechen genuegt. Erst wenn selbst mit Umbruch kein
     Platz bleibt, greift das horizontale Scrollen des Wrappers. */
}

/* Schmale Bildschirme (Tablet hochkant, Handy): Eine Tabelle, die selbst mit
   Umbruch nicht in die Breite passt, muesste sonst seitlich gescrollt werden –
   Schaltflaechen am Zeilenende landen dann ausserhalb des Sichtbereichs.
   tabellen-stapeln.js erkennt genau diese Tabellen und setzt .gestapelt; hier
   werden sie dann zu Karten: Spaltenname links, Wert rechts, eine Zeile je Karte.
   Ohne JavaScript bleibt es beim horizontalen Scrollen des Wrappers – kein
   Rueckschritt gegenueber vorher. */
@media (max-width: 820px) {
  .tabelle-scroll.gestapelt table,
  .tabelle-scroll.gestapelt tbody,
  .tabelle-scroll.gestapelt tr,
  .tabelle-scroll.gestapelt td {
    display: block;
    width: 100%;
  }
  .tabelle-scroll.gestapelt thead {
    display: none;
  }
  .tabelle-scroll.gestapelt tr {
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 0.35rem 0.7rem;
    margin-bottom: 0.6rem;
  }
  .tabelle-scroll.gestapelt td {
    border: none;
    padding: 0.28rem 0;
    display: flex;
    gap: 0.9rem;
    justify-content: space-between;
    align-items: baseline;
    text-align: right;
  }
  .tabelle-scroll.gestapelt td[data-label]::before {
    content: attr(data-label);
    font-weight: 600;
    color: var(--color-text-muted);
    text-align: left;
    flex: 0 0 7.5rem;
  }
  /* Zellen ohne Spaltentitel (z. B. die reine Aktionsspalte) nehmen die
     volle Breite und richten links aus. */
  .tabelle-scroll.gestapelt td:not([data-label]) {
    justify-content: flex-start;
    text-align: left;
  }
}

/* Innerhalb einer Karte darf nichts ueber den Rand hinauslaufen. */
.card {
  overflow-wrap: anywhere;
}

th,
td {
  text-align: left;
  padding: 0.75rem;
  border-bottom: 1px solid var(--color-border);
  /* Nur ueberlange Woerter umbrechen (Chargennummern, E-Mail-Adressen).
     "anywhere" waere zu aggressiv und wuerde auch kurze Angaben wie ein
     Datum mitten entzweireissen. */
  overflow-wrap: break-word;
}

/* Angaben, die nie umbrechen duerfen, weil sie sonst unleserlich werden. */
td.nichts-umbrechen,
th.nichts-umbrechen {
  white-space: nowrap;
}

/* Aktionsspalten sollen ihre Schaltflaechen nicht umbrechen. */
td .btn-row {
  flex-wrap: nowrap;
}

td .btn {
  white-space: nowrap;
}

th {
  color: var(--color-text-muted);
  font-weight: 600;
  font-size: 0.9rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

tr.row-warning td {
  background: var(--color-warning-bg);
}

tr.row-danger td {
  background: var(--color-danger-bg);
}

.badge {
  display: inline-block;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 600;
}

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

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

.badge.muted {
  background: var(--color-bg);
  color: var(--color-text-muted);
}

.filter-bar {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  align-items: flex-end;
  margin-bottom: 1.25rem;
}

.filter-bar > div {
  flex: 1 1 200px;
}

.filter-bar label {
  margin-top: 0;
}

/* Schnellfilter: eine Reihe Schaltflaechen, die aktive ist hervorgehoben.
   Bewusst Links und kein Formular – so laesst sich ein Filter als Lesezeichen
   ablegen und die Zurueck-Taste tut, was sie soll. */
.schnellfilter {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0.75rem 0 1rem;
}

.schnellfilter .btn {
  padding: 0.35rem 0.8rem;
  font-size: 0.9rem;
}

.schnellfilter-zahl {
  display: inline-block;
  min-width: 1.4rem;
  margin-left: 0.3rem;
  padding: 0 0.35rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.12);
  font-size: 0.82rem;
  text-align: center;
}

/* Senkrechter Trenner zwischen zwei Umschaltergruppen in derselben Reihe. */
.schnellfilter-trenner {
  width: 1px;
  align-self: stretch;
  margin: 0 0.35rem;
  background: var(--color-border);
}

/* Mehrfachauswahl in der Schnellfilter-Reihe – sieht aus wie die
   Schaltflaechen daneben, ist aber eine Checkbox. */
.schnellfilter-haken {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  padding: 0.35rem 0.8rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  font-size: 0.9rem;
  font-weight: normal;
  cursor: pointer;
}

/* Fusszeile: unaufdringlich, aber lesbar. Sie steht auf jeder Seite – vor der
   Anmeldung nur mit der Versionsnummer. */
.seitenfuss {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  margin: 2.5rem auto 1.5rem;
  padding: 0 1rem;
  color: var(--color-text-muted);
  font-size: 0.8rem;
}

.seitenfuss-trenner {
  opacity: 0.6;
}

.seitenfuss .badge {
  font-size: 0.72rem;
}

/* Nur fuer Screenreader – sichtbar ist die Spalte durch ihren Inhalt. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.alert {
  padding: 1rem 1.25rem;
  border-radius: var(--radius);
  margin-bottom: 1rem;
}

.alert.danger {
  background: var(--color-danger-bg);
  color: var(--color-danger);
}

.alert.warning {
  background: var(--color-warning-bg);
  color: var(--color-warning);
}

/* Gelungen – bewusst gruen und nicht in der Akzentfarbe der Praxis: Diese
   Meldung sagt "fertig", und dafuer gibt es eine eingefuehrte Farbe. Sie
   kommt selten vor, deshalb faellt sie auch auf. */
.alert.erfolg {
  background: #e8f3ea;
  color: #2f6b3d;
}

.empty-state {
  color: var(--color-text-muted);
  padding: 2rem 0;
  text-align: center;
}

.login-wrap {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

.login-card {
  width: 100%;
  max-width: 380px;
}

/* Die vier Inventarmeldungen stehen in derselben Karte wie ihr Filter –
   getrennt war beim Umschalten nicht zu sehen, worauf sich die Auswahl
   auswirkt. Statt vier Karten also vier Gruppen mit einer Trennlinie. */
.warngruppen {
  display: grid;
  gap: 1.25rem;
  margin-top: 0.5rem;
}

.warngruppe + .warngruppe {
  padding-top: 1.25rem;
  border-top: 1px solid var(--color-border);
}

.warngruppe h3 {
  margin: 0 0 0.4rem;
  font-size: 1rem;
}

/* In einer eigenen Karte darf "nichts gefunden" Luft haben. Als eine von vier
   Gruppen untereinander reisst dieselbe Luft die Karte unnoetig auseinander. */
.warngruppe .empty-state {
  padding: 0.4rem 0;
  text-align: left;
}

/* Kurzer Hinweis neben den Filtern, waehrend im Hintergrund geladen wird. */
.filter-stand {
  align-self: center;
  color: var(--color-text-muted);
  font-size: 0.85rem;
}

ul.plain {
  list-style: none;
  padding: 0;
  margin: 0;
}

ul.plain li {
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--color-border);
}

ul.plain li:last-child {
  border-bottom: none;
}

.autocomplete-wrap {
  position: relative;
}

.autocomplete-results {
  display: none;
  position: absolute;
  z-index: 10;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  margin-top: 0.25rem;
  max-height: 260px;
  overflow-y: auto;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.08);
}

.autocomplete-item {
  padding: 0.65rem 0.9rem;
  cursor: pointer;
}

.autocomplete-item:hover,
.autocomplete-item.aktiv {
  background: var(--color-bg);
}

/* Tastaturauswahl deutlich abheben, damit erkennbar bleibt, was Enter
   uebernehmen wuerde. */
.autocomplete-item.aktiv {
  box-shadow: inset 3px 0 0 var(--color-primary);
  font-weight: 500;
}

.materials-table td,
.materials-table th {
  vertical-align: middle;
}

.materials-table input[type='number'] {
  width: 6.5rem;
}

/* --- Bereichsseite "Verwaltung" ------------------------------------------ */
.kachel-liste {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 0.75rem;
}

.kachel {
  display: block;
  padding: 0.9rem 1rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  text-decoration: none;
  color: inherit;
}

.kachel:hover {
  border-color: var(--color-primary);
  background: var(--color-primary-soft, var(--color-bg));
}

.kachel-titel {
  display: block;
  font-weight: 600;
  color: var(--color-primary-dark);
}

.kachel-text {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

/* --- Erste Schritte ------------------------------------------------------ */
.fortschritt {
  height: 0.7rem;
  border-radius: 999px;
  background: var(--color-border);
  overflow: hidden;
}

.fortschritt-balken {
  height: 100%;
  background: var(--color-primary);
  transition: width 0.2s;
}

.checkliste {
  list-style: none;
  margin: 0;
  padding: 0;
}

.checkliste li {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--color-border);
  flex-wrap: wrap;
}

.checkliste li:last-child {
  border-bottom: none;
}

.checkliste-haken {
  font-size: 1.2rem;
  line-height: 1.3;
  color: var(--color-text-muted);
}

.checkliste li.erledigt .checkliste-haken {
  color: #2c6e3f;
}

.checkliste-text {
  flex: 1 1 16rem;
}

.checkliste-text p {
  margin: 0.2rem 0 0;
}

.checkliste-aktion {
  flex: 0 0 auto;
}

.anleitung {
  padding-left: 1.3rem;
}

.anleitung li {
  margin-bottom: 0.6rem;
}

/* --- Handbuch ------------------------------------------------------------ */
.handbuch-liste,
.datei-liste {
  list-style: none;
  margin: 0;
  padding: 0;
}

.handbuch-liste li {
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--color-border);
}

.handbuch-liste li:last-child {
  border-bottom: none;
}

.handbuch-titel {
  font-weight: 600;
  margin-right: 0.5rem;
}

.handbuch-liste p {
  margin: 0.2rem 0 0;
}

.datei-liste li {
  padding: 0.4rem 0;
  display: flex;
  gap: 0.75rem;
  align-items: baseline;
  flex-wrap: wrap;
}

.version-block {
  padding: 0.75rem 0;
  border-top: 1px solid var(--color-border);
}

.version-block p {
  margin: 0 0 0.3rem;
}

/* --- Branding im Einstellungsformular ------------------------------------ */
.logo-vorschau {
  max-width: 100%;
  max-height: 5rem;
  /* Karierter Hintergrund macht Transparenz sichtbar. */
  background:
    repeating-conic-gradient(#eceae6 0% 25%, #ffffff 0% 50%) 50% / 16px 16px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 0.4rem;
}

.farbwahl {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.farbwahl input[type='color'] {
  width: 4rem;
  height: 2.6rem;
  padding: 0.2rem;
  margin: 0;
}

.farbe-probe {
  padding: 0.45rem 0.9rem;
  border-radius: var(--radius);
  font-weight: 500;
}

/* --- Anmeldeseite -------------------------------------------------------- */
.login-marke {
  text-align: center;
  margin-bottom: 1.25rem;
}

.login-logo {
  max-width: 100%;
  max-height: 5rem;
}

.login-praxis {
  margin: 0.5rem 0 0;
  font-weight: 600;
  color: var(--color-text-muted);
}

/* Zeilen ohne Inhalt zuruecknehmen, ohne sie zu verstecken. */
.gedimmt {
  opacity: 0.55;
}

/* Dokumentationsstatus eines Termins. Bewusst ein Symbol und kein Farbwechsel des Blocks:
   Die Blockfarbe steht fuer die Mitarbeiterin bzw. die Behandlungsart und
   darf nicht doppelt belegt werden. */
.doku-zeichen {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.05em;
  height: 1.05em;
  border-radius: 50%;
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1;
  vertical-align: baseline;
  flex: 0 0 auto;
}

.doku-zeichen.erledigt {
  color: #2c6e3f;
  background: rgba(44, 110, 63, 0.14);
}

.doku-zeichen.offen {
  color: #fff;
  background: var(--color-danger);
}


/* --- Notfallblock in der Patientenakte ------------------------------------ */
/* Steht ganz oben und ist farblich abgesetzt: Bei einem Zwischenfall muss der
   Blick sofort dort landen, ohne Suchen und ohne Scrollen. */
.notfallblock {
  background: #fdf6ec;
  border: 1px solid #e2c894;
  border-left: 6px solid var(--color-warning);
  border-radius: var(--radius);
  padding: 1rem 1.25rem;
  margin-bottom: 1.5rem;
}

.notfallblock h2 {
  margin: 0 0 0.6rem;
  font-size: 1.05rem;
}

/* Ohne Angaben bleibt der Block sichtbar, tritt aber zurueck – die
   Information "nichts erfasst" ist wichtig, aber kein Alarm. */
.notfallblock.leer {
  background: var(--color-surface);
  border-color: var(--color-border);
  border-left-color: var(--color-text-muted);
}

.notfall-leer {
  margin: 0;
  color: var(--color-text-muted);
}

.notfall-liste {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 0.75rem 1.5rem;
  margin: 0;
}

.notfall-liste dt {
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-text-muted);
}

.notfall-liste dd {
  margin: 0.15rem 0 0;
  font-size: 1.02rem;
  font-weight: 500;
  overflow-wrap: break-word;
}

.notfall-liste dd.ohne-angabe {
  font-weight: 400;
  color: var(--color-text-muted);
}

.notfall-anamnese {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-top: 1rem;
  padding-top: 0.85rem;
  border-top: 1px solid rgba(0, 0, 0, 0.08);
}

.notfall-anamnese .fehlt {
  color: var(--color-danger);
}

/* --- Verdeckte Angaben ---------------------------------------------------- */
/* Interne Notizen sind unscharf, bis jemand das Auge antippt. Gedacht fuer den
   Blick ueber die Schulter, wenn der Patient auf denselben Bildschirm schaut –
   KEIN Zugriffsschutz (der Text steht im Quelltext). */
.verdeckt {
  display: inline-flex;
  align-items: baseline;
  gap: 0.45rem;
  max-width: 100%;
}

.verdeckt-text {
  filter: blur(4.5px);
  /* Nicht markierbar, solange verdeckt – sonst liesse sich der Text durch
     Markieren doch lesen. */
  user-select: none;
  transition: filter 0.12s ease-out;
}

.verdeckt.offen .verdeckt-text {
  filter: none;
  user-select: text;
}

.verdeckt-schalter {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Grosszuegige Trefferflaeche fuer die Bedienung am Tablet. */
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: 50%;
  background: var(--color-surface);
  cursor: pointer;
  font-size: 0.9rem;
  line-height: 1;
}

.verdeckt-schalter:hover,
.verdeckt-schalter:focus-visible {
  border-color: var(--color-primary);
  background: var(--color-primary-soft, var(--color-bg));
}

.verdeckt.offen .verdeckt-auge {
  opacity: 0.45;
}

/* Nur fuer Vorlesehilfen sichtbar. */
.visuell-versteckt {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --- Arbeitszeiten -------------------------------------------------------- */

.wochentag-wahl {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
}

/* Der ganze Schalter ist Trefferflaeche – am Tablet laesst sich ein
   16-Pixel-Kaestchen kaum treffen. */
.tag-schalter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 3.2rem;
  padding: 0.55rem 0.7rem;
  margin: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  cursor: pointer;
  font-weight: 500;
  user-select: none;
}

.tag-schalter input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.tag-schalter:has(input:checked) {
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-color: var(--color-primary);
}

.tag-schalter:has(input:focus-visible) {
  outline: 2px solid var(--color-primary-dark);
  outline-offset: 2px;
}

/* Schaltflaeche, die wie ein Link aussieht (Schnellauswahl der Wochentage). */
.link-schalter {
  border: none;
  background: none;
  padding: 0;
  font: inherit;
  color: var(--color-primary-dark);
  text-decoration: underline;
  cursor: pointer;
}

/* Die Zeile, die gerade bearbeitet wird, hebt sich ab. */
tr.bearbeitet > td {
  background: var(--color-primary-soft, var(--color-bg));
  vertical-align: middle;
}

tr.bearbeitet input,
tr.bearbeitet select {
  margin: 0;
}

/* Das hidden-Attribut muss auch gegen display-Regeln aus Klassen gewinnen:
   Die Regel des Browsers ([hidden] { display: none }) hat weniger Gewicht als
   jede Klasse, sodass z.B. .grid-2 sie sonst aushebelt. */
[hidden] {
  display: none !important;
}

/* --- Inventar: Chargen ---------------------------------------------------- */

/* Jede Charge ist eine eigene Karte mit farbiger Kante links – so bleibt bei
   einem Artikel mit acht Lieferungen erkennbar, wo eine endet. */
.card.charge {
  border-left: 4px solid var(--color-border);
}

.card.charge h3 {
  font-size: 1.05rem;
}

/* Buchungsmaske innerhalb einer Charge absetzen. */
.buchungsmaske {
  margin-top: 0.75rem;
  padding: 0.75rem 1rem 1rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-bg);
}

/* Vorzeichen der Bewegung auch farblich, nicht nur als Zeichen. */
.zugang {
  color: #2c6e3f;
}

.abgang {
  color: var(--color-danger);
}

/* --- Behandlungsfotos ----------------------------------------------------- */

/* Quadratischer Rahmen fuer jedes Foto – die Begruendung steht ausfuehrlich in
   views/partials/bild-anzeige.ejs. Kurz: transform: rotate() aendert die
   Layout-Box nicht. Nur weil beide Kanten der Box gleich lang sind, bleibt das
   Bild bei 0, 90, 180 und 270 Grad vollstaendig im Rahmen. Feste Groesse,
   damit die Reihe beim Sammel-Drehen nicht springt. */
.foto-rahmen {
  width: 160px;
  height: 160px;
  border-radius: 8px;
  background: var(--color-bg);
  overflow: hidden;
  /* Zentriert das Bild im Rahmen. Es fuellt ihn NICHT aus – siehe unten. */
  display: flex;
  align-items: center;
  justify-content: center;
}

.foto-rahmen img {
  display: block;
  /* Bewusst KEIN width/height: 100% mit object-fit. Das Bild bekommt seine
     native Groesse und wird nur nach oben begrenzt. Zwei Gruende:

     1. Kein Hochskalieren. Ein 1002x1337-Scan wurde bisher auf die Rahmenhoehe
        hochgerechnet und dadurch unscharf. Die native Aufloesung ist jetzt die
        Obergrenze; groessere Bilder werden weiterhin eingepasst.
     2. Nachpruefbarkeit. So ist die Layout-Box genau das, was zu sehen ist –
        bei object-fit bleibt die Box gross und nur der Inhalt schrumpft, was
        sich weder messen noch beim Drehen sauber begrenzen laesst.

     Beschnitten wird nichts: Ein Bild aus der Akte darf nicht angeschnitten
     werden. Und weil beide Kanten hoechstens so lang sind wie die Rahmenseite,
     passt das Bild auch nach einer Drehung um 90 oder 270 Grad vollstaendig
     hinein. */
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  transform-origin: center center;
  /* Der Browser wertet EXIF wie ueblich selbst aus. Fuer Behandlungsfotos ist
     das wirkungslos – ihre Datei traegt kein EXIF mehr.

     Bei Dokumenten ist es dagegen NOETIG. Deren Originaldatei bleibt
     unveraendert und behaelt ihr EXIF, das Vorschaubild wird neu erzeugt und
     hat keins. Ein Bild mit Drehflag und sein Vorschaubild wuerden also
     unterschiedlich stehen – ausser der Browser wendet das Flag an. Genau das
     gleicht die beiden wieder an:

       Browser wertet EXIF aus  -> Original aufrecht; das Vorschaubild wurde
                                   beim Dekodieren mitgedreht, ist also
                                   ebenfalls aufrecht. Vorbelegung 0.
       Browser wertet EXIF nicht aus -> Original liegt roh; das Vorschaubild
                                   wurde roh dekodiert, liegt also gleich.
                                   Vorbelegung entspricht dem Flag.

     Beide Faelle stimmen ueberein, weil dieselbe Browser-Eigenschaft auf
     beide wirkt. Welcher der beiden vorliegt, wird beim Hochladen gemessen
     (public/js/bildverarbeitung.js, vorbelegeDrehung) und nicht angenommen. */
  image-orientation: from-image;
}

/* Vollansicht: dasselbe Prinzip, nur groesser. Quadratisch, damit auch hier
   jeder Drehwert vollstaendig sichtbar bleibt und nichts ueberlaeuft. */
.foto-rahmen-voll {
  width: min(92vw, 74vh);
  /* Nie breiter als die Seite – sonst laeuft die Kachel auf schmalen Seiten
     ueber den Rand hinaus. aspect-ratio haelt sie dabei quadratisch. */
  max-width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  margin: 0 auto;
}

/* Die Kachel ist ein Link – ohne die Unterstreichung und Farbe eines solchen. */
.bild-kachel {
  display: inline-block;
  text-decoration: none;
  border-radius: 8px;
}

.bild-kachel:focus-visible {
  outline: 3px solid var(--color-primary);
  outline-offset: 2px;
}

/* --- Overlay (Lightbox) ---------------------------------------------------
   Liegt ueber der Akte; die Seite dahinter bleibt sichtbar und behaelt ihre
   Scrollposition. Sie wird nur am Scrollen gehindert, solange das Overlay
   offen ist. */

.bild-overlay-offen {
  overflow: hidden;
}

.bild-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
}

.bild-overlay[hidden] {
  display: none;
}

.bild-overlay-hintergrund {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.82);
}

.bild-overlay-inhalt {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  width: 100%;
  height: 100%;
  padding: 0.75rem;
  color: #fff;
}

.bild-overlay-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex: 0 0 auto;
}

.bild-overlay-zaehler {
  font-weight: 600;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
}

.bild-overlay-buehne {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 0;
}

/* Quadratischer Rahmen wie in der Kachel – die Begruendung steht in
   views/partials/bild-anzeige.ejs. Er ist so gross wie die kuerzere Seite der
   Buehne, damit auch eine 90-Grad-Drehung vollstaendig hineinpasst. */
.bild-overlay-rahmen {
  width: min(78vw, 78vh);
  height: min(78vw, 78vh);
  background: transparent;
}

.bild-overlay-fuss {
  flex: 0 0 auto;
  text-align: center;
}

.bild-overlay-drehen {
  display: flex;
  gap: 0.5rem;
  justify-content: center;
  margin-bottom: 0.4rem;
}

.bild-overlay-drehen[hidden] {
  display: none;
}

.bild-overlay-angaben {
  margin: 0;
  font-size: 0.9rem;
  opacity: 0.9;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
}

.bild-overlay-meldung {
  margin: 0.5rem auto 0;
  max-width: 32rem;
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius);
  background: var(--color-danger);
  color: #fff;
  font-size: 0.9rem;
}

/* Grosse Trefferflaechen – bedient wird das ueberwiegend auf dem Tablet. */
.bild-overlay-knopf {
  min-width: 3rem;
  min-height: 3rem;
  padding: 0.5rem 0.9rem;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: var(--radius);
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}

.bild-overlay-knopf:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.2);
}

.bild-overlay-knopf:disabled {
  opacity: 0.3;
  cursor: default;
}

.bild-overlay-knopf[hidden] {
  display: none;
}

/* Die Drehknoepfe stehen dicht am Bild und sollen nicht wie Hauptaktionen
   wirken. */
.foto-drehen {
  display: flex;
  gap: 0.25rem;
  margin-top: 0.3rem;
}

.foto-drehen button {
  padding: 0.15rem 0.5rem;
  font-size: 0.85rem;
  line-height: 1.4;
}

.foto-angaben {
  max-width: 160px;
  font-size: 0.78rem;
  line-height: 1.3;
  margin-top: 0.2rem;
}

/* Fortschritt waehrend der Bildaufbereitung im Browser. Ohne diese Anzeige
   wirkt das Formular nach dem Klick auf Speichern eingefroren. */
.bild-fortschritt {
  margin: 1rem 0;
  padding: 0.75rem 1rem;
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-primary);
  border-radius: var(--radius);
  background: var(--color-surface);
  font-weight: 500;
}

/* Warnung vor der automatischen Abmeldung.
   Liegt ueber allem anderen (auch ueber dem Bild-Overlay, z-index 100): Wer sie
   uebersieht, verliert seine Eingaben – oder glaubt es zumindest. */
.sitzung-warnung {
  position: fixed;
  right: 1.5rem;
  bottom: 1.5rem;
  z-index: 200;
  max-width: 24rem;
  padding: 1.25rem;
  border: 2px solid var(--color-warning, #b8860b);
  border-radius: var(--radius);
  background: var(--color-surface);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25);
}

.sitzung-warnung[hidden] {
  display: none;
}

.sitzung-warnung p {
  margin: 0 0 0.75rem;
}

.sitzung-countdown {
  font-size: 1.5rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.sitzung-hinweis {
  font-size: 0.875rem;
  color: var(--color-text-muted);
}

@media (max-width: 40rem) {
  .sitzung-warnung {
    right: 0.75rem;
    left: 0.75rem;
    bottom: 0.75rem;
    max-width: none;
  }
}

/* Befehlszeilen auf der Backup-Seite. Sie werden abgetippt, nicht angeklickt –
   deshalb gut lesbar und breit genug, statt in einen Fließtext gequetscht. */
.befehl {
  margin: 0 0 1rem;
  padding: 0.75rem 1rem;
  overflow-x: auto;
  border-radius: var(--radius);
  background: var(--color-surface-alt, #f4f4f5);
  font-size: 0.9375rem;
  line-height: 1.6;
}

.befehl code {
  background: none;
  padding: 0;
}

.befehl-kommentar {
  color: var(--color-text-muted);
}

/* Kleiner Knopf in Tabellenzeilen (Download je Sicherungsstand). */
.btn-klein {
  padding: 0.3rem 0.7rem;
  font-size: 0.8125rem;
}

/* Hinweis neben dem Sicherungsknopf, solange der Lauf arbeitet. */
.sicherung-arbeitet {
  align-self: center;
  color: var(--color-text-muted);
  font-size: 0.9375rem;
}

.sicherung-arbeitet[hidden] {
  display: none;
}

/* --- Zwei-Faktor-Anmeldung ------------------------------------------------ */

/* QR-Code. Weisser Rahmen ringsum, weil Lesegeraete eine Ruhezone brauchen –
   ein QR-Code direkt an einer farbigen Kante wird oft nicht erkannt. */
.qr-rahmen {
  display: inline-block;
  margin: 1rem 0;
  padding: 0.5rem;
  border: 1px solid var(--color-border, #ddd);
  border-radius: var(--radius);
  background: #ffffff;
}

.qr-code {
  display: block;
  width: 15rem;
  height: 15rem;
  /* Scharfe Kanten statt weichgezeichneter Quadrate – sonst leidet die
     Erkennung auf kleinen Displays. */
  image-rendering: pixelated;
}

/* Der Schluessel zum Abtippen: gleichbreite Schrift, damit sich Zeichen nicht
   verwechseln lassen. */
.geheimnis {
  display: inline-block;
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius);
  background: var(--color-surface-alt, #f4f4f5);
  font-size: 1.0625rem;
  letter-spacing: 0.08em;
}

/* Wiederherstellungscodes: zum Ausdrucken gedacht, deshalb gross und ruhig. */
.wiederherstellungscodes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0.5rem;
  margin: 1rem 0;
  padding: 1rem;
  list-style: none;
  border: 1px solid var(--color-border, #ddd);
  border-radius: var(--radius);
  background: var(--color-surface-alt, #f4f4f5);
}

.wiederherstellungscodes code {
  background: none;
  font-size: 1.0625rem;
  letter-spacing: 0.05em;
}

/* Aufklappbare Nebenwege (neue Codes, Abschalten). Sie sollen erreichbar sein,
   aber nicht so aussehen, als waeren sie der uebliche Weg. */
.aufklappbar {
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--color-border, #ddd);
}

.aufklappbar > summary {
  cursor: pointer;
  font-weight: 500;
}

.btn-warnung {
  background: var(--color-danger, #b3261e);
  border-color: var(--color-danger, #b3261e);
  color: #ffffff;
}

/* Nebensaechliche Aktion (Abbrechen): sichtbar, aber ohne Gewicht. */
.btn-schlicht {
  padding: 0.5rem 0;
  border: none;
  background: none;
  color: var(--color-text-muted);
  font-size: 0.9375rem;
  text-decoration: underline;
  cursor: pointer;
}

@media print {
  /* Beim Ausdrucken der Codes soll nur das Wesentliche aufs Papier. */
  .topnav,
  .seitenfuss,
  .aufklappbar {
    display: none;
  }
}

/* Kontrollkaestchen mit erklaerendem Zusatz (z.B. "Diesem Gerät vertrauen"). */
.kontrollkaestchen {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  cursor: pointer;
}

.kontrollkaestchen input {
  margin-top: 0.2rem;
  width: auto;
  flex: none;
}

.kontrollkaestchen .field-hint {
  display: block;
  margin-top: 0.15rem;
}

/* Erklaerung der Pflichtstufen unter der Auswahl. */
.stufen-erklaerung {
  margin: 0.75rem 0 0;
  font-size: 0.9375rem;
}

.stufen-erklaerung dt {
  font-weight: 600;
  margin-top: 0.5rem;
}

.stufen-erklaerung dd {
  margin: 0.1rem 0 0;
  color: var(--color-text-muted);
}

/* Wen eine Umstellung trifft – mit Namen, damit niemand aus Versehen das
   halbe Team aussperrt. */
.betroffene-liste {
  margin: 0.5rem 0 1rem;
  padding: 0.75rem 1rem 0.75rem 2rem;
  border-radius: var(--radius);
  background: var(--color-surface-alt, #f4f4f5);
}

.betroffene-liste li {
  margin: 0.25rem 0;
}

/* Suchfeld ueber der Materialtabelle. Ausgeliefert wird es versteckt und erst
   von material-suche.js eingeblendet – ohne Skript stuende hier sonst ein Feld
   ohne Wirkung. */
.material-suche {
  margin: 0 0 0.75rem;
}

.material-suche input[type='search'] {
  max-width: 22rem;
}

.material-suche .field-hint {
  margin-top: 0.25rem;
  min-height: 1.2em;
}

/* Hinweis unter der Personenauswahl, wenn die gewaehlte Person zu dem
   Zeitpunkt abwesend ist. Warnfarbe, aber keine Sperre – die Zuordnung
   bleibt moeglich. */
.warnung-abwesend {
  color: var(--color-warning);
}

/* Trefferzahl am Inventarfilter. Sie steht an JEDEM Filter, auch am
   abgewaehlten – sonst muesste man anhaken, um zu sehen, ob es etwas zu sehen
   gibt. Ohne Treffer bleibt sie blass: Eine Null soll nicht so aussehen wie
   eine Warnung. */
.schnellfilter-haken.hat-treffer {
  border-color: var(--color-warning);
}

.schnellfilter-haken.hat-treffer .schnellfilter-zahl {
  background: var(--color-warning-bg);
  color: var(--color-warning);
  font-weight: 600;
}

.schnellfilter-haken.ohne-treffer {
  color: var(--color-text-muted);
}

.schnellfilter-haken.ohne-treffer .schnellfilter-zahl {
  background: none;
  color: var(--color-text-muted);
}

/* Zahl neben der Gruppenueberschrift. Etwas kleiner als der Titel, damit sie
   ihn nicht ueberstimmt. */
.warngruppe h3 .badge {
  font-size: 0.78rem;
  vertical-align: middle;
  margin-left: 0.35rem;
}
