* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  background: #f4f6f9;
  color: #1a1a1a;
}

/* Ohne diese Regel greift der Browser-Default für :visited (lila) — bei
   Tabellenzeilen, die auf eine Detailseite verlinken (z.B. Ticketsystem),
   sieht das inkonsistent aus, sobald man den Link einmal besucht hat.
   Statt des Standard-Web-Blaus die ohnehin schon etablierte Akzentfarbe der
   App (.btn/.topnav) mit dezenter Unterstreichung — dadurch bleiben Links
   erkennbar, ohne einen zusätzlichen, unpassenden Farbton einzuführen.
   Spezifischere Regeln (Nav, Breadcrumbs, Buttons) haben Vorrang. */
a:link,
a:visited {
  color: #111827;
  text-decoration: underline;
  text-decoration-color: #c7cbd1;
  text-underline-offset: 2px;
  transition: text-decoration-color 0.15s ease;
}

a:hover {
  text-decoration-color: #111827;
}

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

.auth-card {
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
  padding: 2.5rem;
  width: 100%;
  max-width: 420px;
}

.auth-card h1 {
  font-size: 1.4rem;
  font-weight: 700;
  text-align: center;
  margin: 0;
}

.auth-card .subtitle {
  color: #888;
  font-size: 0.88rem;
  text-align: center;
  margin: 0.4rem 0 2rem;
}

form label {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  margin: 1rem 0 0.3rem;
}

form label:first-child {
  margin-top: 0;
}

form input[type='email'],
form input[type='password'],
form input[type='text'],
form input[type='number'],
form input[type='date'],
form input[type='datetime-local'],
form select,
form textarea {
  width: 100%;
  padding: 0.65rem 0.8rem;
  border: 1.5px solid #d1d5db;
  border-radius: 8px;
  font-size: 1rem;
  font-family: inherit;
  background: #fff;
}

form textarea {
  font-family: inherit;
  resize: vertical;
}

.table-input {
  width: 100%;
  min-width: 8rem;
  padding: 0.4rem 0.6rem;
  border: 1.5px solid transparent;
  border-radius: 6px;
  font-size: 0.88rem;
  background: transparent;
  font-family: inherit;
}

.table-input:hover,
.table-input:focus {
  border-color: #d1d5db;
  background: #fff;
}

.table-checkbox-label {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.88rem;
}

.dt-override-block {
  margin-top: 1rem;
}

.country-rule-box {
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  overflow: hidden;
}

.country-rule-item {
  border-bottom: 1px solid #e5e7eb;
}

.country-rule-item:last-child {
  border-bottom: none;
}

.country-rule-item summary {
  padding: 0.7rem 1rem;
  cursor: pointer;
  font-weight: 600;
  list-style: none;
}

.country-rule-item summary::-webkit-details-marker {
  display: none;
}

.country-rule-item summary::before {
  content: '▸';
  display: inline-block;
  width: 1em;
  color: #888;
}

.country-rule-item[open] summary::before {
  content: '▾';
}

.country-rule-item[open] summary {
  border-bottom: 1px solid #e5e7eb;
}

.country-rule-item form {
  padding: 1rem;
}

.country-rule-item form.inline-form {
  padding: 0 1rem 1rem;
}

/* .row-actions sitzt als <div> INNERHALB der td (nicht mehr auf der td
   selbst) — display:flex direkt auf einer td hebt sie aus dem normalen
   Tabellenzellen-Verhalten heraus, wodurch sie sich nicht mehr automatisch
   auf die (durch die höchste Zelle bestimmte) Zeilenhöhe streckt und ihr
   unterer Rand dadurch versetzt zu den übrigen Zellen der Zeile liegt. Als
   div bleibt die td selbst eine normale Zelle (volle Zeilenhöhe,
   vertical-align:middle zentriert den Button-Inhalt korrekt), nur die
   horizontale Anordnung der Buttons kommt vom div. */
.row-actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  /* Genug Platz für "Speichern" + "Löschen" nebeneinander, damit diese
     Spalte in einer auto-layout-Tabelle nicht kleiner als ihr Inhalt
     braucht wirkt (bzw. knapp umbricht) — die anderen Spalten wachsen bei
     Bedarf einfach etwas weniger. */
  min-width: 11rem;
}

form input.code-input {
  text-align: center;
  letter-spacing: 0.3em;
  font-size: 1.4rem;
  font-weight: 700;
  font-family: monospace;
}

.btn {
  display: block;
  width: 100%;
  margin-top: 1.5rem;
  padding: 0.7rem 1rem;
  background: #111827;
  color: #fff;
  border: none;
  border-radius: 8px;
  font-size: 1rem;
  font-weight: 600;
  text-align: center;
  cursor: pointer;
}

.btn:hover {
  background: #000;
}

