:root {
  --ink: #000000;
  --ink-2: #2B2B2B;
  --text: #000000;
  --text-soft: #1A1A1A;
  --paper: #F3DFC7;
  --panel: #FFFFFF;
  --panel-soft: #FAFBFC;
  --panel-soft-2: #FAFAF7;
  --neutral-soft: #EEECE7;
  --sidebar-bg: #F7EFE1;
  --line: #E8D3B4;
  --accent: #E8734A;
  --accent-dark: #C25A34;
  --accent-soft: #FCEEE8;
  --navy-accent: #3E9186;
  --navy-accent-soft: #E4F2EF;
  --success: #2C7A6C;
  --success-soft: #E4F2EF;
  --warning: #B07423;
  --warning-soft: #FBF0DF;
  --danger: #C0392B;
  --danger-soft: #FBEAE8;
  --contrast-text: #FFFFFF;
  --radius: 6px;
  --shadow-sm: 0 1px 2px rgba(45,42,40,0.05);
  --shadow-md: 0 4px 16px rgba(45,42,40,0.08);
}

html.dark {
  --ink: #F3EEE7;
  --ink-2: #DCD4C8;
  --text: #F3EEE7;
  --text-soft: #B7AFA2;
  --paper: #221C16;
  --panel: #2B241D;
  --panel-soft: #322A22;
  --panel-soft-2: #302921;
  --neutral-soft: #3A322A;
  --sidebar-bg: #262019;
  --line: #40372D;
  --accent: #E8794F;
  --accent-dark: #F2A17A;
  --accent-soft: #3D2C21;
  --navy-accent: #57B3A4;
  --navy-accent-soft: #203832;
  --success: #52B79B;
  --success-soft: #1F362E;
  --warning: #E0A253;
  --warning-soft: #3B2E1B;
  --danger: #E37363;
  --danger-soft: #3C231C;
  --contrast-text: #221C16;
  --shadow-sm: 0 1px 2px rgba(0,0,0,0.35);
  --shadow-md: 0 4px 16px rgba(0,0,0,0.45);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--text);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 15px;
  line-height: 1.5;
}

h1, h2, h3 {
  font-family: 'Libre Franklin', 'Inter', sans-serif;
  font-weight: 500;
  letter-spacing: -0.01em;
  margin: 0 0 0.4em 0;
  color: var(--ink);
}

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

.layout { display: flex; min-height: 100vh; }

/* ---------- Sidebar ---------- */
.sidebar {
  width: 232px;
  flex-shrink: 0;
  background: var(--sidebar-bg);
  color: var(--text-soft);
  display: flex;
  flex-direction: column;
  padding: 26px 0;
  border-right: 1px solid var(--line);
}

.sidebar .brand {
  font-family: 'Libre Franklin', sans-serif;
  font-weight: 600;
  font-size: 1.2rem;
  letter-spacing: 0.01em;
  padding: 0 22px 22px 22px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 14px;
  color: var(--ink);
}

.sidebar .brand span { color: var(--accent); }

.sidebar nav { display: flex; flex-direction: column; gap: 2px; flex: 1; }

.sidebar nav a {
  color: var(--text-soft);
  padding: 11px 22px;
  font-size: 0.92rem;
  font-weight: 500;
  border-left: 3px solid transparent;
  letter-spacing: 0.01em;
}
.sidebar nav a:hover { background: var(--accent-soft); text-decoration: none; color: var(--accent-dark); }
.sidebar nav a.active {
  background: var(--accent-soft);
  border-left-color: var(--accent);
  color: var(--accent-dark);
  font-weight: 600;
}

.sidebar .user-box {
  padding: 16px 22px;
  border-top: 1px solid var(--line);
  font-size: 0.85rem;
}
.sidebar .user-box strong { color: var(--ink); }
.sidebar .user-box .role-badge {
  display: inline-block;
  margin-top: 5px;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 3px;
  background: var(--accent-soft);
  color: var(--accent-dark);
}
.sidebar .user-box form { margin-top: 12px; }
.sidebar .user-box button {
  background: none;
  border: 1px solid var(--line);
  color: var(--text-soft);
  padding: 7px 12px;
  border-radius: var(--radius);
  cursor: pointer;
  font-size: 0.82rem;
  width: 100%;
  transition: background 0.15s;
}
.sidebar .user-box button:hover { background: var(--paper); color: var(--ink); }

/* ---------- Main ---------- */
/* Der Inhalt nutzt die Breite, laeuft aber auf sehr grossen Bildschirmen
   nicht ins Uferlose: 1460px sind rund 120 Zeichen pro Zeile - darueber
   wird Lesen anstrengend. margin:auto haelt ihn mittig, wenn mehr Platz
   da ist. */
main {
  flex: 1;
  width: 100%;
  max-width: 1460px;
  margin: 0 auto;
  padding: 32px;
  min-width: 0;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 28px;
  gap: 16px;
  flex-wrap: wrap;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--line);
}
.page-header h1 { margin: 0; font-size: 1.5rem; }
/* Schaltflaechen im Kopf brechen als Ganzes in die naechste Zeile um, aber
   nie innerhalb der Beschriftung: "+ Produkt" auf zwei Zeilen sieht aus wie
   ein Fehler und macht die Schaltflaeche unnoetig hoch. */
.page-header .btn { white-space: nowrap; }

