/* ==========================================================================
   Cockpit best-weekend — zentrales Stylesheet
   Farbwelt uebernommen von best-weekend.de (Shopware-Theme, 19.07.2026):
   Gold #ce9e3c als Primaerfarbe (Buttons/Links des Shops), Anthrazit #2b3136
   (Body-Text des Shops) als Kopfleiste, warmes Hell fuer Flaechen. Das Logo
   (assets/img/logo-best-weekend.svg, Grau/Gold/Weiss) steht auf dem dunklen
   Header und den Auth-Seiten.
   ========================================================================== */

:root {
    /* --- Farbwelt best-weekend.de --- */
    --accent:        #ce9e3c;   /* Shop-Primaerfarbe: Gold */
    --accent-hover:  #d5ad59;   /* Hover-Gold des Shops */
    --accent-fg:     #1c1608;   /* dunkler Text auf Gold (Shop nutzt #000) */
    --accent-deep:   #523f18;   /* dunkles Gold fuer Text-Akzente auf hell */
    --header-bg:     #2b3136;   /* Anthrazit (Shop-Textfarbe) */
    --header-fg:     #ffffff;

    /* --- Flaechen & Text (warmes Neutral, harmoniert mit Gold) --- */
    --bg:            #f6f4ef;
    --bg-hover:      #faf8f3;
    --card:          #ffffff;
    --bd:            #e6e1d5;
    --fg:            #2b3136;
    --muted:         #6d7278;
    --danger:        #c20017;   /* Fehlerrot des Shop-Themes */
    --shadow-sm:     0 1px 2px rgba(43, 49, 54, 0.08);

    /* --- Links (VN 29.08.2026) ---
       Das reine Shop-Gold (#ce9e3c) ist auf Weiss zu hell zum Lesen (Kontrast
       nur 2,2:1). Fuer Textlinks daher ein abgedunkeltes Gold-Braun mit rund
       5:1 Kontrast (WCAG AA), das trotzdem eindeutig golden wirkt und sich klar
       vom anthrazitfarbenen Fliesstext abhebt. Beim Ueberfahren wird es noch
       dunkler, die Unterstreichung dafuer kraeftiger. */
    --link:           #8a6a22;
    --link-hover:     var(--accent-deep);
    --link-underline: rgba(206, 158, 60, 0.55);  /* zartes Gold */

    /* --- Umgebungs-Badge: local = grau, test = orange, live = gruen --- */
    --env-local:     #64748b;
    --env-test:      #f59e0b;
    --env-live:      #10b981;

    /* --- Gemeinsame Fluchtlinie (VN 29.08.2026) ---
       Der Inhalt der Kopfleiste (Logo links, Logout rechts) soll links wie
       rechts genau dort beginnen, wo auch der Karten-Inhalt beginnt (z. B. die
       Schaltflaeche "Einchecken" auf stock.php). Kasten-Elemente wie Karten und
       Meldungen richten sich weiterhin mit ihrem RAND an --gutter aus; ihr
       INHALT liegt um Rahmen + Innenabstand weiter innen — genau das ist
       --content-inset. Wer eine der drei Groessen aendert, verschiebt die
       Fluchtlinie automatisch mit. */
    --gutter:        20px;  /* Abstand der Kaesten zum Fensterrand (.wrap) */
    --card-pad-x:    30px;  /* Innenabstand der Karte (.card) */
    --content-inset: calc(var(--gutter) + 1px + var(--card-pad-x));  /* = 51px */
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    background: var(--bg);
    color: var(--fg);
    font-size: 15px;
    line-height: 1.5;
}

/* --------------------------------------------------------------------------
   Links — einheitlicher Standard fuer die ganze Anwendung (VN 29.08.2026)
   Vorher gab es gar keine globale Regel: alle Links ohne eigene Klasse
   erschienen im Browser-Blau mit dicker Unterstreichung (z. B. die Monate auf
   settlement.php) — das passte nicht zur Gold/Anthrazit-Farbwelt.
   Bewusst als reine Element-Regel (a { … }) gehalten: Jede vorhandene
   Link-Klasse (.bw-nav-link, .btn, .page-chip, .bw-logout …) ist staerker und
   behaelt ihr eigenes Aussehen ohne Anpassung.
   -------------------------------------------------------------------------- */
a {
    color: var(--link);
    /* Fein gestrichelte Linie (VN 29.08.2026) — zurueckhaltender als ein
       durchgezogener Strich, aber eindeutig als Link erkennbar. Beim
       Ueberfahren wird sie durchgezogen und kraeftiger. */
    text-decoration: underline dashed;
    text-decoration-color: var(--link-underline);
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
    transition: color 0.12s ease, text-decoration-color 0.12s ease;
}
a:hover {
    color: var(--link-hover);
    text-decoration-style: solid;
    text-decoration-color: currentColor;
}
/* Tastaturbedienung: sichtbarer Goldrahmen — Mausklicks loesen ihn nicht aus. */
a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

/* Zarter Pfeil nach rechts oben als Link-Kennzeichen (VN 29.08.2026).
   Bewusst nur an Links OHNE eigene Klasse: Navigation, Schaltflaechen,
   Seitenzahlen, Logout usw. tragen eine Klasse und sollen ihr Aussehen
   behalten — sie sind als Bedienelement ohnehin erkennbar.
   display:inline-block haelt die Unterstreichung vom Pfeil fern. */