.btn:disabled,
.btn-sm:disabled {
  opacity: 0.6;
  cursor: default;
}

.alert {
  background: #fef2f2;
  border: 1px solid #fecaca;
  color: #991b1b;
  border-radius: 8px;
  padding: 0.8rem 1rem;
  font-size: 0.88rem;
  margin-bottom: 1.2rem;
}

.success {
  background: #f0fdf4;
  border: 1px solid #bbf7d0;
  color: #166534;
  border-radius: 8px;
  padding: 0.8rem 1rem;
  font-size: 0.88rem;
  margin-top: 1.2rem;
}

.hint {
  background: #fffbea;
  border: 1px solid #fde68a;
  color: #92400e;
  border-radius: 8px;
  padding: 0.8rem 1rem;
  font-size: 0.85rem;
  margin-bottom: 1.2rem;
}

.center-link {
  text-align: center;
  margin-top: 1.2rem;
  font-size: 0.83rem;
}

.center-link.tight {
  margin-top: 0;
}

.center-link a {
  color: #888;
}

.setup-box {
  text-align: center;
  margin-bottom: 1rem;
}

.setup-box img {
  border-radius: 8px;
  border: 4px solid #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  max-width: 180px;
  margin: 0 auto 1rem;
  display: block;
}

.setup-box .secret-label {
  font-size: 0.75rem;
  color: #888;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 0.2rem;
}

.setup-box code {
  font-size: 0.85rem;
  letter-spacing: 0.07em;
  font-weight: 700;
  word-break: break-all;
}

.topnav {
  display: flex;
  align-items: center;
  gap: 0 2rem;
  background: #111827;
  color: #fff;
  padding: 0.9rem 1.5rem;
  flex-wrap: wrap;
}

.topnav-top {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  color: #fff;
  padding: 0.35rem;
  margin: 0;
  cursor: pointer;
  border-radius: 6px;
}

.nav-toggle:hover {
  background: rgba(255, 255, 255, 0.1);
}

.nav-toggle svg {
  width: 24px;
  height: 24px;
  display: block;
}

.topnav-collapse {
  display: flex;
  align-items: center;
  flex: 1;
  gap: 0.6rem 2rem;
  flex-wrap: wrap;
}

.topnav-brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 700;
}

.brand-logo {
  height: 28px;
  width: 28px;
  display: block;
  background: #fff;
  border-radius: 50%;
  padding: 2px;
}

.topnav-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.2rem;
  flex: 1;
  min-width: 0;
}

.topnav-links a {
  color: #d1d5db;
  font-size: 0.9rem;
  text-decoration: none;
}

.topnav-links a:hover {
  color: #fff;
}

#ajax-toast {
  position: fixed;
  top: 1rem;
  left: 50%;
  transform: translateX(-50%) translateY(-0.5rem);
  background: #111827;
  color: #fff;
  padding: 0.6rem 1.2rem;
  border-radius: 8px;
  font-size: 0.88rem;
  font-weight: 600;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
  z-index: 1000;
}

#ajax-toast.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

.nav-badge {
  display: inline-block;
  min-width: 1.2rem;
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
  background: #dc2626;
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  text-align: center;
  vertical-align: middle;
}

.topnav-user {
  display: flex;
  align-items: center;
  gap: 1rem;
  font-size: 0.85rem;
  color: #f3f4f6;
  font-weight: 500;
}

/* Links & Benutzerzeile hinter einem Menü-Knopf einklappen statt sie als eng
   gequetschten, mehrzeiligen Textblock neben dem Logo umbrechen zu lassen —
   jeder Link bekommt hier eine eigene, gut antippbare Zeile mit Trennlinie
   statt winziger Lücken zwischen Fließtext-Links. Schwelle bewusst hoch
   (1300px statt eines klassischen Handy/Tablet-Breakpoints): Super-Admin hat
   9 Nav-Links + Brand + Benutzerzeile, das passt schon auf vielen normalen
   Laptop-Fenstern (~1280-1366px) nicht mehr in eine Zeile und würde sonst
   sichtbar umbrechen. */
@media (max-width: 1300px) {
  .topnav {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0.7rem 1rem;
  }

  .topnav-top {
    justify-content: space-between;
  }

  .nav-toggle {
    display: flex;
  }

  .topnav-collapse {
    display: none;
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    gap: 0;
    margin-top: 0.6rem;
    padding-top: 0.4rem;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
  }

  .topnav.is-open .topnav-collapse {
    display: flex;
  }

  .topnav-links {
    flex-direction: column;
    flex: none;
    gap: 0;
  }

  .topnav-links a {
    padding: 0.85rem 0.3rem;
    font-size: 1rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  }

  .topnav-user {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.8rem 0.3rem 0.4rem;
  }
}

.topnav-user a {
  color: #f3f4f6;
}