/* Kacheln richten sich nach ihrem Inhalt: Eine Kachel mit langem Titel wird
   breiter, statt den Titel umzubrechen. Reicht der Platz nicht, rutschen die
   ueberzaehligen Kacheln in die naechste Zeile. Ein starres Raster mit
   gleichen Spaltenbreiten kann beides nicht. */
.stats-grid {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 16px;
  margin-bottom: 32px;
}
.stats-grid > a,
.stats-grid > .stat-card {
  /* Grundbreite = Inhaltsbreite; waechst in den freien Platz hinein,
     schrumpft aber nie unter 170px und nie ueber die Zeilenbreite hinaus. */
  flex: 1 1 auto;
  min-width: 170px;
  max-width: 100%;
}

.stat-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-top: 3px solid var(--navy-accent);
  border-radius: var(--radius);
  padding: 20px 22px;
  box-shadow: var(--shadow-sm);
  transition: box-shadow 0.15s, transform 0.15s;
  /* Gleiche Hoehe fuer alle Kacheln, auch wenn nur manche eine
     Zusatzzeile haben. Die Karte fuellt dazu ihre Rasterzelle aus. */
  height: 100%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  /* Gleiche Mindesthoehe fuer ALLE Kacheln - auch ueber Zeilenumbrueche
     hinweg. Ohne sie waere nur jede Zeile fuer sich gleich hoch. */
  min-height: 104px;
}
/* Die Kacheln stecken in einem Link - der muss die Hoehe weiterreichen. */
.stats-grid > a { display: block; height: 100%; }
.stat-card:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
.stat-card .label {
  font-size: 0.76rem;
  color: var(--text-soft);
  margin-bottom: 8px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
  /* Der Titel soll moeglichst in einer Zeile stehen - die Kachel passt sich
     an. Nur wenn selbst das nicht reicht (sehr schmales Display), wird
     innerhalb des Wortes umgebrochen. */
  white-space: nowrap;
  line-height: 1.3;
  /* Fester Platz fuer den Titel: So beginnen die Zahlen aller Kacheln auf
     derselben Hoehe, auch wenn ein Titel einmal zweizeilig wird. */
  min-height: 1.3em;
}
@media (max-width: 640px) {
  .stat-card .label { white-space: normal; overflow-wrap: anywhere; }
}
.stat-card .value {
  font-family: 'Libre Franklin', sans-serif;
  font-size: 2rem;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.1;
  overflow-wrap: anywhere;
}
/* Erlaeuterung unter der Zahl. Sitzt in JEDER Kachel, damit keine
   halbleer wirkt - notfalls leer, dann haelt sie nur den Platz. */
.stat-card .sub {
  font-size: 0.72rem;
  color: var(--text-soft);
  margin-top: 4px;
  min-height: 1em;
  white-space: nowrap;
}

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px 26px;
  margin-bottom: 26px;
  box-shadow: var(--shadow-sm);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.panel h2 { font-size: 1.05rem; margin-bottom: 16px; }