a:not([class])::after {
    content: '\2197';           /* ↗ */
    display: inline-block;
    margin-left: 0.18em;
    font-size: 0.78em;
    line-height: 1;
    vertical-align: 0.14em;
    color: var(--accent);
    opacity: 0.75;
}
a:not([class]):hover::after { opacity: 1; }

/* In farbigen Meldungskaesten wuerde Gold mit der Kastenfarbe streiten: Links
   uebernehmen dort die Textfarbe der Meldung und heben sich fett ab — der
   Pfeil ebenso. */
.alert a { color: inherit; text-decoration-color: currentColor; font-weight: 700; }
.alert a::after { color: inherit; }

.m-0 { margin: 0; }
.muted { color: var(--muted); font-size: 14px; }
/* Bewusst gedaempfte Links (z. B. „← Zur Übersicht") bleiben grau, reagieren
   beim Ueberfahren aber wie jeder andere Link. */
a.muted:hover { color: var(--link-hover); }
/* Vollbreiten-Layout (VN 28.07.2026): Inhalt und Kopfleiste nutzen die ganze
   Fensterbreite — vorher 1100px zentriert; stock.php hatte das per .wrap-wide
   schon lokal aufgehoben, jetzt gilt es ueberall. */
.wrap { max-width: none; margin: 0 auto; padding: 28px var(--gutter); }
/* Die Seitenueberschrift steht frei (ohne Kasten) im .wrap und wird deshalb um
   Rahmen + Karten-Innenabstand eingerueckt, damit sie auf derselben Linie
   sitzt wie Logo, Logout und der Karten-Inhalt (VN 29.08.2026). */
.page-head { margin-bottom: 24px; padding: 0 calc(var(--content-inset) - var(--gutter)); }
.page-head .muted { margin-top: 6px; }
/* eBay-Logo im Fliesstext/Ueberschriften (VN 30.08.2026, ebay.php): die
   offizielle Wortmarke (assets/img/logo-ebay.svg) ERSETZT das Wort "eBay".
   Hoehe folgt der Schriftgroesse; die negative vertical-align senkt das Bild
   so ab, dass die Buchstaben auf der Textbaseline stehen — das y des Logos
   hat eine Unterlaenge (~19 % der Bildhoehe), die darunter haengen muss. */
.ebay-logo { height: 1.08em; vertical-align: -0.21em; }

/* --------------------------------------------------------------------------
   Kopfleiste + Navigation
   -------------------------------------------------------------------------- */
.bw-header {
    background: var(--header-bg);
    color: var(--header-fg);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
}
.bw-header-inner {
    max-width: none; /* volle Breite, passend zum Inhalt (.wrap, VN 28.07.2026) */
    margin: 0 auto;
    /* Fluchtlinie mit dem Seiteninhalt (VN 29.08.2026): Logo und Logout
       stehen genau ueber dem Karten-Inhalt darunter, nicht ueber dem
       Karten-Rand. */
    padding: 14px var(--content-inset);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
}
.bw-brand-group { display: flex; align-items: center; gap: 12px; }
.bw-brand { text-decoration: none; color: var(--header-fg); display: flex; align-items: center; gap: 12px; }
.bw-logo { height: 34px; width: auto; display: block; }
.bw-brand-name { font-size: 15px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--accent); }
.bw-build { font-size: 11px; color: rgba(255, 255, 255, 0.55); letter-spacing: 0.03em; }

/* Deutlich sichtbares Umgebungs-Badge (ENTSCHEIDUNGEN.md):
   local = grau, test = orange, live = gruen. Zusaetzlich bekommt der Header
   in test/local einen farbigen Unterstrich, damit man es SOFORT sieht. */
.bw-env-badge {
    display: inline-block;
    padding: 4px 12px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #ffffff;
}
.bw-env-local { background: var(--env-local); }
.bw-env-test  { background: var(--env-test); }
.bw-env-live  { background: var(--env-live); }
/* Konflikt .env vs. Hostname: rot + blinkend — muss sofort auffallen */
.bw-env-mismatch { background: var(--danger); animation: bw-env-blink 1.1s linear infinite; }
@keyframes bw-env-blink { 50% { opacity: 0.45; } }
.bw-header.env-test  { border-bottom: 3px solid var(--env-test); }
.bw-header.env-local { border-bottom: 3px solid var(--env-local); }