.session-timer {
  font-size: 0.85rem;
  font-weight: 700;
  color: #f3f4f6;
  font-variant-numeric: tabular-nums;
  padding: 0.15em 0.55em;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.12);
}

.session-timer.session-timer-warning {
  color: #fff;
  background: #dc2626;
}

.page {
  /* Skaliert mit der Fensterbreite statt fest bei 960px gedeckelt zu sein —
     auf breiten Bildschirmen bekommen breite Tabellen (Buchhaltung,
     Ticketsystem, Saalplan bei der manuellen Buchung) so spürbar mehr Platz
     und müssen seltener intern horizontal scrollen (siehe .card
     overflow-x). Obergrenze verhindert nur, dass reiner Fließtext/Formulare
     auf sehr breiten Monitoren unangenehm lange Zeilen bekommen. */
  max-width: min(96vw, 1440px);
  margin: 2.5rem auto;
  padding: 0 1.5rem;
}

.page h1 {
  margin-bottom: 0.3rem;
}

.page .meta {
  color: #555;
  font-size: 0.9rem;
  margin-bottom: 1.5rem;
}

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1.5rem;
}

.page-header h1 {
  margin: 0;
}

.plan-rename-form {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.plan-rename-input {
  font-size: 1.3rem;
  font-weight: 700;
  padding: 0.3rem 0.6rem;
  border: 1.5px solid transparent;
  border-radius: 6px;
  min-width: 16rem;
  font-family: inherit;
}

.plan-rename-input:hover,
.plan-rename-input:focus {
  border-color: #d1d5db;
}

table.data-table {
  width: 100%;
  border-collapse: collapse;
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
  /* display:block lässt die Tabelle sich selbst horizontal scrollen statt
     die ganze Seite zu sprengen, wenn sie schmaler ist als ihr Inhalt
     (Handy/Tablet) — Zeilen/Zellen behalten ihr normales Tabellen-Layout,
     nur die äußere Box wird zum eigenen Scroll-Container. */
  display: block;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  max-width: 100%;
}

table.data-table th,
table.data-table td {
  padding: 0.7rem 1rem;
  text-align: left;
  border-bottom: 1px solid #eee;
  font-size: 0.9rem;
  vertical-align: middle;
}

table.data-table th {
  background: #f9fafb;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #666;
  white-space: nowrap;
}

table.data-table .text-right {
  text-align: right;
}

table.data-table tfoot td {
  font-weight: 700;
  border-top: 2px solid #e5e7eb;
  border-bottom: none;
}

table.data-table tr:last-child td {
  border-bottom: none;
}

/* Zeilen-Feedback für per AJAX editierbare Tabellen (siehe Blöcke- und
   Kategorien-Tabelle in seating-plan.ejs): geänderte, noch nicht gespeicherte
   Zeilen gelb/orange, gerade erfolgreich gespeicherte Zeilen kurz grün und
   über ein paar Sekunden ausblendend — unveränderte Zeilen bleiben normal. */
/* Hintergrund auf der ganzen <tr> statt einzelner <td>s: eine Tabellenzeile
   spannt als table-row immer die volle Tabellenbreite, selbst wenn eine
   einzelne Zelle (hier .row-actions mit display:flex) ihre eigene
   Spaltenbreite nicht ausfüllt — sonst reicht die Markierung rechts nicht
   bis zum Rand. Zellen selbst haben kein eigenes Hintergrund, die Row-Farbe
   scheint also normal durch. */
tr.block-row,
tr.category-row,
tr.discount-row {
  transition: background-color 0.3s ease;
}

/* Block ohne zugewiesene Kategorie: dauerhafter roter Hinweis, bis eine
   Kategorie gewählt wird — steht bewusst VOR is-dirty/is-saved in der
   Kaskade, damit der (temporäre) Bearbeitungsstatus bei gleicher
   Spezifität Vorrang hat. */
tr.block-row.no-category {
  background-color: #fef2f2;
}

tr.block-row.is-dirty,
tr.category-row.is-dirty,
tr.discount-row.is-dirty {
  background-color: #fffbeb;
}

tr.block-row.is-saved,
tr.category-row.is-saved,
tr.discount-row.is-saved {
  animation: block-row-saved-fade 3s ease forwards;
}

/* Farbe einer Kategorie als sauberes Quadrat statt des unterschiedlich
   gerenderten Browser-Standard-Looks von <input type="color"> — min-width
   von .table-input (8rem, für Text-/Auswahlfelder gedacht) muss hier
   explizit auf die quadratische Größe zurückgesetzt werden, sonst gewinnt
   sie gegen die schmalere width hier und das Feld bleibt ein Rechteck. */
input[type='color'].color-square {
  width: 2rem;
  min-width: 2rem;
  height: 2rem;
  padding: 0;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  cursor: pointer;
  background: none;
}

input[type='color'].color-square::-webkit-color-swatch-wrapper {
  padding: 0;
}

input[type='color'].color-square::-webkit-color-swatch {
  border: none;
  border-radius: 5px;
}

input[type='color'].color-square::-moz-color-swatch {
  border: none;
  border-radius: 5px;
}

/* Kategorien-Tabelle: die Name-Spalte bekommt explizit die ganze übrige
   Breite (in der normalen, inhaltsbasierten auto-Verteilung reicht das, um
   die Tabelle auf 100% zu strecken) — Farbe/Stehplatz/Aktionen bleiben so
   groß wie ihr Inhalt braucht, statt fest (und dadurch leicht zu eng)
   vorgegeben zu sein. table-layout:fixed mit festen rem-Breiten für die
   Buttons-Spalte hatte die Speichern/Löschen-Buttons umbrechen lassen. */
#categories-table th:nth-child(2),
#categories-table td:nth-child(2) {
  width: 100%;
}