/* ---------- Buttons ---------- */
.btn { /* btn-creme */
  display: inline-block;
  background: var(--sidebar-bg);
  color: var(--text);
  border: 1px solid var(--accent);
  padding: 10px 20px;
  border-radius: var(--radius);
  cursor: pointer;
  font-size: 0.88rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  transition: background 0.15s;
}
.btn:hover { background: var(--accent-soft); text-decoration: none; color: var(--text); }
.btn-secondary {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--line);
  font-weight: 500;
}
.btn-secondary:hover { background: var(--paper); color: var(--text); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover { background: #8B2C24; color: #fff; }
.btn-sm { padding: 6px 13px; font-size: 0.8rem; }

/* ---------- Tables ---------- */
table { width: 100%; min-width: 600px; border-collapse: collapse; }
th, td { text-align: left; padding: 12px 14px; border-bottom: 1px solid var(--line); font-size: 0.9rem; }
th {
  color: var(--text-soft);
  font-weight: 700;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: var(--panel-soft);
}
tr:hover td { background: var(--panel-soft-2); }

/* ---------- Badges ---------- */
.badge {
  display: inline-block;
  padding: 3px 11px;
  border-radius: 3px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.badge-aktiv, .badge-abgeschlossen { background: var(--success-soft); color: var(--success); }
.badge-inaktiv { background: var(--danger-soft); color: var(--danger); }
.badge-offen { background: var(--warning-soft); color: var(--warning); }
.badge-in_arbeit { background: var(--navy-accent-soft); color: var(--navy-accent); }
.badge-admin { background: var(--accent-soft); color: var(--accent-dark); }
.badge-mitarbeiter { background: var(--neutral-soft); color: var(--text-soft); }

/* ---------- Forms ---------- */
.form-group { margin-bottom: 18px; }
.form-group label {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  margin-bottom: 7px;
  color: var(--ink);
}
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
input[type=text], input[type=email], input[type=tel], input[type=password],
input[type=date], input[type=number], select, textarea {
  width: 100%;
  padding: 10px 13px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: 0.9rem;
  font-family: inherit;
  background: var(--panel);
  color: var(--text);
}
textarea { resize: vertical; min-height: 80px; }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--navy-accent);
  box-shadow: 0 0 0 3px rgba(46,78,126,0.12);
}

.alert {
  padding: 13px 16px;
  border-radius: var(--radius);
  margin-bottom: 18px;
  font-size: 0.88rem;
  border-left: 3px solid var(--danger);
}
.alert-error { background: var(--danger-soft); color: var(--danger); }

.empty-state {
  text-align: center;
  padding: 52px 20px;
  color: var(--text-soft);
}

.search-box { display: flex; gap: 8px; }
.search-box input { min-width: 260px; }

.filter-tabs { display: flex; gap: 8px; margin-bottom: 20px; }
.filter-tabs a {
  padding: 7px 16px;
  border-radius: 20px;
  font-size: 0.83rem;
  font-weight: 500;
  color: var(--text-soft);
  border: 1px solid var(--line);
  background: var(--panel);
}
.filter-tabs a.active { background: var(--ink); color: var(--contrast-text); border-color: var(--ink); }
.filter-tabs a:hover { text-decoration: none; background: var(--navy-accent-soft); }

/* Die Aktionsspalte war ein Flex-Container. Damit faellt die Zelle aus dem
   Zeilenraster der Tabelle - die untere Trennlinie sitzt dann tiefer als in
   den uebrigen Spalten, und die Zeile wirkt zerrissen. Die Zelle bleibt
   deshalb eine normale Tabellenzelle; die Anordnung uebernimmt ein
   Behaelter darin. */
.actions-cell {
  white-space: nowrap;
  padding-left: 20px;
  vertical-align: middle;
}
.actions-cell > * {
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
  margin-right: 20px;
}
.actions-cell > *:last-child { margin-right: 0; }
/* Formulare mit Knopf sollen keine eigene Zeile beanspruchen. */
.actions-cell form { display: inline-flex; margin: 0; }

/* ---------- Login ---------- */
.login-wrap {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #F6A688 0%, #E8734A 55%, #D9603A 100%);
}
.login-card {
  background: var(--panel);
  padding: 44px 40px;
  border-radius: 10px;
  width: 100%;
  max-width: 380px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.35);
}
.login-card .brand {
  font-family: 'Libre Franklin', sans-serif;
  font-weight: 700;
  font-size: 1.4rem;
  margin-bottom: 8px;
  color: var(--ink);
}
.login-card .brand span { color: var(--accent); }
.login-card p.sub { color: var(--text-soft); font-size: 0.88rem; margin-bottom: 26px; }
.login-card .btn { width: 100%; padding: 12px; margin-top: 10px; background: var(--accent); color: #fff; }
.login-card .btn:hover { background: #D3602F; color: #fff; }

@media (max-width: 800px) {
  .layout { flex-direction: column; }
  .sidebar { width: 100%; }
  main { padding: 16px; }
  .form-row { grid-template-columns: 1fr; }
  .panel { padding: 16px; }
  th, td { padding: 9px 10px; font-size: 0.84rem; }
  .stats-grid { gap: 10px; }
  .stats-grid > a, .stats-grid > .stat-card { min-width: 140px; }
  .stat-card { min-height: 92px; padding: 14px 16px; }
  .stat-card .value { font-size: 1.7rem; }
  .page-header { gap: 10px; }
  .page-header h1 { font-size: 1.25rem; }
  .actions-cell { white-space: normal; padding-left: 10px; }
  .actions-cell > * { margin-right: 10px; }
}

/* ---------- Kartenansicht für Modul-Einträge (Kunden, Lieferanten, Produkte, ...) ---------- */
.karten-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 16px;
}
.eintrag-karte {
  display: block;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 16px;
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  color: inherit;
  transition: box-shadow 0.15s, transform 0.15s, border-color 0.15s;
}
.eintrag-karte:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
  border-color: var(--accent);
  text-decoration: none;
}
.eintrag-karte-kopf {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}
.eintrag-karte-avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent-dark);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Libre Franklin', sans-serif;
  font-weight: 600;
  font-size: 0.85rem;
  flex-shrink: 0;
}
.eintrag-karte-kopf-text { min-width: 0; }
.eintrag-karte-titel {
  font-family: 'Libre Franklin', sans-serif;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.eintrag-karte-untertitel {
  font-size: 0.76rem;
  color: var(--text-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.eintrag-karte-felder {
  border-top: 1px solid var(--line);
  padding-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.eintrag-karte-zeile {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  font-size: 0.76rem;
}
.eintrag-karte-label { color: var(--text-soft); flex-shrink: 0; }
.eintrag-karte-wert {
  color: var(--text);
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.eintrag-karte-neu {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px dashed var(--line);
  color: var(--text-soft);
  font-size: 0.85rem;
  font-weight: 500;
  min-height: 100px;
  box-shadow: none;
}
.eintrag-karte-neu:hover {
  border-color: var(--accent);
  color: var(--accent-dark);
  box-shadow: none;
  transform: none;
}

@media (max-width: 800px) {
  .karten-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; }
  .eintrag-karte { padding: 14px; }
}

/* ---------- Dark-Mode-Umschalter ---------- */
body, .panel, .sidebar, .stat-card, input, select, textarea {
  transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.toggle-row { display: flex; align-items: center; gap: 12px; }
.toggle-switch { position: relative; display: inline-block; width: 44px; height: 24px; flex-shrink: 0; }
.toggle-switch input { opacity: 0; width: 0; height: 0; }
.toggle-slider {
  position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0;
  background: var(--line); transition: 0.2s; border-radius: 24px;
}
.toggle-slider::before {
  position: absolute; content: ""; height: 18px; width: 18px; left: 3px; bottom: 3px;
  background: #fff; transition: 0.2s; border-radius: 50%;
}
.toggle-switch input:checked + .toggle-slider { background: var(--accent); }
.toggle-switch input:checked + .toggle-slider::before { transform: translateX(20px); }

/* btn-creme: rote & sekundäre Buttons ohne geerbten Rahmen */
.btn-danger, .btn-secondary { border: none; }

/* Rechnungs-Tabellen: auf schmalen Screens horizontal scrollen statt abschneiden */
.tabelle-scroll { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }


/* rechnungs-karten: Rechnungs-Tabellen auf schmalen Screens als Karten */
@media (max-width: 1024px) {
  .tabelle-scroll { overflow: visible; }
  .tabelle-scroll table,
  .tabelle-scroll tbody,
  .tabelle-scroll tr,
  .tabelle-scroll td { display: block; width: 100%; }
  .tabelle-scroll table { min-width: 0; }
  .tabelle-scroll thead { display: none; }
  .tabelle-scroll tr {
    background: #fff;
    border: 1px solid rgba(0,0,0,0.10);
    border-radius: 12px;
    padding: 12px 14px;
    margin-bottom: 12px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.05);
  }
  .tabelle-scroll td {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 6px 0;
    border: none;
    text-align: right;
  }
  .tabelle-scroll td::before {
    content: attr(data-label);
    font-weight: 600;
    color: var(--text-soft, #666);
    font-size: 0.82rem;
    text-align: left;
    margin-right: auto;
  }
  .tabelle-scroll td.actions-cell {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    justify-content: flex-start;
    padding-top: 10px;
    margin-top: 6px;
    border-top: 1px solid rgba(0,0,0,0.08);
    text-align: left;
  }
  .tabelle-scroll td.actions-cell::before { content: ""; margin: 0; }
  /* In der Kartenansicht ist die Zelle wieder Flex - den Abstand regelt
     dort "gap", der eigene Aussenabstand wuerde sich sonst addieren. */
  .tabelle-scroll td.actions-cell > * { margin-right: 0; }
  .tabelle-scroll .rechnung-nr-link { font-weight: 700; font-size: 1.02rem; }
}

/* ---------- Buchungsformular mit Belegvorschau ---------- */
/* Formular links, Beleg rechts. Beim Erfassen wechselt der Blick staendig
   zwischen beiden - nebeneinander erspart das Fensterwechseln. */
/* Diese Seite darf breiter werden als die uebrigen. Die 1220px an "main"
   sind fuer Textseiten gedacht - hier stehen Formular und Beleg
   nebeneinander, und der Beleg braucht Platz. Gesetzt wird die Ausnahme
   ueber die Elternregel, damit nur diese Seite betroffen ist. */
main:has(.beleg-layout) { max-width: 2000px; }
/* Rueckfall fuer Browser ohne :has() - die Ansicht setzt die Klasse selbst. */
main.main-breit { max-width: 2000px; }

.beleg-layout {
  display: flex;
  gap: 20px;
  /* stretch statt flex-start: Beide Spalten werden so hoch wie die hoehere
     von beiden. Sonst endet das Formular auf halber Hoehe und daneben steht
     der Beleg allein - das wirkt unfertig. */
  align-items: stretch;
}
/* Das Formular braucht nur so viel Breite, wie die Felder benoetigen -
   alles Weitere gehoert dem Beleg. Deshalb feste Grundbreite links und
   "waechst in den Rest" rechts. */
.beleg-layout > .beleg-formular { flex: 0 0 460px; min-width: 0; }
.beleg-layout > .beleg-vorschau { flex: 1 1 auto; min-width: 0; }

/* Beide Panels fuellen ihre Spalte vollstaendig aus. */
.beleg-formular .panel { height: 100%; box-sizing: border-box; margin-bottom: 0; }
.beleg-vorschau .panel {
  height: 100%;
  box-sizing: border-box;
  margin-bottom: 0;
  display: flex;
  flex-direction: column;
}
/* Schmalerer Rand als bei den uebrigen Panels: Jeder Millimeter kommt
   dem Beleg zugute. */
.beleg-vorschau .panel { padding: 12px; }
.beleg-vorschau iframe,
.beleg-vorschau img {
  width: 100%;
  /* Waechst mit, wenn das Formular hoeher ist; gibt sonst selbst die
     Hoehe der Zeile vor. */
  flex: 1 1 auto;
  height: auto;
  min-height: calc(100vh - 190px);
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
  display: block;
}
.beleg-vorschau img { object-fit: contain; }

/* Unter 1100px untereinander: Nebeneinander waere jede Spalte zu schmal,
   um den Beleg noch lesen zu koennen. */
@media (max-width: 1100px) {
  .beleg-layout { display: block; }
  .beleg-formular .panel { height: auto; margin-bottom: 16px; }
  .beleg-vorschau .panel { height: auto; margin-top: 0; }
  .beleg-vorschau iframe, .beleg-vorschau img { height: 75vh; min-height: 0; flex: none; }
}

/* ============================================================
   Mobiler Feinschliff (Telefon, bis 640px)

   Drei Ursachen fuer das seitliche Verrutschen der Seite:
   1. Schaltflaechengruppen im Seitenkopf liegen als EIN Flex-Element
      nebeneinander und koennen nicht umbrechen - bei vier oder fuenf
      Schaltflaechen ragt die Zeile aus dem Bildschirm.
   2. Flex-Elemente schrumpfen ohne min-width:0 nicht unter ihre
      Inhaltsbreite. Ein breiter Inhalt schiebt so die ganze Seite.
   3. Die Seitenleiste beansprucht als volle Spalte den halben
      Bildschirm, bevor der Inhalt beginnt.
   ============================================================ */

@media (max-width: 640px) {

  /* --- 1. Schaltflaechen umbrechen lassen ---
     Die Gruppen sind in den Ansichten mit style="display:flex" gesetzt;
     nur !important greift dagegen durch. */
  .page-header > div {
    flex-wrap: wrap !important;
    justify-content: flex-start !important;
    width: 100%;
    gap: 8px !important;
  }
  .page-header > div > .btn,
  .page-header > div > form > .btn {
    flex: 1 1 calc(50% - 4px);
    text-align: center;
    padding: 10px 12px;
  }
  /* Bei nur einer Schaltflaeche keine halbe Zeile. */
  .page-header > div > .btn:only-child { flex: 0 0 auto; }

  /* Manche Ansichten setzen die Schaltflaechen direkt in den Kopf, ohne
     Gruppe. Der Kopf bricht zwar um, die Schaltflaechen sollen aber
     ebenfalls die halbe Breite fuellen statt ausgefranst zu stehen. */
  .page-header > .btn { flex: 1 1 calc(50% - 8px); text-align: center; }

  /* --- 2. Nichts darf die Seite breiter machen als den Bildschirm --- */
  .layout, main, .panel, .page-header { min-width: 0; max-width: 100%; }
  main { padding: 14px 12px; }
  .panel { padding: 14px; margin-bottom: 16px; }

  /* Lange Werte umbrechen statt die Spalte zu dehnen. */
  td, th, .eintrag-karte { overflow-wrap: anywhere; }

  /* --- 3. Seitenleiste als kompakte Leiste statt voller Spalte --- */
  .sidebar { padding: 10px 0; }
  .sidebar nav {
    flex-direction: row;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    gap: 6px;
    padding: 0 12px 4px;
    /* Scrollbalken ausblenden, gewischt wird trotzdem. */
    scrollbar-width: none;
  }
  .sidebar nav::-webkit-scrollbar { display: none; }
  .sidebar nav a {
    white-space: nowrap;
    padding: 8px 12px;
    border-radius: 6px;
    font-size: 0.86rem;
  }
  .sidebar .brand { padding: 0 12px 8px; font-size: 1.05rem; }
  /* Benutzerbereich zusammenschieben - er soll nicht die halbe Seite fuellen. */
  .sidebar .user-box { padding: 10px 12px; display: flex; align-items: center; gap: 10px; }
  .sidebar .user-box form { margin-top: 0; margin-left: auto; }
  .sidebar .user-box button { padding: 6px 12px; }

  /* --- Formulare --- */
  .form-row { grid-template-columns: 1fr !important; }
  input, select, textarea { font-size: 16px; }  /* verhindert das Zoomen in iOS */

  /* --- Karten --- */
  .karten-grid { grid-template-columns: 1fr !important; gap: 10px; }

  /* --- Kalender ---
     Sieben Spalten waeren auf dem Telefon je 45px breit. Lieber seitlich
     scrollen als unlesbar quetschen. */
  #raster, .kalender-monat { min-width: 620px; }
  .kalender-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
}

/* Kleine Telefone: Schaltflaechen ganze Breite, sonst brechen die
   Beschriftungen mitten im Wort. */
@media (max-width: 380px) {
  .page-header > div > .btn,
  .page-header > div > form > .btn { flex: 1 1 100%; }
}

/* Einzelne Ansichten setzen feste Mindestbreiten fuer ihre Spalten. Auf dem
   Telefon schieben die das Layout seitlich hinaus - dort zaehlt Untereinander
   mehr als Nebeneinander. */
@media (max-width: 640px) {
  .form-group[style*="min-width"],
  .panel[style*="min-width"],
  [style*="flex:1 1 320px"],
  [style*="flex:2"] { min-width: 0 !important; flex-basis: 100% !important; }

  /* Formularfelder mit fester Breite (Konto, Kontonummer) duerfen mitwachsen. */
  .form-group[style*="width:1"] { width: 100% !important; }
}

/* ------------------------------------------------------------
   Tabellen als Karten auf dem Telefon

   Eine Tabelle mit vier oder fuenf Spalten laesst sich auf 390 Pixel
   nicht sinnvoll zeigen: Gequetscht bricht die Ueberschrift Buchstabe
   fuer Buchstabe um, seitlich gescrollt sieht man immer nur einen
   Ausschnitt. Deshalb wird je Datensatz eine Karte daraus, mit der
   Spaltenueberschrift als Beschriftung davor.

   Anwendung: <table class="mobil-karten"> und je Zelle data-label="…".
   Eine leere Beschriftung laesst die Zeile ohne Vorspann - fuer
   Aktionsspalten.

   Die Schwelle liegt bei 1100px und damit deutlich hoeher als beim
   uebrigen Mobilteil. Grund: Die Seitenleiste belegt 232 Pixel. Ein
   Tablet im Querformat hat 1024 Pixel, fuer den Inhalt bleiben also
   rund 790 - zu wenig fuer sieben oder acht Spalten mit echten Werten.
   Erst ab etwa 1100 Pixel Fensterbreite ist eine Tabelle lesbar.
   ------------------------------------------------------------ */
@media (max-width: 1100px) {
  table.mobil-karten { min-width: 0; width: 100%; display: block; }
  table.mobil-karten thead { display: none; }
  table.mobil-karten tbody { display: block; }

  table.mobil-karten tr {
    display: block;
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 10px 12px;
    margin-bottom: 12px;
    background: var(--card-bg, #fff);
  }

  table.mobil-karten td {
    display: flex;
    align-items: baseline;
    gap: 10px;
    width: auto !important;
    border: none;
    border-bottom: 1px solid var(--line);
    padding: 7px 0;
    white-space: normal !important;
  }
  table.mobil-karten tr td:last-child { border-bottom: none; padding-bottom: 0; }

  /* Beschriftung aus data-label davor. Feste Breite, damit die Werte
     untereinander an derselben Linie beginnen. */
  table.mobil-karten td::before {
    content: attr(data-label);
    flex: 0 0 92px;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--text-soft);
  }
  /* Ohne Beschriftung nimmt der Inhalt die ganze Breite. */
  table.mobil-karten td[data-label=""]::before { display: none; }
  table.mobil-karten td[data-label=""] { padding-top: 10px; }

  /* Auswahlfelder und ausklappbare Bereiche sollen die Restbreite fuellen. */
  table.mobil-karten td > form,
  table.mobil-karten td > select,
  table.mobil-karten td > details { flex: 1 1 auto; min-width: 0; }
  table.mobil-karten td select { width: 100%; }
  table.mobil-karten td details > div { min-width: 0 !important; }
}

/* Tablet: Karten zweispaltig.
   Bei 790 Pixel Inhaltsbreite waere eine Angabe pro Zeile Verschwendung -
   die Karte wuerde unnoetig hoch und man scrollt mehr als noetig. Zwei
   Paare nebeneinander nutzen die Breite, ohne zu quetschen. */
@media (min-width: 641px) and (max-width: 1100px) {
  table.mobil-karten tr {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 18px;
    align-items: start;
  }
  /* Die Aktionsspalte ohne Beschriftung laeuft ueber die volle Breite -
     dort stehen mehrere Verweise nebeneinander. */
  table.mobil-karten td[data-label=""] {
    grid-column: 1 / -1;
    border-top: 1px solid var(--line);
    margin-top: 6px;
    padding-top: 10px;
  }
  /* In der vorletzten Zeile sonst eine Trennlinie zu viel. */
  table.mobil-karten td:nth-last-child(2) { border-bottom: none; }
}

/* ------------------------------------------------------------
   Kartendarstellung nach tatsaechlicher Breite statt Bildschirmgroesse

   Die Bildschirmbreite ist ein schlechter Massstab: Ein Lenovo Tab M11
   meldet im Querformat 1280 Pixel, davon gehen 232 fuer die Seitenleiste
   und 88 fuer die Raender ab - fuer die Tabelle bleiben rund 940. Ein
   Laptop mit denselben 1280 Pixel hat dieselbe Enge, ein Bildschirm mit
   1600 nicht.

   Deshalb misst diese Regel den Bereich, in dem die Tabelle wirklich
   steht. Die Media-Query weiter oben bleibt als Rueckfall fuer aeltere
   Browser bestehen; beide erzeugen dasselbe Ergebnis.
   ------------------------------------------------------------ */
.panel { container-type: inline-size; }

@container (max-width: 1000px) {
  table.mobil-karten { min-width: 0; width: 100%; display: block; }
  table.mobil-karten thead { display: none; }
  table.mobil-karten tbody { display: block; }

  table.mobil-karten tr {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 18px;
    align-items: start;
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 10px 12px;
    margin-bottom: 12px;
  }

  table.mobil-karten td {
    display: flex;
    align-items: baseline;
    gap: 10px;
    width: auto !important;
    border: none;
    border-bottom: 1px solid var(--line);
    padding: 7px 0;
    white-space: normal !important;
  }
  table.mobil-karten td::before {
    content: attr(data-label);
    flex: 0 0 92px;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--text-soft);
  }
  table.mobil-karten td[data-label=""]::before { display: none; }
  table.mobil-karten td[data-label=""] {
    grid-column: 1 / -1;
    border-top: 1px solid var(--line);
    border-bottom: none;
    margin-top: 6px;
    padding-top: 10px;
  }
  table.mobil-karten td:nth-last-child(2) { border-bottom: none; }
  table.mobil-karten td select { width: 100%; }
  table.mobil-karten td > form,
  table.mobil-karten td > details { flex: 1 1 auto; min-width: 0; }
}

/* Unter 640px eine Angabe je Zeile - zwei nebeneinander waeren zu eng. */
@container (max-width: 640px) {
  table.mobil-karten tr { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------
   Datums-, Nummern- und Betragsspalten nicht umbrechen

   Browser trennen an Bindestrichen: Aus "2026-09-08" werden sonst zwei
   Zeilen, aus "RE-2026-080926" ebenfalls. Das laesst eine Tabelle unruhig
   wirken, obwohl genug Platz da waere - die Spalte muss nur ein paar
   Pixel breiter sein duerfen.

   Gilt nur fuer die Tabellenform. In der Kartendarstellung hebt
   "white-space: normal !important" es wieder auf, dort ist Umbrechen
   erwuenscht.
   ------------------------------------------------------------ */
td[data-label="Nr."],
td[data-label="Datum"],
td[data-label="Fällig am"],
td[data-label="Betrag"],
td[data-label="Beleg-Nr."],
td[data-label="Kilometer"],
td[data-label="Von"],
td[data-label="Bis"],
td[data-label="Gesichert am"] { white-space: nowrap; }

/* ------------------------------------------------------------
   Aktionsspalte darf umbrechen

   "Bearbeiten Drucken PDF Senden Löschen" braucht in einer Zeile rund
   300 Pixel. Zusammen mit den uebrigen Spalten sprengt das den Bereich,
   und dann wird ausgerechnet die Kundenspalte zusammengedrueckt - der
   Name steht auf zwei Zeilen, obwohl daneben Platz waere.

   Umbrechende Aktionen kosten etwas Hoehe, dafuer passt die Tabelle
   ohne seitliches Scrollen auf jeden Bildschirm.
   ------------------------------------------------------------ */
.actions-cell {
  white-space: normal;
  min-width: 150px;
  max-width: 190px;
}
.actions-cell > * { display: inline-block; margin: 2px 8px 2px 0; }
.actions-cell > *:last-child { margin-right: 0; }

/* Der Kundenname soll dafuer zusammenbleiben - er ist die Angabe, nach
   der man in der Liste sucht. */
td[data-label="Kunde"],
td[data-label="Lieferant"] { white-space: nowrap; }

/* In der Kartendarstellung gilt die Breitenbegrenzung der Aktionsspalte
   nicht - dort steht sie ohnehin ueber die volle Kartenbreite. */
@container (max-width: 1000px) {
  table.mobil-karten .actions-cell { max-width: none; min-width: 0; }
}
@media (max-width: 1100px) {
  table.mobil-karten .actions-cell { max-width: none; min-width: 0; }
}

/* ============================================================
   Rechnungsformular

   Vorher stand das Formular in einem 720px breiten Streifen links -
   auf einem 1920er Bildschirm blieb rechts die halbe Flaeche leer.
   Jetzt fuellt es den Bereich und ordnet die Felder in Spalten.
   ============================================================ */

/* Kopfdaten: drei Spalten am Desktop, zwei am Tablet, eine am Telefon.
   Keine festen Breiten - die Spalten teilen sich den vorhandenen Platz. */
.rechnung-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px 24px;
  margin-bottom: 4px;
}
.rechnung-grid .form-group { margin-bottom: 0; min-width: 0; }
.rechnung-grid input,
.rechnung-grid select { width: 100%; }

@media (max-width: 1199px) {
  .rechnung-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 767px) {
  .rechnung-grid { grid-template-columns: 1fr; }
}

/* ---------- Positionen ---------- */
/* Eine Zeile je Position statt einer hohen Karte: Beschreibung nimmt den
   Rest, die Zahlenfelder bleiben schmal, die Summe steht rechts. */
.pos-tabelle { margin-top: 8px; }

.pos-kopf,
.pos-zeile {
  display: grid;
  grid-template-columns: minmax(300px, 1fr) 100px 160px 160px 50px;
  gap: 12px;
  align-items: center;
}

.pos-kopf {
  padding: 0 4px 8px;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-soft);
  border-bottom: 1px solid var(--line);
}
.pos-kopf .rechts,
.pos-zeile .zeilensumme { text-align: right; }

.pos-zeile {
  padding: 8px 4px;
  border-bottom: 1px solid var(--line);
}
.pos-zeile input { width: 100%; margin: 0; }
.pos-zeile .zeilensumme { font-weight: 600; white-space: nowrap; }
.pos-zeile .zeile-entfernen {
  border: none; background: none; cursor: pointer; line-height: 1;
  color: var(--danger, #c0392b); font-size: 18px; padding: 6px;
  justify-self: center;
}

.pos-summe {
  display: flex;
  justify-content: flex-end;
  align-items: baseline;
  gap: 14px;
  padding: 14px 4px 0;
  font-weight: 700;
}
.pos-summe .wert { font-size: 1.1rem; }

/* Tablet: Beschreibung darf eine eigene Zeile bekommen, die Zahlenfelder
   ruecken darunter zusammen. */
@media (max-width: 1199px) {
  .pos-kopf { display: none; }
  .pos-zeile {
    grid-template-columns: 1fr 100px 140px 50px;
    gap: 10px 12px;
    padding: 12px 4px;
  }
  .pos-zeile .beschreibung { grid-column: 1 / -1; }
  .pos-zeile .zeilensumme { text-align: left; }
  /* Ohne Kopfzeile braucht es Beschriftungen an den Feldern. */
  .pos-zeile [data-feld]::before {
    content: attr(data-feld);
    display: block;
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--text-soft);
    margin-bottom: 3px;
  }
}

/* Telefon: jede Position eine Karte, Felder ueber die volle Breite. */
@media (max-width: 767px) {
  .pos-zeile {
    grid-template-columns: 1fr;
    gap: 8px;
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 12px;
    margin-bottom: 10px;
  }
  .pos-zeile .zeile-entfernen { justify-self: end; }
}

/* ============================================================
   Aktionsmenue (Dreipunkt)

   Fuenf Verweise nebeneinander haben rund 300 Pixel belegt und die
   Tabelle unruhig gemacht. Ein Knopf mit Klappmenue braucht 36.

   Umgesetzt mit <details>/<summary>: Das laesst sich mit Tabulator
   erreichen, mit Enter oder Leertaste oeffnen und zeigt den Fokus
   ohne Zutun. Die Ausrichtung uebernimmt das Skript in der Ansicht -
   das Menue liegt fest am Bildschirm, damit der Rollbereich der
   Tabelle es nicht abschneidet.
   ============================================================ */
.aktionen-zelle {
  /* Hebt die Breitenvorgabe der allgemeinen Aktionsspalte auf: Ein
     Dreipunktknopf braucht keine 150 Pixel. */
  width: 1%;
  min-width: 0;
  max-width: none;
  white-space: nowrap;
  text-align: right;
}

.aktionen-menue { display: inline-block; position: relative; }

.aktionen-menue > summary {
  list-style: none;
  cursor: pointer;
  width: 36px; height: 36px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px;
  font-size: 20px; line-height: 1;
  color: var(--text-soft);
  user-select: none;
}
.aktionen-menue > summary::-webkit-details-marker { display: none; }
.aktionen-menue > summary:hover { background: var(--accent-soft); color: var(--accent-dark); }
.aktionen-menue > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.aktionen-menue[open] > summary { background: var(--accent-soft); color: var(--accent-dark); }

.aktionen-menue .menue-inhalt {
  position: fixed;          /* wird vom Skript gesetzt */
  z-index: 1000;
  min-width: 190px;
  padding: 6px;
  background: var(--card-bg, #fff);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 10px 28px rgba(0,0,0,0.16);
  text-align: left;
}
.aktionen-menue .menue-inhalt a,
.aktionen-menue .menue-inhalt button {
  display: block;
  width: 100%;
  text-align: left;
  padding: 10px 12px;      /* mindestens 40px hoch - auch mit dem Finger treffbar */
  border: none;
  background: none;
  border-radius: 7px;
  font: inherit;
  font-size: 0.9rem;
  color: var(--ink);
  cursor: pointer;
  text-decoration: none;
}
.aktionen-menue .menue-inhalt a:hover,
.aktionen-menue .menue-inhalt button:hover { background: var(--accent-soft); text-decoration: none; }
.aktionen-menue .menue-inhalt a:focus-visible,
.aktionen-menue .menue-inhalt button:focus-visible {
  outline: 2px solid var(--accent); outline-offset: -2px;
}
.aktionen-menue .menue-inhalt form { margin: 0; }

.aktionen-menue .menue-trenner {
  height: 1px; background: var(--line); margin: 6px 4px;
}
/* Loeschen als gefaehrliche Aktion kennzeichnen. */
.aktionen-menue .menue-inhalt button.gefahr { color: var(--danger, #c0392b); font-weight: 600; }
.aktionen-menue .menue-inhalt button.gefahr:hover { background: rgba(192,57,43,0.10); }

/* Auf Touch-Geraeten groessere Trefferflaeche. */
@media (pointer: coarse) {
  .aktionen-menue > summary { width: 44px; height: 44px; }
  .aktionen-menue .menue-inhalt a,
  .aktionen-menue .menue-inhalt button { padding: 12px 14px; }
}

/* In der Kartendarstellung sitzt der Knopf rechts in seiner Zeile. */
@container (max-width: 1000px) {
  table.mobil-karten .aktionen-zelle { width: auto; justify-content: flex-end; }
}
@media (max-width: 1100px) {
  table.mobil-karten .aktionen-zelle { width: auto; justify-content: flex-end; }
}

/* ============================================================
   Adaptives Aktionsmenue

   Breit: Das <details> steht offen, der Dreipunktknopf ist versteckt,
   die Verweise stehen nebeneinander wie bisher.
   Schmal: Das <details> ist zu, es zeigt sich nur der Knopf.

   Die Umschaltung besorgt das Skript in head.ejs ueber das
   open-Attribut - so bleiben die Elemente an Ort und Stelle und
   Formulare samt Bestaetigungsabfragen funktionieren unveraendert.
   ============================================================ */
.aktionen-menue.auto[open] > summary { display: none; }
.aktionen-menue.auto[open] > .menue-inhalt {
  position: static;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  min-width: 0;
  padding: 0;
  background: none;
  border: none;
  box-shadow: none;
}
.aktionen-menue.auto[open] > .menue-inhalt > * { width: auto; }
.aktionen-menue.auto[open] > .menue-inhalt a,
.aktionen-menue.auto[open] > .menue-inhalt button { padding: 2px 0; }
.aktionen-menue.auto[open] > .menue-inhalt .menue-trenner { display: none; }

/* ============================================================
   Zentrale Schutzmassnahmen gegen seitlichen Ueberlauf

   Diese Regeln greifen projektweit und ersetzen Einzelkorrekturen
   auf jeder Seite. Sie aendern am Aussehen nichts, solange genug
   Platz da ist - sie verhindern nur, dass etwas herausragt.
   ============================================================ */

/* Nichts darf breiter werden als sein Behaelter. */
img, svg, video, canvas, iframe { max-width: 100%; height: auto; }
input, select, textarea { max-width: 100%; }

/* Flex- und Grid-Elemente schrumpfen ohne min-width:0 nicht unter ihre
   Inhaltsbreite - die haeufigste Ursache fuer waagrechtes Scrollen. */
.layout, main, .panel, .form-group, .karten-grid { min-width: 0; }

/* Lange Namen, Nummern und Adressen umbrechen statt die Spalte zu dehnen. */
.eintrag-karte-titel, .eintrag-karte, td, th { overflow-wrap: break-word; }

@media (max-width: 900px) {
  /* Ansichten setzen fuer Formularkarten feste Hoechstbreiten
     (480, 520, 560 Pixel). Auf kleinen Bildschirmen zaehlt die volle
     Breite mehr als die Zeilenlaenge. */
  .panel[style*="max-width"] { max-width: 100% !important; }

  /* Reihen aus mehreren Elementen umbrechen lassen. Die Ansichten setzen
     display:flex meist ohne flex-wrap; nebeneinander bleiben waere hier
     der schlechtere Ausgang. */
  main div[style*="display:flex"] { flex-wrap: wrap; }

  /* Eingabefelder fuellen ihre Zeile. */
  .form-group input, .form-group select, .form-group textarea { width: 100%; }
}