.bw-nav { display: flex; align-items: center; gap: 6px; }
.bw-nav-link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 8px 14px;
    border-radius: 8px;
    color: rgba(255, 255, 255, 0.85);
    text-decoration: none;
    font-size: 14px;
    font-weight: 600;
    border: none;
    background: transparent;
    font-family: inherit;
    cursor: pointer;
}
.bw-nav-link:hover { background: rgba(255, 255, 255, 0.1); color: #ffffff; }
.bw-nav-link.active { background: rgba(206, 158, 60, 0.22); color: var(--accent); }
.bw-nav-link svg { width: 16px; height: 16px; }
/* Dashboard-Eintrag ist nur ein Haeuschen-Symbol — etwas groesser als die
   16px-Chevrons, damit es als eigenstaendiger Menuepunkt wirkt. */
.bw-nav-home svg { width: 18px; height: 18px; }

.bw-dropdown { position: relative; }
.bw-dropdown-content {
    display: none;
    position: absolute;
    right: 0;
    top: 100%;
    min-width: 190px;
    background: var(--card);
    border: 1px solid var(--bd);
    border-radius: 10px;
    box-shadow: 0 8px 20px rgba(15, 23, 42, 0.15);
    padding: 6px;
    z-index: 100;
}
.bw-dropdown:hover .bw-dropdown-content,
.bw-dropdown:focus-within .bw-dropdown-content { display: block; }
/* Variante fuer Dropdowns mitten in der Leiste (eBay): linksbuendig unterm
   Button — right:0 passt nur fuer SETUP am rechten Rand. */
.bw-dropdown-left .bw-dropdown-content { left: 0; right: auto; }
.bw-dropdown-content a {
    display: block;
    padding: 9px 12px;
    border-radius: 6px;
    color: var(--fg);
    text-decoration: none;
    font-size: 14px;
}
.bw-dropdown-content a:hover { background: var(--bg-hover); }
.bw-dropdown-content a.active { background: var(--bg); font-weight: 700; }


/* --------------------------------------------------------------------------
   Jahres-Auswahl in der Kopfleiste (VN 26.08.2026)
   Bewusst auffaellig: goldene Pille auf dem Anthrazit-Header, damit sofort
   sichtbar ist, WELCHE Jahre gerade betrachtet werden. Solange "Alle Jahre"
   eingestellt ist, bleibt sie dezent (Umriss); sobald eine Auswahl aktiv ist,
   leuchtet sie gefuellt — die Einschraenkung darf nie unbemerkt wirken.
   -------------------------------------------------------------------------- */
.bw-yearpick { position: relative; margin-left: 10px; }
.bw-yearpick > summary { list-style: none; }
.bw-yearpick > summary::-webkit-details-marker { display: none; }

.bw-yearpick-pill {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 14px;
    border-radius: 999px;
    border: 1.5px solid var(--accent);
    color: var(--accent);
    background: rgba(206, 158, 60, 0.10);
    font-size: 14px;
    font-weight: 800;
    letter-spacing: 0.03em;
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
    transition: background 0.15s, color 0.15s, box-shadow 0.15s;
}
.bw-yearpick-pill:hover { background: rgba(206, 158, 60, 0.22); color: var(--accent-hover); }
.bw-yearpick-pill svg { width: 15px; height: 15px; flex: none; }
.bw-yearpick-chevron { transition: transform 0.15s; opacity: 0.8; }
.bw-yearpick[open] .bw-yearpick-chevron { transform: rotate(180deg); }

/* Aktive Einschraenkung: gefuellt in Gold + weicher Schein. */
.bw-yearpick.is-set .bw-yearpick-pill {
    background: var(--accent);
    color: var(--accent-fg);
    box-shadow: 0 0 0 3px rgba(206, 158, 60, 0.25);
}
.bw-yearpick.is-set .bw-yearpick-pill:hover { background: var(--accent-hover); color: var(--accent-fg); }

.bw-yearpick-panel {
    position: absolute;
    right: 0;
    top: calc(100% + 8px);
    width: 290px;
    background: var(--card);
    color: var(--fg);
    border: 1px solid var(--bd);
    border-radius: 12px;
    box-shadow: 0 12px 28px rgba(15, 23, 42, 0.22);
    padding: 14px;
    z-index: 200;
}
.bw-yearpick-head {
    margin: 0 0 10px;
    font-size: 12px;
    font-weight: 800;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--muted);
}
.bw-yearpick-years { display: flex; flex-wrap: wrap; gap: 7px; }
.bw-yearpick-year { position: relative; }
.bw-yearpick-year input {
    position: absolute; opacity: 0; width: 0; height: 0;
}
.bw-yearpick-year span {
    display: inline-block;
    padding: 7px 13px;
    border-radius: 8px;
    border: 1px solid var(--bd);
    background: var(--bg);
    font-size: 14px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
}
.bw-yearpick-year span:hover { background: var(--bg-hover); border-color: var(--accent); }
.bw-yearpick-year input:checked + span {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-fg);
}
/* Tastaturbedienung sichtbar machen (die Checkbox selbst ist unsichtbar). */
.bw-yearpick-year input:focus-visible + span { outline: 2px solid var(--accent-deep); outline-offset: 2px; }

.bw-yearpick-hint { margin: 12px 0 0; font-size: 12px; line-height: 1.45; color: var(--muted); }
.bw-yearpick-actions { display: flex; gap: 8px; margin-top: 12px; }
.bw-yearpick-btn {
    padding: 7px 12px;
    border-radius: 8px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    border: 1px solid var(--bd);
}
.bw-yearpick-btn.ghost { background: var(--bg); color: var(--fg); }
.bw-yearpick-btn.ghost:hover { background: var(--bg-hover); }
.bw-yearpick-btn.primary {
    margin-left: auto;
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-fg);
}
.bw-yearpick-btn.primary:hover { background: var(--accent-hover); }

/* Hinweiszeile ueber der Liste, wenn die Auswahl gerade etwas ausblendet. */
.bw-yearnote {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 16px;
    padding: 10px 14px;
    border-radius: 10px;
    border: 1px solid var(--accent);
    background: rgba(206, 158, 60, 0.12);
    font-size: 14px;
}
.bw-yearnote strong { font-variant-numeric: tabular-nums; }
.bw-yearnote a { color: var(--accent-deep); font-weight: 700; margin-left: auto; white-space: nowrap; }