#discounts-table th:nth-child(3),
#discounts-table td:nth-child(3) {
  width: 100%;
}

@keyframes block-row-saved-fade {
  0%,
  35% {
    background-color: #bbf7d0;
  }
  100% {
    background-color: transparent;
  }
}

.tabs {
  display: flex;
  gap: 0.25rem;
  border-bottom: 1px solid #e5e7eb;
  margin-bottom: 1.5rem;
  overflow-x: auto;
  overflow-y: hidden;
}

.tab-btn {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 0.7rem 1rem;
  margin-bottom: -1px;
  font-size: 0.9rem;
  font-weight: 600;
  color: #666;
  cursor: pointer;
  white-space: nowrap;
}

.tab-btn:hover {
  color: #111827;
}

.tab-btn.active {
  color: #111827;
  border-bottom-color: #111827;
}

.card {
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
  padding: 1.5rem;
  margin-bottom: 1.5rem;
  /* Breite Tabellen (data-table) dürfen die Karte intern scrollen statt die
     ganze Seite horizontal zu sprengen — auf Handy/Tablet sorgt genau das
     sonst dafür, dass der mobile Browser den gesamten Viewport aufzoomt und
     alles winzig darstellt. */
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.checkbox-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0.5rem 1rem;
  margin: 1rem 0;
  max-height: 320px;
  overflow-y: auto;
  padding: 0.25rem;
}

.checkbox-grid label {
  font-size: 0.88rem;
  font-weight: 400;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
}

.card h2 {
  margin-top: 0;
  font-size: 1.05rem;
}

/* Eine zweite (oder weitere) Überschrift innerhalb derselben Karte — z.B.
   "Neue Kategorie"/"Neuer Block" nach der jeweiligen Tabelle — braucht mehr
   Abstand zum Element davor, sonst klebt sie direkt daran. Nur die
   Karten-Hauptüberschrift (erstes Kind) bleibt bei margin-top:0. */
.card h2:not(:first-child) {
  margin-top: 2rem;
}

/* Abgesetzte Einstellungsgruppe innerhalb einer .card, z.B. Video-Auswahl auf
   der Startseite — liegt außerhalb eines <form>-Elements (Speichern läuft
   dort per JS/fetch), braucht deshalb eigene Feld-/Label-Styles statt der
   globalen "form label"/"form input"-Regeln. */
.video-settings {
  border: 1.5px solid #e5e7eb;
  border-radius: 8px;
  padding: 1.1rem 1.2rem 1.2rem;
  margin: 1rem 0 1.5rem;
  background: #fafafa;
}

.video-settings h3 {
  margin: 0 0 0.5rem;
  font-size: 0.95rem;
}

.video-settings code {
  background: #eef0f3;
  border-radius: 4px;
  padding: 0.05rem 0.35rem;
  font-size: 0.85em;
}

.radio-group {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.5rem;
  margin: 0.8rem 0;
}

.radio-option {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
}

.video-settings .field {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid #e5e7eb;
}

.video-settings .field label {
  display: block;
  font-size: 0.8rem;
  font-weight: 600;
  margin-bottom: 0.35rem;
}

.video-settings .field input[type='text'] {
  width: 100%;
  max-width: 480px;
  padding: 0.55rem 0.75rem;
  border: 1.5px solid #d1d5db;
  border-radius: 6px;
  font-size: 0.9rem;
  font-family: inherit;
}

.video-settings .field .meta {
  margin: 0.5rem 0 0;
}

.form-inline {
  display: flex;
  gap: 0.6rem;
  align-items: flex-end;
  flex-wrap: wrap;
}

.form-inline label {
  display: block;
  font-size: 0.78rem;
  font-weight: 600;
  margin-bottom: 0.3rem;
}

.form-inline input,
.form-inline select {
  padding: 0.5rem 0.6rem;
  border: 1.5px solid #d1d5db;
  border-radius: 6px;
  font-size: 0.9rem;
}

.btn-sm {
  display: inline-block;
  padding: 0.4rem 0.8rem;
  background: #111827;
  color: #fff;
  border: none;
  border-radius: 6px;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
}

/* "+ Neue Kategorie"/"+ Neuer Block": folgt direkt auf die Tabelle
   (bzw. deren Status-Zeile) und klebt ohne Abstand daran. */
.add-row-btn {
  margin-top: 1rem;
}

.btn-sm:hover {
  background: #000;
}

.btn-sm.danger {
  background: #dc2626;
}

.is-loading {
  opacity: 0.6;
  pointer-events: none;
}

.btn-sm.danger:hover {
  background: #b91c1c;
}

.btn-sm.ghost {
  background: #fff;
  color: #111827;
  border: 1.5px solid #d1d5db;
}

.pill {
  display: inline-block;
  padding: 0.15em 0.6em;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
  background: #eef2ff;
  color: #3730a3;
}

.pill-new {
  background: #dc2626;
  color: #fff;
}

tr.row-link {
  cursor: pointer;
}

tr.row-link:hover td {
  background: #f4f6f9;
}

tr.row-link.unread td {
  font-weight: 600;
}

.pill-queued {
  background: #eef2ff;
  color: #3730a3;
}

.pill-retrying {
  background: #fef3c7;
  color: #92400e;
}

.pill-sent {
  background: #dcfce7;
  color: #166534;
}

.pill-failed {
  background: #fef2f2;
  color: #991b1b;
}

.filter-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.filter-tabs a {
  padding: 0.35rem 0.8rem;
  border-radius: 999px;
  font-size: 0.85rem;
  text-decoration: none;
  color: #555;
  background: #f0f0f0;
}

.filter-tabs a.active {
  background: #111827;
  color: #fff;
}

.empty-state {
  color: #888;
  font-size: 0.9rem;
  padding: 1.5rem;
  text-align: center;
}

.breadcrumbs {
  font-size: 0.85rem;
  color: #888;
  margin-bottom: 0.5rem;
}

.breadcrumbs a {
  color: #888;
}

.inline-form {
  display: inline;
  margin-right: 1.5rem;
}

/* Für .inline-form-Formulare, die (anders als ein einzelner Button) ein
   Label+Select-Paar enthalten: die machen wegen "form select { width:100% }"
   den ganzen umschließenden Block breit und stapeln sich sonst ohne jeden
   Abstand übereinander. */
.field-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem 2rem;
}

.order-summary {
  margin-top: 1rem;
}

.field-row form.inline-form {
  display: block;
  margin: 0;
}

.field-row form.inline-form select {
  width: auto;
  min-width: 14rem;
}

.recenter-form {
  display: block;
  margin-top: 0.75rem;
}

.editor-toolbar {
  display: flex;
  gap: 1.5rem;
  align-items: flex-end;
  flex-wrap: wrap;
  margin-bottom: 1rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid #eee;
}

.editor-toolbar label {
  display: block;
  font-size: 0.78rem;
  font-weight: 600;
  margin-bottom: 0.3rem;
}

.editor-toolbar select,
.editor-toolbar input {
  padding: 0.45rem 0.6rem;
  border: 1.5px solid #d1d5db;
  border-radius: 6px;
  font-size: 0.9rem;
}

.editor-toolbar-status {
  font-size: 0.82rem;
  color: #888;
  align-self: center;
}

.zoom-controls {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
}

.zoom-controls span {
  font-size: 0.85rem;
  color: #555;
  min-width: 3.2em;
  text-align: center;
}

.editor-toolbar-status.is-error {
  color: #dc2626;
}

.editor-save-status {
  min-height: 1.2em;
  margin-top: 1.5rem;
  font-size: 0.9rem;
  font-weight: 600;
}

.editor-save-status:empty {
  display: none;
}

.editor-save-status.is-success {
  padding: 0.6rem 0.9rem;
  border-radius: 8px;
  background: #f0fdf4;
  border: 1px solid #bbf7d0;
  color: #166534;
}

.editor-save-status.is-error {
  padding: 0.6rem 0.9rem;
  border-radius: 8px;
  background: #fef2f2;
  border: 1px solid #fecaca;
  color: #991b1b;
}

.editor-commit-controls {
  display: flex;
  gap: 1rem;
  margin-top: 0.75rem;
}

.editor-commit-controls .btn {
  flex: 1;
  margin-top: 0;
  padding: 1rem;
  font-size: 1.1rem;
}

.editor-commit-controls .btn.ghost {
  background: #fff;
  color: #111827;
  border: 1.5px solid #d1d5db;
}

.editor-commit-controls .btn.ghost:hover {
  background: #f9fafb;
}