.bw-user-box { display: flex; align-items: center; gap: 14px; }
.bw-user-mail { font-size: 12px; color: rgba(255, 255, 255, 0.7); text-align: right; line-height: 1.3; }
.bw-user-mail strong { color: #ffffff; font-size: 13px; }
.bw-logout {
    padding: 6px 12px;
    font-size: 12px;
    text-decoration: none;
    background: rgba(255, 255, 255, 0.1);
    color: #ffffff;
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 8px;
}
.bw-logout:hover { background: rgba(255, 255, 255, 0.2); }

/* --------------------------------------------------------------------------
   Eingebettet im Modal-iframe (Seite "Gutscheine" oeffnet Ein-/Auschecken
   als Modalfenster): Kopfleiste ausblenden, Innenabstand verkleinern.
   Die Klasse setzt includes/head.php per Inline-Script (window.self !== top).
   -------------------------------------------------------------------------- */
.is-embedded .bw-header { display: none; }
.is-embedded .wrap { padding-top: 16px; }
/* Landet stock.php selbst im Modal-iframe (z. B. denyAccess-Redirect einer
   eingebetteten Seite), keine Aktions-Kacheln zeigen — kein Modal im Modal. */
.is-embedded .voucher-actions { display: none; }

/* --------------------------------------------------------------------------
   Karten, Formulare, Tabellen, Meldungen
   -------------------------------------------------------------------------- */
.card {
    background: var(--card);
    border: 1px solid var(--bd);
    padding: 26px var(--card-pad-x);
    border-radius: 12px;
    box-shadow: var(--shadow-sm);
}
.card-title {
    margin-top: 0;
    border-bottom: 1px solid var(--bd);
    padding-bottom: 15px;
    margin-bottom: 20px;
    font-size: 18px;
}

/* Alarm-Karte (VN 19.08.2026): fuer Warnungen, die sofort auffallen muessen —
   z. B. die Restbestand-Warnung im Eincheck-Fenster. Signalroter Rahmen,
   signalrote Ueberschrift, leicht roter Hintergrund. */
.card-alarm {
    border: 2px solid var(--danger);
    background: #fff5f5;
}
.card-alarm .card-title {
    color: var(--danger);
    border-bottom-color: rgba(194, 0, 23, 0.35);
    font-weight: 700;
}

.form-group { margin-bottom: 20px; }
.form-group label { display: block; margin-bottom: 8px; font-weight: 600; font-size: 14px; color: var(--fg); }
.form-control {
    width: 100%;
    padding: 12px 14px;
    border: 1px solid var(--bd);
    border-radius: 8px;
    font-size: 15px;
    /* Eingetragene Werte fett (VN 28.08.2026), damit das Ausgefuellte sofort
       ins Auge springt; Platzhaltertexte bleiben bewusst normalgewichtig. */
    font-weight: 600;
    font-family: inherit;
    background: #ffffff;
    color: var(--fg);
}
.form-control::placeholder { font-weight: 400; }
.form-control:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.rules { font-size: 12px; color: var(--muted); margin-top: 6px; }

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 10px 18px;
    border-radius: 8px;
    font-size: 14px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    text-decoration: none;
    border: 1px solid var(--bd);
    background: var(--card);
    color: var(--fg);
}
.btn:hover { background: var(--bg-hover); }
.btn.primary { background: var(--accent); color: var(--accent-fg); border-color: var(--accent); }
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); opacity: 1; }
.btn.outline { background: transparent; }
.btn-block { width: 100%; }
.btn-sm { padding: 4px 8px; font-size: 12px; }
.btn-danger { color: var(--danger); border-color: var(--danger); }