@media (max-width: 600px) {
  .editor-commit-controls {
    flex-direction: column;
  }
}

.editor-dirty-indicator {
  font-size: 0.82rem;
  font-weight: 600;
  color: #b45309;
  background: #fffbeb;
  border: 1px solid #fde68a;
  border-radius: 6px;
  padding: 0.3rem 0.7rem;
  align-self: center;
}

.side-panel-actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 1rem;
}

/* In einer Tabellenzelle sprengt der obere Abstand die vertikale Zentrierung
   der Zeile (vertical-align:middle zentriert den ganzen Inhalt inkl.
   margin-top, wodurch die Buttons sichtbar tiefer als der restliche
   Zeileninhalt sitzen) — hier ist kein Zwischenraum zu etwas Darüberliegendem
   nötig wie bei den übrigen .side-panel-actions-Stellen (Karten, Dialog). */
table.data-table .side-panel-actions {
  margin-top: 0;
}

.placeholder-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 1rem 0;
}

.quill-editor {
  background: #fff;
}

.quill-editor .ql-editor {
  min-height: 220px;
  font-size: 1rem;
}

#homepage-editor .ql-editor {
  min-height: 360px;
}

/* Kompakte Quill-Instanz je Tabellenzeile (Userverwaltung, Signatur) — der
   Standard-Editor ist mit 220px viel zu hoch für ein paar Zeilen Signatur. */
.quill-cell {
  min-width: 22rem;
}

.quill-cell .ql-editor {
  min-height: 70px;
  font-size: 0.88rem;
}

.editor-layout {
  display: flex;
  flex-direction: column;
  gap: 1.2rem;
}

.editor-canvas-wrap {
  width: 100%;
  overflow: auto;
  border: 1.5px solid #e5e7eb;
  border-radius: 8px;
  background: #fafafa;
  max-height: 640px;
  /* touch-action:none auf den einzelnen SVG-Elementen (Anfasser, Plätze,
     Blöcke) reicht auf manchen Touch-Browsern nachweislich NICHT — die
     Wisch-Geste startet dort trotzdem ein natives Scrollen und bricht das
     Ziehen mitten in der Bewegung ab (touch-action wird auf verschachtelten
     SVG-Kindelementen nicht zuverlässig respektiert, u. a. auf älteren
     WebKit-Versionen). Daher hier fest auf dem Wrapper (einem normalen div,
     wo touch-action durchgängig unterstützt wird) deaktiviert — das nimmt
     in Kauf, dass leere Fläche nicht mehr per Ein-Finger-Wisch verschoben
     werden kann (Zoom-Regler und Scrollbar funktionieren unverändert).
     Maus-Scrollen/-Wheel ist von touch-action nicht betroffen. */
  touch-action: none;
}

@media (max-width: 780px) {
  .editor-canvas-wrap {
    /* Auf schmalen Bildschirmen sonst zu viel Fläche unterhalb des sichtbaren
       Ausschnitts — verschachteltes Scrollen (Seite + Canvas) verwirrt beim
       Wischen. Kleinerer Ausschnitt, dafür mit Zoom-Reglern gezielt navigierbar. */
    max-height: 60vh;
  }
}

.editor-canvas-wrap svg {
  display: block;
  cursor: crosshair;
}

.blocking-canvas-wrap {
  touch-action: auto;
}

.blocking-canvas-wrap svg {
  cursor: default;
}

.editor-side-panel {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 1rem;
  border: 1.5px solid #e5e7eb;
  border-radius: 8px;
  padding: 1rem;
}

.editor-side-panel .field {
  display: flex;
  flex-direction: column;
}

.editor-side-panel label {
  display: block;
  font-size: 0.78rem;
  font-weight: 600;
  margin: 0 0 0.3rem;
}

.editor-side-panel input,
.editor-side-panel select {
  width: 160px;
  padding: 0.45rem 0.6rem;
  border: 1.5px solid #d1d5db;
  border-radius: 6px;
  font-size: 0.9rem;
}

.editor-side-panel .side-panel-actions {
  margin-top: 0;
}

.panel-label {
  width: 100%;
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
}

.panel-status {
  width: 100%;
  min-height: 1.2em;
  padding: 0;
  font-size: 0.85rem;
  transition: padding 0.15s ease;
}

.panel-status:empty {
  display: none;
}

.panel-status.is-success {
  padding: 0.5rem 0.8rem;
  border-radius: 6px;
  background: #f0fdf4;
  border: 1px solid #bbf7d0;
  color: #166534;
}

.panel-status.is-error {
  padding: 0.5rem 0.8rem;
  border-radius: 6px;
  background: #fef2f2;
  border: 1px solid #fecaca;
  color: #991b1b;
}