.alert { padding: 14px; border-radius: 8px; margin-bottom: 24px; font-weight: 500; font-size: 14px; }
.alert-success { background: #ecfdf5; color: #065f46; border: 1px solid #10b981; }
.alert-danger { background: #fef2f2; color: #b91c1c; border: 1px solid #fca5a5; }
.alert-info { background: #eff6ff; color: #1d4ed8; border: 1px solid #93c5fd; }

table { width: 100%; border-collapse: collapse; margin-top: 20px; }
/* Einheitliches Mass fuer alle Datentabellen (VN 29.08.2026): 13px und
   kompakte Zellabstaende — bisher galt das nur fuer die Gutscheinliste
   (.register-table in stock.php), waehrend Seiten ohne eigene Tabellen-Stile
   (z. B. ebay.php) 15px grosse Zellen zeigten. Die Ueberschriften waren schon
   immer 13px; auffaellig war also allein der zu grosse Zelltext.
   Seiten mit eigenen Tabellenmassen (users/roles.php, setup_audit_log.php)
   sind staerker und bleiben unveraendert. */
th, td { padding: 8px 10px; text-align: left; border-bottom: 1px solid var(--bd); font-size: 13px; }
th { font-weight: 600; color: var(--muted); text-transform: uppercase; }

/* --------------------------------------------------------------------------
   Haftender Tabellenkopf — wiederverwendbarer Standard (VN 29.08.2026)
   Vorbild ist die Gutscheinliste (stock.php): beim Scrollen bleiben die
   Spaltenueberschriften und, falls vorhanden, die Suchfeldzeile am oberen
   Fensterrand stehen. Anwenden mit class="… table-sticky" an der <table>.

   Zwei Voraussetzungen, sonst haftet nichts:
   1. Kein Vorfahre der Tabelle darf `overflow` setzen — der Kopf wuerde sonst
      am Scrollkasten haften statt an der Seite. Ein umschliessendes
      .table-scroll wird darum unten ausdruecklich wieder auf sichtbar
      gestellt.
   2. border-collapse: separate — bei `collapse` gehoeren die Zellraender der
      Tabelle, nicht den Zellen; sie wuerden beim Scrollen zurueckbleiben.
      Optisch aendert sich dadurch nichts, jede Zelle malt ihren Strich selbst.

   --sticky-top ist die Hoehe dessen, was ueber der Tabelle haftet (z. B. eine
   sticky Titelleiste wie auf stock.php). Ohne solche Leiste bleibt es 0.
   -------------------------------------------------------------------------- */
.table-sticky {
    border-collapse: separate;
    border-spacing: 0;
    --sticky-top: 0px;
    --sticky-head-h: 36px;  /* Kopfhoehe: 20px Zeilenhoehe + 2x 8px Polster */
}
.table-scroll:has(> .table-sticky) { overflow: visible; }
.table-sticky th {
    position: sticky;
    top: var(--sticky-top);
    z-index: 3;
    background: var(--card);
    line-height: 20px;  /* fixiert die Kopfhoehe, s. --sticky-head-h */
}
/* Die Suchfeldzeile haftet direkt unter den Ueberschriften. Der 1px-Ueberlapp
   wird vom hoeheren z-index der Kopfzeile verdeckt — kein Sehschlitz. */
.table-sticky tr.filter-cells td {
    position: sticky;
    top: calc(var(--sticky-top) + var(--sticky-head-h));
    z-index: 2;
}
/* Gruppen-Kopfzeilen (tr.group-head, s. u.) sind AUSGENOMMEN: ihr <th colspan>
   wuerde sonst ebenfalls oben haften und die Spaltenueberschriften uebermalen
   (gleicher z-index, spaeter im DOM gewinnt — beobachtet auf ebay.php
   30.08.2026). Sie scrollen mit ihren Datenzeilen mit. */
.table-sticky tr.group-head > th { position: static; }

/* --------------------------------------------------------------------------
   Gruppen-Kopfzeile in Datentabellen (VN 29.08.2026)
   Eine Zeile, die quer ueber alle Spalten eine Gruppe von Datenzeilen
   einleitet — z. B. die Endetage der eBay-Angebote. Aufbau:

     <tbody>
       <tr class="group-head"><th colspan="N"><span class="group-row">
         <span class="group-name">Freitag, 04.09.2026</span>
         <span class="group-meta">in 3 Tagen</span>
         <span class="group-count">4 Angebote</span>
       </span></th></tr>
       … Datenzeilen …
     </tbody>

   Warum <th colspan> und ein <tbody> je Gruppe: Fuer table-ui.js ist eine
   Zeile mit colspan KEINE Datenzeile (kein Zebra, keine Auswahl, bleibt beim
   Sortieren stehen), und sortiert wird innerhalb des Elternelements — die
   Gliederung ueberlebt das Umsortieren also.
   Der Flex-Kasten sitzt im <span>, nicht im <th>: ein <th> mit display:flex
   faellt aus dem Tabellen-Layout und spannt nicht mehr ueber die Breite.
   Die aufklappbare Variante (Jahre der Monatsuebersicht) baut in
   settlement.php auf demselben Muster auf, dort mit einer Schaltflaeche.
   -------------------------------------------------------------------------- */
tr.group-head > th {
    padding: 9px 10px;
    background: var(--bg);
    border-bottom: 1px solid var(--bd);
    color: var(--fg);
    text-transform: none;
    font-size: 14px;
}
tr.group-head .group-row { display: flex; align-items: baseline; gap: 12px; }
tr.group-head .group-name { font-weight: 700; font-size: 15px; font-variant-numeric: tabular-nums; }
tr.group-head .group-meta {
    padding: 1px 8px; border-radius: 999px;
    background: rgba(206, 158, 60, 0.18); color: var(--accent-deep);
    font-size: 12px; font-weight: 600;
}
/* Die Stueckzahl steht rechtsbuendig am Zeilenende — sie ist die eigentliche
   Aussage der Gruppierung ("wie viele enden an diesem Tag?"). */
tr.group-head .group-count { margin-left: auto; color: var(--muted); font-size: 12px; }
/* Tagesgruppen (ebay.php): Die Ueberschrift gehoert optisch zu ihren
   Datenzeilen DARUNTER — deshalb viel Luft nach oben (Abstand zur vorigen
   Gruppe), wenig nach unten (VN 30.08.2026). Erster Wurf war grosses
   padding-top — das malt aber den grauen Kasten mit hoch und die Zeile wirkt
   weiter zentriert. Deshalb jetzt: dicker border-top in KARTENFARBE = echte
   weisse Luecke ueber dem Band (Tabellenzeilen kennen keine Margins, ein
   Rahmen in Hintergrundfarbe ist der klassische Ersatz); das graue Band
   selbst bleibt kompakt und sitzt mit knappem Fuss direkt auf seinen Zeilen.
   Bewusst nur auf tbody.day-group gescoped — die Jahresgruppen der
   Monatsuebersicht (settlement.php) behalten ihre kompakte Zeile. */
tbody.day-group tr.group-head > th {
    border-top: 22px solid var(--card);
    padding: 7px 10px 4px;
    vertical-align: bottom;
}

/* Zeilenfuehrung (UI-Standard VN 26.07.2026; Klassen setzt assets/js/table-ui.js):
   row-alt      = jede zweite SICHTBARE Datenzeile, dezent abgesetzt
   :hover       = Zeile unter dem Mauszeiger
   row-selected = angeklickte Zeile (Lesehilfe, erneuter Klick hebt sie auf)
   Prioritaet: Auswahl schlaegt Hover schlaegt Zebra.
   HELLIGKEITS-REIHENFOLGE (Review 26.07.2026): Karte > Zebra > Hover. Der
   Hover-Ton MUSS dunkler sein als das Zebra — mit --bg-hover (heller als --bg)
   wurde die Zeile unter dem Mauszeiger heller statt dunkler, die Rueckmeldung
   war also auf gestreiften Zeilen verkehrt herum. Deshalb hier ein eigener,
   dunklerer Ton statt --bg-hover.
   Seiteneigene Hover-Regeln (frueher in users/roles.php und
   setup_audit_log.php) wurden entfernt — sie haetten diese Regeln per
   Spezifitaet ausgehebelt und sind durch row-data jetzt ueberfluessig. */
tr.row-alt > td, tr.row-alt > th { background: var(--bg); }
tr.row-data:hover > td, tr.row-data:hover > th { background: #efebe1; }
tr.row-selected > td, tr.row-selected > th { background: #fdf4e2; }
tr.row-selected > :first-child { box-shadow: inset 3px 0 0 var(--accent); }
tr.row-selected:hover > td, tr.row-selected:hover > th { background: #f9edd2; }

/* Spalten-Suchfelder (UI-Standard VN 24.07.2026; erzeugt von
   assets/js/table-ui.js fuer jede Tabelle mit class="filterable"). */
tr.filter-cells td { padding: 4px 6px; border-bottom: 2px solid var(--bd); background: var(--bg); vertical-align: top; }
tr.filter-cells input,
tr.filter-cells select {
    width: 100%;
    min-width: 56px;
    padding: 5px 8px;
    font-size: 12px;
    font-family: inherit;
    border: 1px solid var(--bd);
    border-radius: 6px;
    background: #ffffff;
    color: var(--fg);
}
tr.filter-cells input:focus, tr.filter-cells select:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Anwesenheits-Checkboxen "mit …"/"ohne …" unter dem Suchfeld
   (table-ui.js, <th data-filter-presence>). */
tr.filter-cells label.filter-presence {
    display: flex; align-items: center; gap: 5px;
    margin-top: 4px; font-size: 11px; color: var(--muted);
    white-space: nowrap; cursor: pointer;
}
tr.filter-cells label.filter-presence input { width: auto; min-width: 0; padding: 0; margin: 0; }
/* Aufklapp-Filter in der Filterzeile (table-ui.js): Monats-Kalender
   (data-filter-date) und Auswahl-Checkboxen (data-filter-choices). Das Panel
   haengt absolut unter der Zusammenfassungszeile und schliesst bei Klick
   ausserhalb (JS). */
tr.filter-cells details.filter-pop { position: relative; margin-top: 4px; }
tr.filter-cells details.filter-pop summary {
    list-style: none; cursor: pointer; user-select: none;
    font-size: 11px; color: var(--muted); white-space: nowrap;
}
tr.filter-cells details.filter-pop summary::-webkit-details-marker { display: none; }
tr.filter-cells details.filter-pop summary::after { content: ' ▾'; }
tr.filter-cells details.filter-pop[open] summary::after { content: ' ▴'; }
tr.filter-cells .pop-panel {
    position: absolute; left: 0; top: 100%; z-index: 10;
    min-width: 180px; max-height: 280px; overflow: auto;
    margin-top: 4px; padding: 8px 10px;
    background: #ffffff; border: 1px solid var(--bd); border-radius: 8px;
    box-shadow: 0 8px 20px rgba(43, 49, 54, 0.18);
}
tr.filter-cells .pop-panel label {
    display: flex; align-items: center; gap: 6px;
    padding: 3px 0; font-size: 12px; color: var(--fg);
    white-space: nowrap; cursor: pointer;
}
tr.filter-cells .pop-panel input[type="checkbox"] { width: auto; min-width: 0; padding: 0; margin: 0; }
tr.filter-cells .pop-year { margin: 6px 0 2px; font-size: 11px; font-weight: 700; color: var(--muted); }
tr.filter-cells .pop-months { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; }
tr.filter-cells .pop-month {
    padding: 3px 4px; font-size: 11px; font-family: inherit; cursor: pointer;
    border: 1px solid var(--bd); border-radius: 6px; background: var(--bg); color: var(--fg);
}
tr.filter-cells .pop-month:hover { background: var(--bg-hover); }
tr.filter-cells .pop-clear { width: 100%; font-weight: 600; }
/* Trefferanzeige unter einer gefilterten Tabelle (nur sichtbar beim Filtern). */
.filter-count { margin: 10px 0 0; font-size: 13px; font-weight: 600; color: var(--accent-deep); }
.filter-count[hidden] { display: none; }

/* Sortierbare Spaltenueberschriften (UI-Standard VN 28.07.2026; Verhalten in
   assets/js/table-ui.js, Baustein 4, fuer Tabellen mit class="sortable").
   Der Pfeil zeigt die aktive Sortierspalte und -richtung. Der Platz fuer den
   Pfeil ist auf ALLEN sortierbaren Ueberschriften fest reserviert (unsichtbarer
   Platzhalter) — sonst wuerden beim Wechsel der Sortierspalte alle Spalten
   rechts davon horizontal springen (Review 28.07.2026). */
table.sortable th { cursor: pointer; user-select: none; }
table.sortable th:not([data-nosort])::after { content: ' ▲'; font-size: 10px; visibility: hidden; }
table.sortable th.sort-asc::after { content: ' ▲'; visibility: visible; }
table.sortable th.sort-desc::after { content: ' ▼'; visibility: visible; }
table.sortable th[data-nosort] { cursor: default; }
/* Tastaturfokus sichtbar machen (Sortieren per Enter/Leertaste, table-ui.js). */
table.sortable th:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.cell-strong { font-weight: 500; font-size: 14px; }
.cell-actions { text-align: right; display: flex; justify-content: flex-end; gap: 8px; }

/* Roter Inaktiv-Punkt (VN 24.08.2026): haengt ueberall hinter Hotelname und
   PN-NR, wenn das Hotel bei PERSONIGHTS nicht mehr aktiv ist
   (erp_hotel.is_active = 0; Master dafuer ist der PN-Import,
   includes/hotel_import.php). Gleiche Optik wie der rote "verkauft"-Punkt
   der Gutscheine-Uebersicht (stock.php, .state-dot.sold); Erklaerung im
   title-Tooltip des Punkts. Markup liefert hotelInactiveDot()
   (includes/voucher.php). */
.hotel-inactive-dot {
    display: inline-block; width: 12px; height: 12px; border-radius: 50%;
    background: #dc2626; vertical-align: middle; margin-left: 5px;
}
/* Punkt in Ellipsis-geclippten Zellen (VN 25.08.2026): Flex-Wrapper um
   Name + Punkt — der Name schrumpft mit "…", der Punkt behaelt seinen Platz
   und bleibt immer sichtbar (vorher schnitt das overflow:hidden der Zelle
   ihn bei langen Namen mit ab). Markup liefert hotelNameClipped()
   (includes/voucher.php). Das overflow:hidden am Clip-Span setzt zugleich
   die automatische Flex-Mindestbreite ausser Kraft — ohne das wuerde der
   Name nicht unter seine volle Breite schrumpfen. */
.clip-with-dot { display: flex; align-items: center; }
.clip-with-dot .clip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.clip-with-dot .hotel-inactive-dot { flex: none; }
/* Hotelname als Link auf den Shop-Artikel (VN 30.08.2026, stock.php; Markup
   liefert hotelNameClipped() mit $shopUrl): der klassenlose Link (Hausstil
   Strichelung + ↗) ist selbst Flex-Container, damit der Name weiter mit "…"
   auslaeuft, das ↗-Kennzeichen (a::after) aber NICHT mit abgeschnitten wird —
   als Inline-Anhang hinter dem Clip-Span verschwaende es bei langen Namen.
   min-width: 0 laesst den Link unter seine Inhaltsbreite schrumpfen.
   Als Flex-Item verliert das ::after seine Inline-Sonderrolle (display wird
   blockified): die Strichelung des Ankers liefe UNTER den Pfeil weiter und
   vertical-align wirkt nicht mehr (Review 30.08.2026). Deshalb: Strichelung
   nicht am Anker, sondern am Clip-Span (Werte wie der a-Hausstil oben); der
   Pfeil wird per top-Versatz auf die Inline-Optik angehoben. KEIN
   align-items: baseline — der Clip-Span ist durch overflow: hidden ein
   Scroll-Container, sein Baseline-Ersatz (Boxunterkante) saesse zu tief. */
.clip-with-dot a { display: flex; align-items: center; min-width: 0; text-decoration: none; }
.clip-with-dot a .clip-name {
    text-decoration: underline dashed;
    text-decoration-color: var(--link-underline);
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
    transition: text-decoration-color 0.12s ease;
}
.clip-with-dot a:hover .clip-name { text-decoration-style: solid; text-decoration-color: currentColor; }
.clip-with-dot a::after { flex: none; position: relative; top: -0.1em; }
/* Zahnrad-Link in den Shopware-Admin hinter dem Hotelnamen (VN 30.08.2026,
   stock.php; Markup liefert hotelNameClipped() mit $adminUrl). Bewusst MIT
   Klasse: als Symbol ist er ohnehin als Bedienelement erkennbar und soll
   weder Strichelung noch ↗ tragen (Muster Navigation/Schaltflaechen, siehe
   Kommentar am a:not([class])-Hausstil oben). Das Zeichen kommt als
   ::before-Pseudoelement, damit es — wie der leere Inaktiv-Punkt — nicht in
   textContent auftaucht (table-ui.js sortiert/filtert darueber). */
.clip-with-dot .hotel-admin-link { flex: none; margin-left: 5px; padding: 0 2px; color: var(--muted); }
.clip-with-dot .hotel-admin-link:hover { color: var(--link-hover); }
/* \FE0E = Text-Variationsselektor: erzwingt die einfarbige Textdarstellung
   des Zahnrads (haelt sich an color) statt des bunten Emoji-Glyphs. */
.hotel-admin-link::before { content: '\2699\FE0E'; }

/* Blaetter-Leiste unter grossen Tabellen (VN 25.08.2026): Seitenzahlen als
   Chips in der Optik der uebrigen Bedienelemente (8px-Radius, Kartenrand,
   Gold als Akzent). Die aktuelle Seite ist ein goldener Chip ohne Link,
   links davor die gedaempfte "Seite x von y"-Angabe. */
.pagination { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 14px; }
.pagination-label { font-size: 13px; color: var(--muted); margin-right: 8px; }
.page-chip {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 34px; height: 34px; padding: 0 10px;
    border: 1px solid var(--bd); border-radius: 8px;
    background: var(--card); color: var(--fg);
    font-size: 13px; font-weight: 600; text-decoration: none;
    font-variant-numeric: tabular-nums;
}
a.page-chip:hover { background: var(--bg-hover); border-color: var(--accent); color: var(--accent-deep); }
.page-chip.current { background: var(--accent); border-color: var(--accent); color: var(--accent-fg); }

/* --------------------------------------------------------------------------
   Auth-Seiten (Login, OTP, Passwort vergessen/zuruecksetzen)
   -------------------------------------------------------------------------- */
body.auth-page {
    background: var(--header-bg);
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.login-card {
    width: 100%;
    max-width: 380px;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 16px;
    padding: 36px 32px;
    color: #ffffff;
}
.login-brand {
    text-align: center;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 26px;
}
.login-logo {
    display: block;
    width: 200px;
    max-width: 80%;
    margin: 0 auto 14px;
}
.login-card .form-group label { color: rgba(255, 255, 255, 0.85); }
.login-card .form-control {
    background: rgba(255, 255, 255, 0.95);
    border-color: transparent;
}
.login-card .info { font-size: 14px; color: rgba(255, 255, 255, 0.75); margin-bottom: 20px; }
.login-card .rules { color: rgba(255, 255, 255, 0.6); }
.login-btn {
    display: block;
    width: 100%;
    padding: 12px;
    border: none;
    border-radius: 8px;
    background: var(--accent);
    color: var(--accent-fg);
    font-size: 15px;
    font-weight: 700;
    font-family: inherit;
    cursor: pointer;
    text-align: center;
    text-decoration: none;
    margin-top: 4px;
}
.login-btn:hover { background: var(--accent-hover); }
.forgot-link:hover, .auth-alt-link a:hover { color: var(--accent); }
.error-msg {
    background: rgba(220, 38, 38, 0.18);
    border: 1px solid rgba(248, 113, 113, 0.6);
    color: #fecaca;
    padding: 12px 14px;
    border-radius: 8px;
    font-size: 14px;
    margin-bottom: 20px;
}
.login-card .alert-success { background: rgba(16, 185, 129, 0.15); color: #a7f3d0; border-color: rgba(16, 185, 129, 0.5); }
.login-card .alert-danger { background: rgba(220, 38, 38, 0.18); color: #fecaca; border-color: rgba(248, 113, 113, 0.6); }
.forgot-link {
    display: block;
    text-align: center;
    margin-top: 20px;
    color: rgba(255, 255, 255, 0.7);
    font-size: 13px;
    text-decoration: none;
}
.forgot-link:hover { color: #ffffff; }
.auth-alt-link { text-align: center; margin-top: 20px; }
.auth-alt-link a { color: rgba(255, 255, 255, 0.7); font-size: 13px; text-decoration: none; }
.otp-code { text-align: center; font-size: 22px; letter-spacing: 0.35em; font-family: 'Courier New', Courier, monospace; }

/* --------------------------------------------------------------------------
   Nach-oben-Pfeil (VN 19.08.2026)
   Bei langen Listen (Gutscheinliste, Abrechnung, Befunde) blendet sich unten
   rechts ein runder Pfeil ein, sobald weiter als 400 px gescrollt wurde; ein
   Klick rollt die Seite weich zum Anfang. Angebaut wird er zentral von
   assets/js/table-ui.js, gilt also auf allen Seiten.
   -------------------------------------------------------------------------- */
.bw-to-top {
    position: fixed;
    right: 24px;
    bottom: 24px;
    z-index: 90;               /* unter der Kopfleiste (100), ueber dem Inhalt */
    width: 46px;
    height: 46px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 50%;
    background: var(--header-bg);
    color: var(--accent);
    cursor: pointer;
    box-shadow: 0 3px 12px rgba(43, 49, 54, 0.3);
    /* Ausgeblendet startet der Knopf unsichtbar UND unklickbar. */
    opacity: 0;
    visibility: hidden;
    transform: translateY(10px);
    transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
}
.bw-to-top svg { width: 22px; height: 22px; display: block; }
.bw-to-top.is-visible { opacity: 0.92; visibility: visible; transform: none; }
.bw-to-top:hover { opacity: 1; background: #3a4147; }
.bw-to-top:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Bei offenem Modalfenster (dialog) stoert der Pfeil unter dem Backdrop nur. */
body:has(dialog[open]) .bw-to-top { display: none; }
@media print { .bw-to-top { display: none; } }

/* --------------------------------------------------------------------------
   Responsive Kleinigkeiten
   -------------------------------------------------------------------------- */
@media (max-width: 720px) {
    /* Auf schmalen Geraeten waeren 51px Einrueckung links UND rechts zu viel —
       die Fluchtlinie rueckt naeher an den Rand, bleibt aber eine Linie. */
    :root { --gutter: 12px; --card-pad-x: 16px; }
    .bw-header-inner { flex-direction: column; align-items: flex-start; gap: 10px; }
    .bw-user-box { width: 100%; justify-content: space-between; }
    .cell-actions { flex-direction: column; align-items: flex-end; }
}