.seat-circle {
  stroke: #fff;
  stroke-width: 1.5;
  cursor: grab;
  /* Ohne dieses touch-action versucht der Browser bei einer Ziehgeste auf
     einem Touch-Gerät, den Canvas-Ausschnitt zu scrollen, statt den Platz
     zu verschieben — das JS bekommt die Pointer-Events dann nur bruchstückhaft. */
  touch-action: none;
}

.seat-circle.selected {
  stroke: #111827;
  stroke-width: 2.5;
}

.seat-label {
  font-size: 8px;
  fill: #fff;
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
  font-family: monospace;
}

.stage-rect {
  fill: #374151;
  stroke: #111827;
  stroke-width: 1.5;
  rx: 6;
  cursor: grab;
  touch-action: none;
}

.stage-rect.selected {
  stroke: #2563eb;
  stroke-width: 3;
}

.stage-label {
  font-size: 13px;
  font-weight: 600;
  fill: #fff;
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.marker-rect {
  fill: #fef9c3;
  stroke: #a16207;
  stroke-width: 1.5;
  stroke-dasharray: 3 3;
  rx: 4;
  cursor: grab;
  touch-action: none;
}

.marker-rect.selected {
  stroke: #2563eb;
  stroke-width: 3;
  stroke-dasharray: none;
}

.marker-label {
  font-size: 12px;
  font-weight: 600;
  fill: #713f12;
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
}

.area-rect {
  fill-opacity: 0.35;
  stroke: #1f2937;
  stroke-width: 1.5;
  stroke-dasharray: 6 4;
  cursor: grab;
  touch-action: none;
}

.area-rect.selected {
  stroke: #2563eb;
  stroke-width: 3;
  stroke-dasharray: none;
}

/* Block enthält bereits verkaufte/reservierte Plätze — kann nicht mehr
   verschoben/skaliert/gelöscht werden (siehe hasSoldSeats). Grabbing-Cursor
   weg, damit es nicht wie ein normal ziehbarer Block aussieht. */
.area-rect.locked {
  cursor: not-allowed;
  stroke-dasharray: none;
  fill-opacity: 0.5;
}

.area-label {
  font-size: 13px;
  font-weight: 600;
  fill: #1f2937;
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
}

/* Sperren-Übersicht (event-blocking.ejs) — eigene, nicht-ziehbare Varianten
   der Block-/Sitzplatz-Darstellung, bewusst mit eigenem Klassennamen statt
   .area-rect/.seat-circle, damit sie nicht die Zieh-/Editor-Optik erben. */
.block-area-clickable {
  cursor: pointer;
}

.block-area-rect {
  fill-opacity: 0.35;
  stroke: #1f2937;
  stroke-width: 1.5;
}

.block-area-rect.block-area-blocked {
  fill: #9ca3af !important;
  fill-opacity: 0.5;
  stroke: #6b7280;
  stroke-dasharray: 4 3;
}

.block-area-label {
  font-size: 13px;
  font-weight: 600;
  fill: #1f2937;
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
}

.block-seat-dot {
  stroke: #fff;
  stroke-width: 1.5;
  cursor: pointer;
}

.block-seat-dot.sold {
  fill: #cbd5e1 !important;
  cursor: not-allowed;
}

.block-seat-dot.reserved-other {
  fill: #f97316 !important;
}

.block-seat-dot.blocked {
  fill: #9ca3af !important;
  opacity: 0.6;
}

/* Manuelle Buchung: nur frei/gesperrt ist hier wählbar — verkauft/auf
   Zahlung wartend ("sold") und im Warenkorb eines Kunden ("reserved-other")
   bleiben wie beim Sperren-Editor nicht klickbar. */
#booking-canvas .block-seat-dot.reserved-other {
  cursor: not-allowed;
}

#booking-canvas .block-area-rect.block-area-full {
  cursor: not-allowed;
  opacity: 0.4;
}

/* Von uns gesperrt, aber hier bewusst weiterhin wählbar — braucht eine klar
   eigene, nicht mit "verkauft" (grau) verwechselbare Markierung statt der
   grauen Sperren-Editor-Optik. */
#booking-canvas .block-seat-dot.blocked {
  fill: #f59e0b !important;
  opacity: 1;
  stroke: #b45309;
  stroke-width: 2;
}

#booking-canvas .block-area-rect.block-area-blocked {
  fill: #f59e0b !important;
  fill-opacity: 0.45;
  stroke: #b45309;
  stroke-dasharray: none;
}

#booking-canvas .block-seat-dot.in-selection {
  stroke: #16a34a;
  stroke-width: 3.5;
}

.seat-status-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 1rem;
  list-style: none;
  padding: 0;
  margin: 0 0 0.8rem;
  font-size: 0.82rem;
}

.seat-status-legend li {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.seat-status-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  display: inline-block;
}

.seat-status-dot.seat-status-free {
  background: #16a34a;
}

.seat-status-dot.seat-status-sold-booking {
  background: #cbd5e1;
}

.seat-status-dot.seat-status-blocked-booking {
  background: #f59e0b;
  border: 1.5px solid #b45309;
}

.area-lock-icon {
  font-size: 13px;
  pointer-events: none;
}

/* Vorläufige, noch nicht gespeicherte Sperre (Block-Panel-Icon) — amber statt
   dem roten Sperr-Icon für bereits verkaufte/reservierte Blöcke. */
.area-lock-icon.pending {
  fill: #d97706;
}

.seat-circle.admin-locked {
  stroke: #d97706;
  stroke-width: 3;
}

.resize-handle {
  fill: #2563eb;
  stroke: #fff;
  stroke-width: 1;
  touch-action: none;
}

.resize-handle.dir-n,
.resize-handle.dir-s {
  cursor: ns-resize;
}

.resize-handle.dir-e,
.resize-handle.dir-w {
  cursor: ew-resize;
}

.resize-handle.dir-nw,
.resize-handle.dir-se {
  cursor: nwse-resize;
}

.resize-handle.dir-ne,
.resize-handle.dir-sw {
  cursor: nesw-resize;
}

.color-swatch {
  display: inline-block;
  width: 0.9em;
  height: 0.9em;
  border-radius: 3px;
  vertical-align: middle;
  margin-right: 0.4em;
}

/* ── News ────────────────────────────────────────────────────────────────── */

.news-form {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  max-width: 560px;
}

.news-form .field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.news-form label {
  font-size: 0.78rem;
  font-weight: 600;
}

.news-form textarea {
  font-family: inherit;
  padding: 0.6rem 0.8rem;
  border: 1.5px solid #d1d5db;
  border-radius: 8px;
  font-size: 0.95rem;
  resize: vertical;
}

.news-item {
  border: 1.5px solid #e5e7eb;
  border-radius: 10px;
  padding: 0.8rem 1rem;
  margin-bottom: 0.8rem;
}

.news-item summary {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem 0.8rem;
  cursor: pointer;
  list-style: none;
}

.news-item summary::-webkit-details-marker {
  display: none;
}

.news-item-title {
  font-weight: 600;
  flex: 1;
  min-width: 140px;
  overflow-wrap: break-word;
}

.news-thumb {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: 6px;
}

.news-thumb-large {
  max-width: 240px;
  max-height: 160px;
  display: block;
  border-radius: 8px;
  margin-bottom: 0.4rem;
}

.news-item form {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid #f0f0f0;
}

/* Popup für die Vergünstigungen-Zuweisung eines Blocks (seating-plan.ejs) —
   natives <dialog>, damit Backdrop/Esc-zum-Schließen/Fokus-Falle ohne
   eigenes JS funktionieren. */
.discount-modal {
  width: min(32rem, calc(100vw - 2rem));
  border: none;
  border-radius: 10px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  padding: 1.5rem;
}

.discount-modal::backdrop {
  background: rgba(0, 0, 0, 0.4);
}

.filter-bar {
  display: flex;
  gap: 1rem;
  /* stretch statt flex-end: alle direkten Kinder (Label+Feld-Paare wie
     Buttons-Spalte) bekommen dieselbe Höhe wie das höchste Geschwister —
     robuster als zu versuchen, Input- und Button-Innenabstände pixelgenau
     anzugleichen (das hat vorher nicht zuverlässig geklappt). */
  align-items: stretch;
  margin-bottom: 1rem;
}

.filter-bar > div {
  display: flex;
  flex-direction: column;
}

.filter-bar label {
  margin: 0 0 0.3rem;
}

.filter-bar select {
  min-width: 12rem;
}

/* Buttons neben einem Label+Eingabefeld-Paar bekommen dasselbe unsichtbare
   Label darüber (siehe filter-bar-actions in tickets.ejs/accounting.ejs),
   damit die Buttons-Zeile erst auf derselben Höhe wie das Eingabefeld
   beginnt. flex:1 + align-items:center zentriert die Buttons dann in der
   durch align-items:stretch oben erzwungenen vollen Resthöhe. */
.filter-bar-actions label {
  visibility: hidden;
}

.filter-bar-actions > div {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.ticket-thread {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin: 1rem 0 1.5rem;
}

.ticket-message {
  padding: 0.9rem 1rem;
  border-radius: 8px;
  background: #f4f6f9;
}

.ticket-message.note {
  background: #fef9e7;
}

.ticket-message.inbound {
  background: #eaf2fe;
}

.ticket-message .ticket-message-meta {
  font-size: 0.8rem;
  color: #777;
  margin-bottom: 0.4rem;
}

.ticket-message .ticket-message-body {
  white-space: pre-wrap;
}

.discount-modal h2 {
  margin-top: 0;
  font-size: 1.05rem;
}
