/* ============================================================
   Einheiten-Policy: rem fuer Typografie/Abstaende/Groessen (skaliert mit der
   Root-Schriftgroesse - respektiert Browser-Zoom/OS-Textgroesse, UND gibt
   uns einen einzigen zentralen Hebel, die App z.B. fuer das Rezeptions-
   Display groesser zu skalieren, siehe html { font-size: ... }). px NUR
   fuer Faelle, in denen rem keinen Vorteil bringt bzw. echte Pixel-Praezision
   zaehlt:
   - Media-Query-Breakpoints (768px, 767.98px, 1199.98px - Konvention,
     unabhaengig von Text-Skalierung)
   - Border-/Outline-Breiten (inkl. der Border-Dreieck-Technik beim
     Zeiger-Pfeil) - Haarlinien-Schaerfe, kein sinnvoller Skalierungs-Nutzen
   - box-shadow-Werte (Tiefen-Effekt, nicht text-relativ)
   - Scrollbar-Pseudo-Elemente (::-webkit-scrollbar & Co. - eher
     Browser-Chrome als Typografie) sowie der 999px-"Pille"-Trick fuer
     border-radius (beliebig gross gewaehlt, keine echte Groessenangabe)
   - transform-Mikro-Nudges (z.B. der 1px-Hover-Lift) - bewusste
     Pixel-Praezision fuer einen kaum wahrnehmbaren Effekt
   - SVG-interne Werte (Kartenansicht: eigenes viewBox-Koordinatensystem,
     nicht an die Root-Schriftgroesse der Seite gekoppelt)
   letter-spacing bleibt bewusst bei em (nicht rem): em ist hier relativ zur
   Schriftgroesse des jeweiligen Elements SELBST richtig - skaliert die Uhr
   im Icon-only-Modus (kleinere font-size) automatisch mit, rem bliebe
   dagegen immer an der Root-Groesse haengen.
   ============================================================ */
:root {
    /* ============================================================
       MARKEN-FARBEN - die ECHTEN Werte kommen aus Administration >
       Anzeige-Einstellungen (App\Support\Brand): dort generiert die App
       einen :root-Block, der vor templates/custom/custom.css ausgeliefert
       wird und diese Defaults ueberschreibt. Die Werte hier sind nur der
       Fallback, falls das nicht greift.
       ============================================================ */
    --wcp-brand-primary: #4f46e5;   /* Haupt-Akzent: aktiver Navi-Punkt, Buttons, Links */
    --wcp-brand-secondary: #ec4899; /* Zweit-Akzent: Uhr-Verlauf, Hover-Töne */
    /* Das Sidebar-Logo (WebCeption-Marke) haengt bewusst NICHT an diesen
       Variablen - siehe Kommentar bei .wcp-sidebar__logo .wcp-logo-icon
       weiter unten und sidebar.twig. */

    --wcp-sidebar-width: 15rem;      /* 240px */
    --wcp-sidebar-width-icons: 4.75rem; /* 76px */
    --wcp-sidebar-width-mobile: 16.25rem; /* 260px - Offcanvas auf dem Handy, damit 4 runde Buttons nebeneinander passen */

    /* Fliegende Buttons auf dem Handy (.wcp-mfab: Menue, Schnellaktionen, Neue Buchung)
       und der "+" der Kartenansicht: EINE Groesse fuer alle - hier zum Ausprobieren
       aendern (mindestens 2.75rem = 44px fuer gute Treffsicherheit). --wcp-fab-gap =
       Abstand zum Bildschirmrand. */
    --wcp-fab-size: 3.5rem; /* 56px */
    --wcp-fab-gap: 1rem;
    --wcp-sidebar-bg: #262c3d;
    --wcp-sidebar-bg-darker: #1e2331;
    --wcp-sidebar-fg: #e7ebf3;
    --wcp-sidebar-fg-muted: #9aa5b8;
    --wcp-accent: var(--wcp-brand-primary);

    --wcp-ampel-grau: #9aa0a8;
    --wcp-ampel-gruen: #2eb872;
    --wcp-ampel-rot: #e5484d;

    /* Hellgelbe "heute"-Markierung - eine gemeinsame Quelle fuer Kalender
       (ueberschreibt FullCalendars eigene --fc-today-bg-color, siehe unten)
       UND Timeline (.wcp-tl-today-marker), damit beide Ansichten exakt
       denselben Farbton verwenden. */
    --wcp-today-bg-color: rgba(255, 220, 40, .15);

    /* Bootstraps eigene "primary"-Farbe (Buttons, Links, Fokus-Ringe, Checkboxen
       usw. app-weit) auf denselben Marken-Akzent ziehen, statt Bootstraps
       Standardblau. --bs-primary-rgb kann CSS nicht automatisch aus dem Hex-Wert
       berechnen - bei Aenderung von --wcp-brand-primary bitte manuell mitziehen. */
    --bs-primary: var(--wcp-brand-primary);
    --bs-primary-rgb: 79, 70, 229;
    --bs-link-color: var(--wcp-brand-primary);
    --bs-link-color-rgb: 79, 70, 229;
    --bs-link-hover-color: var(--wcp-brand-secondary);
}

/* ============================================================
   Globale Ebenen (z-index) - eine Uebersicht an EINER Stelle, statt vieler
   verstreuter Einzelwerte, damit neue Ueberlagerungen sich sauber
   einordnen lassen statt Zufallswerte zu raten. Bootstrap 5.3 legt seine
   eigene Skala als CSS-Variablen auf :root ab (--bs-zindex-*), unsere
   eigenen Ebenen bauen bewusst DARUM HERUM statt sie zu ueberschreiben:

     (auto) .wcp-content        - normale Content-Flaeche, bewusst OHNE
                                   eigenen z-index (siehe Kommentar dort -
                                   ein Flex-Item MIT z-index wuerde einen
                                   Stacking-Context erzeugen und darin
                                   verschachtelte position:fixed-Elemente
                                   wie .wcp-fab einsperren)
        20  .wcp-sidebar         - nur ab Tablet-Breite (sticky, kein
                                   Offcanvas mehr); auf Mobile UNGESETZT,
                                   siehe Kommentar dort
      1030  .wcp-fab             - fliegender "+"-Button (Kartenansicht, nur ab Tablet)
      1030  .wcp-mfab            - fliegende Handy-Buttons (Menue, Schnellaktionen, Neue Buchung)
      1040  --bs-zindex-offcanvas-backdrop (Bootstrap, unveraendert)
      1045  --bs-zindex-offcanvas (Bootstrap, unveraendert - das ist
                                   .wcp-sidebar auf Mobile)
      1050  --bs-zindex-modal-backdrop (Bootstrap, unveraendert)
      1055  --bs-zindex-modal    (Bootstrap, unveraendert) - alle
                                   "Basis"-Modals (Login/Buchung/Raum-Modal/
                                   Administration-Formulare)
      1070  .wcp-modal-stacked-backdrop - Backdrop von Bestaetigungs-Dialogen
                                   (Loeschen/Dangerzone), die IMMER aus einem
                                   bereits offenen Basis-Modal heraus
                                   geoeffnet werden - Bootstrap selbst kennt
                                   keine gestapelten Modals (alle .modal/
                                   .modal-backdrop teilen denselben
                                   z-index), siehe app.js
      1075  .wcp-modal-stacked   - dito, das Bestaetigungs-Modal selbst
      1070  --bs-zindex-popover, 1080 --bs-zindex-tooltip (Bootstrap,
                                   unveraendert - liegen ohnehin ueber allem)
      2000  .wcp-splash          - Ladebildschirm, deckt initial wirklich
                                   alles ab
      2100  .wcp-devtools        - nicht verlinkte Dev-Werkzeuge (siehe
                                   assets/js/dev-tools.js), bewusst ueber
                                   allem inkl. Splash, da per Hash-Route
                                   (#generate_password/#generate_bigseed)
                                   jederzeit unabhaengig vom Ladezustand
                                   aufrufbar
   ============================================================ */

html, body {
    height: 100%;
}

body {
    background: #f4f6fa;
    /* App-Gefuehl auf dem Handy: kein Pull-to-Refresh/Gummiband-Scrollen
       des Browsers (v.a. in installierter Vollbild-App stoerend). */
    overscroll-behavior-y: none;
}

.wcp-app {
    display: flex;
    min-height: 100vh;
    /* dvh = tatsaechlich sichtbare Hoehe, wenn Browser-Leisten ein-/ausfahren */
    min-height: 100dvh;
}

/* Bootstraps Primary-Buttons/-Switches tragen ihre Farbe fest (#0d6efd) und
   folgen --bs-primary NICHT von selbst - hier auf die Marken-Farbe gezogen,
   damit die Admin-Einstellung (Primary) auch die Buttons erreicht. */
.btn-primary {
    --bs-btn-bg: var(--wcp-brand-primary);
    --bs-btn-border-color: var(--wcp-brand-primary);
    --bs-btn-hover-bg: color-mix(in srgb, var(--wcp-brand-primary) 88%, #000);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--wcp-brand-primary) 82%, #000);
    --bs-btn-active-bg: color-mix(in srgb, var(--wcp-brand-primary) 80%, #000);
    --bs-btn-active-border-color: color-mix(in srgb, var(--wcp-brand-primary) 75%, #000);
    --bs-btn-disabled-bg: var(--wcp-brand-primary);
    --bs-btn-disabled-border-color: var(--wcp-brand-primary);
    --bs-btn-focus-shadow-rgb: var(--bs-primary-rgb);
}

.btn-outline-primary {
    --bs-btn-color: var(--wcp-brand-primary);
    --bs-btn-border-color: var(--wcp-brand-primary);
    --bs-btn-hover-bg: var(--wcp-brand-primary);
    --bs-btn-hover-border-color: var(--wcp-brand-primary);
    --bs-btn-active-bg: var(--wcp-brand-primary);
    --bs-btn-active-border-color: var(--wcp-brand-primary);
    --bs-btn-disabled-color: var(--wcp-brand-primary);
    --bs-btn-disabled-border-color: var(--wcp-brand-primary);
    --bs-btn-focus-shadow-rgb: var(--bs-primary-rgb);
}

.form-check-input:checked {
    background-color: var(--wcp-brand-primary);
    border-color: var(--wcp-brand-primary);
}

@media (min-width: 768px) {
    /* Ab Tablet-Breite ("auf Displays"): die App ist eine fixe, nie selbst
       scrollende Buehne (wie schon die Sidebar per position:sticky+100vh
       weiter unten) - Scrollen passiert NUR noch innerhalb der einen Card
       jeder Ansicht (siehe .wcp-content-Regeln weiter unten). Auf Mobile
       bleibt bewusst normales Seiten-Scrollen (das Offcanvas-Burgermenue
       macht die feste Buehne dort unpraktikabel, der Platz ist ohnehin knapp). */
    .wcp-app {
        height: 100vh;
        overflow: hidden;
    }
}

/* --- Sidebar / Navigation ---
   Deutliche Trennung von Navi und Contentbereich (angelehnt an Shopware 6
   Admin): Schatten am rechten Rand statt nur Farbkontrast. */
.wcp-sidebar {
    width: var(--wcp-sidebar-width);
    flex: 0 0 auto;
    background: var(--wcp-sidebar-bg);
    color: var(--wcp-sidebar-fg);
    display: flex;
    flex-direction: column;
    box-shadow: 3px 0 16px rgba(0, 0, 0, .4);
    transition: width .15s ease;
    /* KEIN eigener z-index hier auf allen Breiten - .wcp-sidebar IST
       gleichzeitig Bootstraps eigenes .offcanvas-Element (siehe
       "offcanvas-md offcanvas-start" in sidebar.twig). Ein pauschaler
       eigener z-index wuerde auch auf Mobile greifen und dort Bootstraps
       eigenen, viel hoeheren Offcanvas-z-index (--bs-zindex-offcanvas:
       1045) ueberschreiben - das Offcanvas-Backdrop (1040, unveraendert)
       laege dann VOR der ausgeklappten Navigation statt dahinter ("bg fade
       liegt ueber allem"). Ab Tablet-Breite (kein Offcanvas mehr, siehe
       .wcp-sidebar-Regel im Media-Query direkt darunter) bekommt sie einen
       eigenen, aber bewusst niedrigen z-index - siehe "Globale Ebenen
       (z-index)" oben am Dateianfang. */
}

/* WICHTIG: ohne eigene, vom Content unabhaengige Hoehe wuerde die Sidebar
   wegen align-items:stretch (Standard in .wcp-app) auf die Hoehe des
   Content-Bereichs mitwachsen (der z.B. bei einer langen Timeline/Doku-Seite
   deutlich hoeher als der Viewport werden kann) - dadurch war .wcp-sidebar__fixed
   nicht am Viewport-Rand "fixiert", sondern irgendwo am Ende dieser
   ueberlangen Sidebar. position:sticky + eigene Hoehe loest das: die Sidebar
   bleibt exakt Viewport-hoch und bleibt beim Scrollen der Seite oben kleben.
   NUR ab Tablet-Breite (wie beim Collapse-Toggle) - auf Mobile ist die
   Sidebar ohnehin schon per Bootstrap-Offcanvas position:fixed. */
@media (min-width: 768px) {
    .wcp-sidebar {
        position: sticky;
        top: 0;
        height: 100vh;
        z-index: 20;
    }
}

.wcp-sidebar__logo {
    display: flex;
    align-items: center;
    gap: .65rem;
    padding: 1rem 1.25rem;
    font-weight: 700;
    font-size: 1.05rem;
    color: #fff;
    border-bottom: 1px solid rgba(255, 255, 255, .08);
    white-space: nowrap;
    overflow: hidden;
}

/* Logo-Icon: echtes <img> (asset('img/logo-sidebar.svg'), siehe sidebar.twig) statt
   Inline-SVG, damit ein individuelles Logo per Datei-Tausch unter
   templates/custom/assets/img/ funktioniert (App\Support\AssetResolver) - die
   mitgelieferte Datei hat bewusst fest codierte Marken-Farben, unabhaengig
   von App-Farbthemes in custom.css. Hier nur Layout. */
.wcp-sidebar__logo .wcp-logo-icon {
    flex: 0 0 auto;
    display: block;
}

.wcp-sidebar__body {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: .5rem 0 1rem;
}

/* Gemeinsamer Stil fuer die drei runden Icon-Buttons unten in der Sidebar
   (Login, Ein-/Ausklapp-Pfeil, Sprachwechsel - siehe .wcp-sidebar__toolrow):
   bewusst unauffaellig (transparent, gedeckte Farbe, dezenter Hover), kein
   Text mehr daneben - die Bedeutung vermittelt allein das Icon + title-
   Tooltip. */
.wcp-circle-btn {
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 30000px;
    background: transparent;
    color: var(--wcp-sidebar-fg-muted);
    transition: color .15s ease, background-color .15s ease;
}

.wcp-circle-btn i {
    font-size: 1.25rem;
    /* Nur fuer den Pfeil genutzt (rotate(180deg) beim Ein-/Ausklappen, siehe
       .wcp-sidebar-toggle i weiter unten) - hier zentral definiert, damit
       ein einzelnes bi-chevron-left-Icon smooth zwischen "<" und ">" dreht
       statt (wie frueher per JS-Klassenwechsel) hart zu springen. */
    transition: transform .25s ease;
}

.wcp-circle-btn:hover {
    color: #fff;
    background: rgba(255, 255, 255, .05);
}

.wcp-lang-switch {
    display: flex;
}

.wcp-nav {
    flex: 1;
}

.wcp-nav-link {
    color: var(--wcp-sidebar-fg-muted);
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .65rem 1.25rem;
    border-left: 3px solid transparent;
    font-size: .95rem;
}

.wcp-nav-link i {
    font-size: 1.15rem;
    width: 1.4rem;
    text-align: center;
}

/* Jeder Navi-Punkt (inkl. Administration im festen unteren Bereich) bekommt
   eine eigene Icon-Farbe statt einheitlichem Grau - macht die Navi lebendiger
   und Punkte auf einen Blick unterscheidbar. Bleibt auch im aktiven/Hover-
   Zustand erhalten (nur Hintergrund/Textfarbe der Zeile aendern sich). */
.wcp-nav-link[data-target="calendar"] i { color: var(--wcp-brand-primary); }
.wcp-nav-link[data-target="timeline"] i { color: #0ea5e9; }
.wcp-nav-link[data-target="map"] i { color: #14b8a6; }
.wcp-nav-link[data-target="raeume"] i { color: #f59e0b; }
.wcp-nav-link[data-target="konflikte"] i { color: #ef4444; }
.wcp-nav-link[data-target="doku"] i { color: #a78bfa; }
.wcp-nav-link[data-target="admin"] i { color: var(--wcp-brand-secondary); }

.wcp-nav-link:hover {
    color: #fff;
    background: rgba(255, 255, 255, .05);
}

.wcp-nav-link.active {
    color: #fff;
    background: color-mix(in srgb, var(--wcp-accent) 18%, transparent);
    border-left-color: var(--wcp-accent);
}

/* --- Fester unterer Sidebar-Bereich (Shopware-6-artig): Administration,
   Uhr, Ein-/Ausklapp-Toggle - bleibt beim Scrollen der Navi-Liste oben
   sichtbar, da er ausserhalb von .offcanvas-body liegt (siehe sidebar.twig). */
.wcp-sidebar__fixed {
    flex: 0 0 auto;
    background: var(--wcp-sidebar-bg-darker);
    border-top: 1px solid rgba(255, 255, 255, .08);
}

.wcp-sidebar__admin-link {
    border-bottom: 1px solid rgba(255, 255, 255, .08);
}

.wcp-sidebar__clock {
    padding: .9rem 1.25rem;
    color: var(--wcp-sidebar-fg-muted);
    font-variant-numeric: tabular-nums;
}

.wcp-clock-time {
    font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 1.4rem;
    font-weight: 600;
    letter-spacing: .02em;
    background: linear-gradient(135deg, var(--wcp-brand-primary), var(--wcp-brand-secondary));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.wcp-clock-date {
    font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .72rem;
    letter-spacing: .05em;
    text-transform: uppercase;
    margin-top: .15rem;
}

/* Toolrow ganz unten: Sprachwechsel - Login - Pfeil. Bewusst KEIN Grid mehr
   (das brach im eingeklappten Zustand: 3 Spalten je 1fr in der schmalen
   Icon-Breite der Sidebar zwangen die Buttons in Spalten, die schmaler als
   ihr eigener Durchmesser sind, wodurch der letzte Button rechts aus der
   sichtbaren Leiste rausragte) - stattdessen absolute Positionierung per
   Prozent-"left" + transform:translate(-50%,-50%) zum Zentrieren. Prozente
   beziehen sich auf die tatsaechliche Breite DIESES Containers, rechnen sich
   also bei jeder Sidebar-Breite (voll/eingeklappt) automatisch neu - kein
   Ueberlauf moeglich, weil absolut positionierte Kinder die Breite des
   Containers nicht mehr mitbestimmen. */
.wcp-sidebar__toolrow {
    position: relative;
    height: 2.75rem;
    margin: .4rem .5rem .75rem;
    transition: height .25s ease;
}

.wcp-sidebar__toolrow .wcp-lang-switch,
.wcp-sidebar__toolrow .wcp-auth-btn,
.wcp-sidebar__toolrow .wcp-carousel-btn,
.wcp-sidebar__toolrow .wcp-gate-btn,
.wcp-sidebar__toolrow .wcp-admin-btn,
.wcp-sidebar__toolrow .wcp-sidebar-toggle {
    position: absolute;
    top: 50%;
    transform: translate(-50%, -50%);
    transition: left .25s ease, top .25s ease, opacity .2s ease;
}

.wcp-sidebar__toolrow .wcp-lang-switch {
    left: 16.6667%;
}

.wcp-sidebar__toolrow .wcp-auth-btn {
    left: 50%;
}

/* Der Pfeil bleibt im ausgeklappten Zustand aussen rechts (letztes Drittel).
   z-index sorgt dafuer, dass er Sprachwechsel/Login im eingeklappten
   Zustand sichtbar ueberlagert, sobald alle drei auf denselben Punkt
   zusammenlaufen (siehe die beiden Kollaps-Bloecke weiter unten). */
.wcp-sidebar__toolrow .wcp-sidebar-toggle {
    left: 83.3333%;
    z-index: 1;
}

/* Kiosk-Zugang: vier statt drei Buttons (Sprache, Abmelden, Karussell, Pfeil) -
   jeder exakt mittig in seinem Viertel. Eingeklappt gelten dieselben
   Kollaps-Regeln wie bei drei Buttons (alles laeuft unter den Pfeil). */
.wcp-sidebar__toolrow--four .wcp-lang-switch { left: 12.5%; }
.wcp-sidebar__toolrow--four .wcp-auth-btn { left: 37.5%; }
.wcp-sidebar__toolrow--four .wcp-carousel-btn,
.wcp-sidebar__toolrow--four .wcp-admin-btn,
.wcp-sidebar__toolrow--four .wcp-gate-btn { left: 62.5%; }
.wcp-sidebar__toolrow--four .wcp-sidebar-toggle { left: 87.5%; }

/* Karussell eingeschaltet: Marken-Farbe als klares An-Signal. */
.wcp-sidebar__toolrow .wcp-circle-btn.is-active {
    background: var(--wcp-brand-primary);
    color: #fff;
}

.wcp-sidebar__toolrow .wcp-circle-btn.is-active:hover {
    background: color-mix(in srgb, var(--wcp-brand-primary) 85%, #000);
}

/* Tablet / mittlere Breiten: standardmaessig nur Icons - ausser der manuelle
   Toggle hat "ausgeklappt" erzwungen (.wcp-sidebar--force-expanded). */
@media (min-width: 768px) and (max-width: 1199.98px) {
    .wcp-sidebar:not(.wcp-sidebar--force-expanded) {
        width: var(--wcp-sidebar-width-icons);
    }

    .wcp-sidebar:not(.wcp-sidebar--force-expanded) .wcp-nav-label,
    .wcp-sidebar:not(.wcp-sidebar--force-expanded) .wcp-logo-label {
        display: none;
    }

    .wcp-sidebar:not(.wcp-sidebar--force-expanded) .wcp-nav-link {
        justify-content: center;
        padding: .75rem .25rem;
    }

    /* Eingeklappt laufen alle drei Buttons auf denselben Punkt (Mitte der
       schmalen Leiste) zusammen und liegen dort uebereinander - der Pfeil
       bleibt dank z-index sichtbar obenauf ("sammelt die anderen ein"),
       Sprachwechsel/Login blenden zusaetzlich aus. So bleibt der Pfeil
       exakt wie frueher (Einzelbutton ueber die volle Breite) schoen mittig
       in der Leiste, egal wie schmal sie ist. */
    .wcp-sidebar:not(.wcp-sidebar--force-expanded) .wcp-sidebar__toolrow .wcp-lang-switch,
    .wcp-sidebar:not(.wcp-sidebar--force-expanded) .wcp-sidebar__toolrow .wcp-auth-btn,
    .wcp-sidebar:not(.wcp-sidebar--force-expanded) .wcp-sidebar__toolrow .wcp-carousel-btn,
    .wcp-sidebar:not(.wcp-sidebar--force-expanded) .wcp-sidebar__toolrow .wcp-gate-btn {
        left: 50%;
        opacity: 0;
        pointer-events: none;
    }

    .wcp-sidebar:not(.wcp-sidebar--force-expanded) .wcp-sidebar__toolrow .wcp-sidebar-toggle {
        left: 50%;
    }

    /* Pfeil-Icon dreht sich smooth zwischen "<" und ">" statt (wie frueher)
       hart per JS die Icon-Klasse zu tauschen - siehe .wcp-sidebar-toggle i
       weiter unten fuer die Basis-transition. */
    .wcp-sidebar:not(.wcp-sidebar--force-expanded) .wcp-sidebar-toggle i {
        transform: rotate(180deg);
    }

    /* Datum/Uhrzeit im Icon-Modus kompakt anzeigen */
    .wcp-sidebar:not(.wcp-sidebar--force-expanded) .wcp-sidebar__clock {
        text-align: center;
        padding: .75rem .25rem .25rem;
    }

    .wcp-sidebar:not(.wcp-sidebar--force-expanded) .wcp-clock-date {
        display: none;
    }

    .wcp-sidebar:not(.wcp-sidebar--force-expanded) .wcp-clock-time {
        font-size: .85rem;
    }
}

/* Manueller Ein-/Ausklapp-Toggle (wie Shopware 6 Admin): erzwingt Icon-only
   unabhaengig von der Fensterbreite, auch auf Desktop-Breiten. Zustand wird
   in app.js per localStorage gemerkt. */
.wcp-sidebar--force-collapsed {
    width: var(--wcp-sidebar-width-icons) !important;
}

.wcp-sidebar--force-collapsed .wcp-nav-label,
.wcp-sidebar--force-collapsed .wcp-logo-label {
    display: none;
}

.wcp-sidebar--force-collapsed .wcp-nav-link {
    justify-content: center;
    padding: .75rem .25rem;
}

.wcp-sidebar--force-collapsed .wcp-sidebar__toolrow .wcp-lang-switch,
.wcp-sidebar--force-collapsed .wcp-sidebar__toolrow .wcp-auth-btn,
.wcp-sidebar--force-collapsed .wcp-sidebar__toolrow .wcp-carousel-btn,
.wcp-sidebar--force-collapsed .wcp-sidebar__toolrow .wcp-gate-btn {
    left: 50%;
    opacity: 0;
    pointer-events: none;
}

.wcp-sidebar--force-collapsed .wcp-sidebar__toolrow .wcp-sidebar-toggle {
    left: 50%;
}

.wcp-sidebar--force-collapsed .wcp-sidebar-toggle i {
    transform: rotate(180deg);
}

.wcp-sidebar--force-collapsed .wcp-sidebar__clock {
    text-align: center;
    padding: .75rem .25rem .25rem;
}

.wcp-sidebar--force-collapsed .wcp-clock-date {
    font-size: .5rem; /* 8px */
}

.wcp-sidebar--force-collapsed .wcp-clock-time {
    font-size: .85rem;
}

/* Mobile: Sidebar wird zum Offcanvas (siehe offcanvas-md Klasse im Template).
   .wcp-sidebar__fixed liegt als Geschwister-Element NACH .offcanvas-body
   (das Bootstrap selbst scrollbar macht) - bleibt dadurch automatisch auch
   im ausgeklappten mobilen Layer unten fixiert, keine zusaetzliche Anpassung
   noetig. */
/* Fliegende Handy-Buttons (siehe layout.twig): die Bedienung sitzt unten, oben ist die
   grosse Flaeche fuer die Inhalte. Groesse/Abstand ueber --wcp-fab-size/--wcp-fab-gap
   (oben bei :root). Links das Menue (Pille), Mitte Schnellaktionen, rechts Neue Buchung.
   Ab Tablet-Breite gibt es sie nicht (dort bleibt die feste Sidebar). */
.wcp-mfab {
    position: fixed;
    bottom: calc(var(--wcp-fab-gap) + env(safe-area-inset-bottom, 0px));
    z-index: 1030; /* siehe "Globale Ebenen (z-index)" - unter dem Offcanvas-Backdrop (1040) */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: var(--wcp-fab-size);
    min-width: var(--wcp-fab-size);
    padding: 0;
    border: 0;
    border-radius: 30000px;
    font-size: calc(var(--wcp-fab-size) * .43);
    line-height: 1;
    box-shadow: 0 4px 14px rgba(0, 0, 0, .28);
    transition: transform .15s ease, box-shadow .15s ease;
}

.wcp-mfab:active {
    transform: scale(.94);
}

.btn.wcp-mfab {
    --bs-btn-color: #fff;
    --bs-btn-hover-color: #fff;
    --bs-btn-active-color: #fff;
    --bs-btn-border-color: transparent;
    --bs-btn-hover-border-color: transparent;
    --bs-btn-active-border-color: transparent;
}

.btn.wcp-mfab--menu {
    --bs-btn-bg: var(--wcp-sidebar-bg);
    --bs-btn-hover-bg: var(--wcp-sidebar-bg);
    --bs-btn-active-bg: var(--wcp-sidebar-bg);
    left: var(--wcp-fab-gap);
    width: var(--wcp-fab-size);
    background: var(--wcp-sidebar-bg);
    color: #fff;
}

.btn.wcp-mfab--quick {
    --bs-btn-bg: #fff;
    --bs-btn-hover-bg: #fff;
    --bs-btn-active-bg: #fff;
    --bs-btn-color: var(--wcp-brand-primary);
    --bs-btn-hover-color: var(--wcp-brand-primary);
    --bs-btn-active-color: var(--wcp-brand-primary);
    left: calc(50% - var(--wcp-fab-size) / 2);
    width: var(--wcp-fab-size);
    background: #fff;
    color: var(--wcp-brand-primary);
    box-shadow: 0 4px 14px rgba(0, 0, 0, .22), 0 0 0 1px rgba(0, 0, 0, .06);
}

.btn.wcp-mfab--add {
    right: var(--wcp-fab-gap);
    width: var(--wcp-fab-size);
    background: linear-gradient(135deg, var(--wcp-brand-primary), var(--wcp-brand-secondary));
    color: #fff;
}

.btn.wcp-mfab--menu:hover,
.btn.wcp-mfab--menu:active,
.btn.wcp-mfab--add:hover,
.btn.wcp-mfab--add:active {
    color: #fff;
}

.btn.wcp-mfab--quick:hover,
.btn.wcp-mfab--quick:active {
    background: #fff;
    color: var(--wcp-brand-primary);
}

@media (min-width: 768px) {
    .wcp-mfab {
        display: none;
    }
}

/* --- Content ---
   Grund-Styling-Entscheidung: jede Ansicht (views/*.twig) hat GENAU einen
   Wurzel-Div, darin GENAU eine Card - das ist die verbindliche Grundstruktur
   fuer alle (Kalender/Timeline/Karte/Raeume/Konflikte/Administration; die
   Administration packt ihre mehreren Bereiche als Reiter EINER Card, siehe
   admin.twig). Ab Tablet-Breite bekommt diese eine Card die volle verfuegbare
   Hoehe und scrollt bei zu viel Inhalt NUR noch in ihrem eigenen card-body -
   die Seite/das Layout drumherum scrollt nie mit (siehe .wcp-app oben).
   min-height:0 ist an jeder Stelle dieser Flex-Kette noetig, sonst verhindert
   Flexbox' Default (min-height:auto) das Schrumpfen unter die Inhaltsgroesse
   und der Overflow "leckt" nach oben durch, statt lokal zu scrollen. */
.wcp-content {
    flex: 1;
    min-width: 0;
    padding: 1.5rem;
    background: #f4f6fa;
    /* KEIN eigener z-index/position hier (siehe "Globale Ebenen (z-index)"
       oben am Dateianfang): .wcp-content ist ein Flex-Item von .wcp-app -
       ein Flex-Item mit z-index != auto erzeugt per Spec einen eigenen
       Stacking-Context, auch OHNE position. Das wuerde jedes position:fixed-
       Element darin (z.B. .wcp-fab in der Kartenansicht) auf die lokale
       Ebene "1" einsperren, egal welchen z-index es selbst traegt - der
       Vergleich mit Geschwistern wie .wcp-sidebar (Ebene 20) faende dann
       schon EINE Ebene hoeher statt. Genau das fuehrte zu dem Bug, dass der
       fliegende Button zeitweise unsichtbar/verdeckt war. */
}

@media (min-width: 768px) {
    .wcp-content {
        height: 100vh;
        display: flex;
        flex-direction: column;
        /* Fallback fuer Seiten OHNE die Card-Struktur (freie content/*.twig-
           Seiten wie Doku/WLAN, die bewusst NICHT dieser Grundregel folgen,
           siehe Kommentar oben an .wcp-content) - normales Scrollen der
           gesamten Flaeche, damit z.B. eine lange Doku-Seite ueberhaupt
           erreichbar bleibt. Views MIT Card ueberschreiben das gleich
           darunter auf "nicht selbst scrollend". */
        overflow: auto;
    }

    /* :has() grenzt die "Buehne scrollt nie, nur die Card scrollt"-Regel
       gezielt auf Ansichten mit der verbindlichen Card-Struktur ein - ohne
       das wuerde z.B. die kartenlose Doku-Seite durch overflow:hidden
       ploetzlich unerreichbar. */
    .wcp-content:has(> div > .card) {
        overflow: hidden;
    }

    .wcp-content > div:has(> .card) {
        flex: 1;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }

    .wcp-content > div > .card {
        flex: 1;
        min-height: 0;
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }

    .wcp-content > div > .card > .card-body {
        flex: 1;
        min-height: 0;
        overflow: auto;
    }
}

@media (max-width: 767.98px) {
    /* Handy: Kopfzeile (Toolbar) steht wie am Desktop OBEN in der Card, darunter die
       Inhalte; die Bedienung (Menue/Schnellaktionen/Neue Buchung) liegt als fliegende
       Buttons unten (.wcp-mfab) - deshalb unten genug Platz, damit nichts verdeckt wird. */
    .wcp-content {
        padding:
            calc(1rem + env(safe-area-inset-top, 0px))
            calc(1rem + env(safe-area-inset-right, 0px))
            calc(var(--wcp-fab-size) + var(--wcp-fab-gap) * 2 + env(safe-area-inset-bottom, 0px))
            calc(1rem + env(safe-area-inset-left, 0px));
    }
}

/* --- Einheitliche Kopfzeilen-Toolbar ---
   EIN gemeinsames, flaches Klassen-Set fuer alle Card-Header mit Steuer-
   elementen statt pro Ansicht eigener Utility-Klassen/Groessen (Kalender/
   Timeline/Karte/Räume/Konflikte + die Admin-Subnavi) - siehe jeweilige
   *.twig. Struktur immer: .card-header.wcp-view-toolbar > .wcp-toolbar-start
   (Buttons/Titel, links) + optional .wcp-toolbar-end (rechts, z.B.
   "+"-Button). Custom content/*.twig-Seiten (Doku/WLAN) sind bewusst
   aussen vor. */
.wcp-view-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    flex-wrap: wrap;
}

.wcp-toolbar-start,
.wcp-toolbar-end {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
}

/* Reine Titel-Header ohne echte Buttons (Räume/Konflikte, nur ein <span>):
   bekommt DIESELBE vertikale Polsterung wie ein .btn in dieser Toolbar
   (siehe .wcp-view-toolbar .btn weiter unten, gleiche Media-Query-Werte),
   damit seine Zeilenhoehe dem eines echten Buttons pixelgenau entspricht -
   card-header selbst hat ueberall dieselbe Polsterung, der Unterschied
   entstand also rein durch die zusaetzliche Eigen-Polsterung/den Rahmen
   eines .btn gegenueber reinem Text. Ein vorheriger Versuch darueber ein
   pauschales min-height auf .wcp-view-toolbar zu legen, griff nicht: das
   min-height bezieht sich auf die Toolbar selbst (inkl. card-header-
   Polsterung), waehrend ein Button-Header seine Hoehe zusaetzlich ÜBER die
   eigene Button-Polsterung INNERHALB dieser bereits gepolsterten Toolbar
   aufbaut - ein Button-Header wurde dadurch trotzdem hoeher. */
.wcp-toolbar-title {
    display: inline-flex;
    align-items: center;
    padding: .25rem 0;
    border: 1px solid transparent;
    line-height: 1.5;
    font-size: .875rem;
}

@media (min-width: 768px) {
    .wcp-toolbar-title {
        padding: .375rem 0;
        font-size: 1rem;
    }
}

/* Etwas Luft zwischen Icon und Text in fetten Headline-Titeln (Räume,
   Konflikte, Admin-Standort-Header...) - sonst klebt das Bootstrap-Icon
   direkt am Text, weil dazwischen nur ein einzelnes Leerzeichen im Markup
   steht. Absichtlich an :first-child statt an jedes <i> in .fw-semibold,
   falls irgendwo noch ein zweites/anderes Icon danach folgt (z.B. Badges). */
.fw-semibold > i:first-child {
    margin-right: .4rem;
}

/* Groesse der Steuerelemente folgt EINER Skala statt verstreuter
   .btn-sm-Klassen: auf Mobile einheitlich kompakt (bisher .btn-sm bei
   Kalender/Timeline) - greift auch auf Buttons OHNE eigene .btn-sm-Klasse
   (z.B. die per JS gerenderten Standort-Buttons der Kartenansicht, siehe
   map.js) sowie auf die Admin-Subnavi-Reiter (.nav-link), die von Haus aus
   groesser sind. */
@media (max-width: 767.98px) {
    .wcp-view-toolbar .btn {
        --bs-btn-padding-y: .25rem;
        --bs-btn-padding-x: .5rem;
        --bs-btn-font-size: .875rem;
    }

    .wcp-view-toolbar .nav-link {
        padding: .25rem .5rem;
        font-size: .875rem;
    }
}

/* Ab Tablet-Breite: einheitlich die groessere "Admin"-Groesse (Bootstraps
   Standard-Buttongroesse) - hebt ein vorhandenes .btn-sm wieder an, damit
   nicht mehr pro View einzeln zwischen .btn/.btn-sm entschieden werden muss. */
@media (min-width: 768px) {
    .wcp-view-toolbar .btn {
        --bs-btn-padding-y: .375rem;
        --bs-btn-padding-x: .75rem;
        --bs-btn-font-size: 1rem;
    }
}

/* --- Ansicht-Umschalter im Kalender (Böppel <-> Balken) ---
   Ein Icon-Button im Stil der uebrigen Toolbar-Buttons. Das Icon ist
   diagonal (von oben rechts nach unten links) geteilt: links oben die
   Böppel, rechts unten die Balken. Die AKTIVE Haelfte steht in der
   Marken-Farbe, die inaktive ist ausgegraut (data-mode am Button, siehe
   calendar.js). */
.wcp-viewmode-btn {
    --bs-btn-hover-bg: #f1f3f5;
    --bs-btn-hover-border-color: #6c757d;
    --bs-btn-hover-color: inherit;
    --bs-btn-active-bg: #e9ecef;
    --bs-btn-active-border-color: #6c757d;
    --bs-btn-active-color: inherit;
}

.wcp-viewmode-btn svg {
    display: inline-block;
    width: 1.5em;
    height: 1.5em;
    vertical-align: -.4em;
}

.wcp-viewmode-btn .vm-chips,
.wcp-viewmode-btn .vm-bars {
    color: #adb5bd;
    transition: color .15s ease;
}

.wcp-viewmode-btn[data-mode="chips"] .vm-chips,
.wcp-viewmode-btn[data-mode="bars"] .vm-bars {
    color: var(--wcp-brand-primary);
}

/* --- Ampel-Böppel (Raum-Status) ---
   5 Zustaende, rein ueber data-color + CSS gestylt:
   - gruen        : heute UND morgen frei
   - rot          : heute UND morgen belegt
   - grau         : heute (admin-)blockiert / nicht buchbar
   - rot-gruen    : heute noch belegt, ab morgen frei (Checkout morgen)
   - gruen-rot    : heute noch frei, ab morgen belegt (Check-in morgen)
   Die beiden Uebergangs-Zustaende werden als weicher Gradient dargestellt. */
.wcp-ampel {
    display: inline-block;
    width: .85rem;
    height: .85rem;
    /* IMMER ein Kreis: in Flex-Zeilen (z.B. schmale Timeline-Namensspalte) darf
       der Boeppel weder schrumpfen noch sich strecken - sonst wird er zur Ellipse. */
    flex: 0 0 auto;
    min-width: .85rem;
    min-height: .85rem;
    aspect-ratio: 1 / 1;
    box-sizing: border-box;
    border-radius: 50%;
    background: var(--wcp-ampel-grau);
    vertical-align: middle;
    cursor: help;
}

.wcp-ampel[data-color="gruen"] { background: var(--wcp-ampel-gruen); }
.wcp-ampel[data-color="rot"] { background: var(--wcp-ampel-rot); }
.wcp-ampel[data-color="grau"] { background: var(--wcp-ampel-grau); }

.wcp-ampel[data-color="rot-gruen"] {
    background: linear-gradient(135deg,
        var(--wcp-ampel-rot) 0%, var(--wcp-ampel-rot) 45%,
        var(--wcp-ampel-gruen) 55%, var(--wcp-ampel-gruen) 100%);
}

.wcp-ampel[data-color="gruen-rot"] {
    background: linear-gradient(135deg,
        var(--wcp-ampel-gruen) 0%, var(--wcp-ampel-gruen) 45%,
        var(--wcp-ampel-rot) 55%, var(--wcp-ampel-rot) 100%);
}

/* --- Administration: sortierbare Spalten + Name-Klick-Bearbeiten --- */
.wcp-raum-name-cell {
    cursor: pointer;
}

.wcp-raum-name-cell:hover {
    text-decoration: underline;
}

.wcp-sortable-table .wcp-sort-th {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}

.wcp-sortable-table .wcp-sort-th:hover {
    color: var(--wcp-accent);
}

.wcp-sort-icon {
    font-size: .65rem;
}

/* --- Öffentliche Räume-Übersicht --- */
.wcp-raeume-row {
    cursor: pointer;
}

/* --- Raum-Modal --- */
.wcp-room-photo {
    max-height: 13.75rem; /* 220px */
    max-width: 100%;
    border-radius: .5rem;
    object-fit: cover;
}

.wcp-booking-list {
    max-height: 16.25rem; /* 260px */
    overflow-y: auto;
    overflow-x: hidden;
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    gap: .5rem;
    /* Unten etwas Luft fuer die Pfeilspitze des aktiven Badges (siehe
       .wcp-booking-badge--active::after) - sonst wirkt sie am unteren Rand
       der scrollbaren Liste abgeschnitten/gequetscht. */
    padding: 0 .25rem .625rem 0;
}

.wcp-booking-badge {
    position: relative;
    cursor: pointer;
    font-size: .85rem;
    padding: .5rem .75rem;
    color: #fff;
    border: 2px solid transparent;
    transition: transform .1s ease, border-color .15s ease, opacity .15s ease;
}

/* Ohne Login: reine Anzeige, nicht anklickbar */
.wcp-booking-badge--static {
    cursor: default;
}

/* Sobald IRGENDEIN Badge aktiv ist, alle anderen dezent zuruecknehmen -
   macht die Auswahl auch bei vielen/mehrzeiligen Badges auf den ersten
   Blick eindeutig. Klasse sitzt auf .wcp-booking-list selbst (statt jedes
   Badge einzeln zu pruefen), siehe renderBookingBadges() in room-modal.js. */
.wcp-booking-list--has-active .wcp-booking-badge:not(.wcp-booking-badge--active) {
    opacity: .45;
}

/* Aktuell im Detailformular darunter angezeigte Buchung - der kleine Zeiger
   (::after) haengt direkt an DIESEM Badge (nicht mehr an einem gemeinsamen
   Element unterhalb der ganzen Liste, siehe Doku-Kommentar hier: bei
   mehrzeiligen Badges - z.B. mobil schon ab 2 Buchungen - liess sich eine
   einzelne, nur X-positionierte Zeiger-Spitze nicht mehr eindeutig einer
   Zeile zuordnen. Als ::after des jeweiligen Badges braucht es dafuer auch
   keinerlei JS-Positionsberechnung/getBoundingClientRect() mehr - der
   Browser haengt es automatisch an die richtige Stelle, in jeder Zeile). */
.wcp-booking-badge--active {
    border-color: #1b2331;
    transform: translateY(-1px);
    opacity: 1;
}

.wcp-booking-badge--active::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: -.625rem; /* 10px */
    transform: translateX(-50%);
    width: 0;
    height: 0;
    border-left: .5rem solid transparent;
    border-right: .5rem solid transparent;
    border-top: .5rem solid var(--wcp-badge-color, #1b2331);
    pointer-events: none;
}

.wcp-booking-badge__icon {
    margin-right: .3rem;
}

/* Detailformular-Container: braucht position:relative als Bezugsrahmen fuer
   den fliegenden Bearbeiten-Button (siehe .wcp-detail-edit-fab). */
.wcp-booking-detail {
    position: relative;
}

.wcp-detail-edit-fab {
    position: absolute;
    top: .5rem;
    right: .5rem;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: .35rem;
}

/* ?-Symbol neben einem Feldnamen: Erklaerung als Tooltip statt Hilfetext unter dem Feld */
.wcp-help-icon {
    cursor: help;
}

/* --- Konflikte-Uebersicht --- */
.wcp-konflikt-room,
.wcp-konflikt-booking {
    cursor: pointer;
}

/* --- Kalenderansicht: Tages-Böppel pro Raum --- */
.wcp-cal-chip {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Groesse per Variable, damit der Kalender-Zoom (.wcp-cal--compact) sie zentral verkleinern kann */
    width: var(--wcp-cal-chip-size, 1.5rem);
    height: var(--wcp-cal-chip-size, 1.5rem);
    border-radius: 50%;
    color: #fff;
    font-size: var(--wcp-cal-chip-font, .65rem);
    font-weight: 700;
    margin: .1rem;
    cursor: pointer;
}

/* Komplett abgeschlossene Buchung (end_date in der Vergangenheit, siehe
   calendar.js/timeline.js) - optisch zurueckgenommen, aber weiterhin normal
   anklickbar (oeffnet die Bearbeiten-Maske, siehe eventClick()/room-modal.js). */
.wcp-cal-chip--past {
    opacity: .4;
}

/* Ueberschneidung mit einer anderen Buchung im selben Raum (siehe "Konflikte") */
.wcp-cal-chip--conflict {
    box-shadow: 0 0 0 2px #fff, 0 0 0 3.5px #dc3545;
}

.wcp-cal-chip--conflict::after {
    content: "!";
    position: absolute;
    top: -.25rem; /* -4px */
    right: -.25rem; /* -4px */
    width: .75rem; /* 12px */
    height: .75rem; /* 12px */
    border-radius: 50%;
    background: #dc3545;
    color: #fff;
    font-size: .5625rem; /* 9px */
    font-weight: 700;
    line-height: .75rem; /* 12px */
    text-align: center;
}

/* Halber Böppel am Checkin-/Checkout-Tag einer mehrtaegigen Buchung (ohne
   Kuerzel-Text - zu klein dafuer): Checkin = linke Haelfte gefuellt,
   Checkout = rechte Haelfte gefuellt. FullCalendar rendert den Chip in einem
   Flex-Container (.fc-daygrid-dot-event, volle Zellbreite) - Checkout bleibt
   dadurch von selbst linksbuendig (Standard-Flex-Ausrichtung), Checkin wird
   per margin-left:auto zusaetzlich an den rechten Zellenrand geschoben. */
.wcp-cal-chip--half {
    background: transparent;
}

.wcp-cal-chip--checkin {
    margin-left: auto;
}

.wcp-cal-chip--half::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: var(--wcp-chip-color, #9aa0a8);
}

.wcp-cal-chip--checkin::before {
    clip-path: inset(0 50% 0 0);
}

.wcp-cal-chip--checkout::before {
    clip-path: inset(0 0 0 50%);
}

/* Zusammengefuehrtes Checkout+Checkin-Paar desselben Raums am selben Tag
   (siehe calendar.js, mergeCheckoutCheckinPairs()): beide Haelften stehen in
   EINER Zeile nebeneinander und beruehren sich mit ihren RUNDEN Seiten
   (Spitze an Spitze, wie eine liegende Sanduhr): links Checkout (rechte
   Halbscheibe, flache Kante aussen links), rechts Checkin (linke
   Halbscheibe, flache Kante aussen rechts) - dieselbe Reihenfolge wie bei den
   Einzel-Halbboeppeln (Checkout links, Checkin rechts). Jede Haelfte hat nur
   die halbe Boxbreite (.75rem), der Kreis dahinter (::before, volle Breite)
   wird per clip-path auf die jeweils sichtbare Haelfte beschnitten und bei
   Checkout um eine halbe Breite nach links versetzt - so bleibt auch die
   Hover-/Klickflaeche genau die sichtbare Halbscheibe. */
.wcp-cal-chip-pair {
    --wcp-cal-chip-half: calc(var(--wcp-cal-chip-size, 1.5rem) / 2);
    display: flex;
    width: var(--wcp-cal-chip-size, 1.5rem);
    height: var(--wcp-cal-chip-size, 1.5rem);
    margin: .1rem auto;
}

.wcp-cal-chip-pair .wcp-cal-chip {
    position: relative;
    flex: none;
    width: var(--wcp-cal-chip-half);
    height: var(--wcp-cal-chip-size, 1.5rem);
    margin: 0;
}

.wcp-cal-chip-pair .wcp-cal-chip--checkout {
    border-radius: 0 var(--wcp-cal-chip-half) var(--wcp-cal-chip-half) 0; /* Halbscheibe: runde Seite rechts (fuer den Konflikt-Rahmen) */
}

.wcp-cal-chip-pair .wcp-cal-chip--checkin {
    border-radius: var(--wcp-cal-chip-half) 0 0 var(--wcp-cal-chip-half); /* runde Seite links */
}

.wcp-cal-chip-pair .wcp-cal-chip::before {
    inset: auto;
    top: 0;
    left: 0;
    width: var(--wcp-cal-chip-size, 1.5rem);
    height: 100%;
}

.wcp-cal-chip-pair .wcp-cal-chip--checkout::before {
    left: calc(var(--wcp-cal-chip-half) * -1);
}

/* Böppel-Modus (.wcp-cal--chips, siehe calendar.js): die Böppel eines Tages fliessen
   nebeneinander und brechen bei Bedarf um, statt dass jeder eine eigene Zeile belegt - bei
   vielen Raeumen bleiben die Tageszellen so klein. Welcher Böppel zu welcher Buchung gehoert,
   zeigt das Ueberfahren (Tooltip + Markierung des Zeitraums). Bewusst Flex statt float:right:
   die Reihenfolge (nach Raumkuerzel, eventOrder) bleibt links->rechts lesbar.
   FullCalendar setzt pro Event einen Abstand nach oben (margin-top als Inline-Style), um
   gleiche "Ebenen" ueber die Woche auszurichten - nebeneinander ergibt das keinen Sinn, daher
   !important. Gilt nicht im Balken-Modus, der braucht FullCalendars Zeilen-Layout. */
.wcp-cal--chips #wcpCalendar .fc-daygrid-day-events {
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
}

.wcp-cal--chips #wcpCalendar .fc-daygrid-event-harness {
    margin-top: 0 !important;
}

.wcp-cal--chips #wcpCalendar .fc-daygrid-day-bottom {
    margin-top: 0 !important;
}

.wcp-cal--chips #wcpCalendar .fc-daygrid-dot-event {
    padding: 0;
}

/* Test-Modus "Balken" (siehe calendar.js, barMode): dezente Variante der
   past-/conflict-Zustaende auf FullCalendars eigenem Standard-Balken statt
   des eigenen Chip-Markups. */
.wcp-cal-bar--past {
    opacity: .5;
}

.wcp-cal-bar--conflict {
    box-shadow: inset 0 0 0 2px #dc3545;
}

/* Hover auf einen Böppel markiert den gesamten zusammenhaengenden
   Buchungszeitraum im sichtbaren Kalender (siehe highlightBookingRange()
   in calendar.js) - Farbe kommt vom jeweiligen Raum. */
.wcp-cal-day--highlight {
    background: color-mix(in srgb, var(--wcp-highlight-color, var(--wcp-brand-primary)) 18%, transparent);
}

/* --- Kalenderansicht: "+"-Button pro Tageszelle (neue Buchung) --- */
.wcp-cal-add-btn {
    position: absolute;
    bottom: .125rem; /* 2px */
    right: .125rem; /* 2px */
    width: 1.3rem;
    height: 1.3rem;
    padding: 0;
    line-height: 1;
    font-size: .65rem;
    border: 1px solid #dde2ea;
    border-radius: .3rem;
    background: #fff;
    color: #9aa4b6;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    z-index: 2;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}

.wcp-cal-add-btn:hover {
    background: var(--wcp-accent);
    border-color: var(--wcp-accent);
    color: #fff;
}

/* --- Modal-Header: Speichern-Icon vor dem Schliessen-Kreuz (siehe
   new_booking_modal.twig, room_modal.twig, admin.twig) - einheitlich in
   allen Modals mit Formular verfuegbar. */
.wcp-modal-save-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border-radius: .375rem;
}

/* Bestaetigungs-Dialoge (Loeschen-Bestaetigung, Dangerzone), die IMMER aus
   einem bereits offenen Basis-Modal heraus geoeffnet werden koennen (z.B.
   Buchung-Loeschen aus dem Raum-Modal) - Bootstrap kennt von Haus aus keine
   gestapelten Modals (alle .modal/.modal-backdrop teilen denselben
   z-index), deshalb hier eine explizite Ebene hoeher. Siehe "Globale Ebenen
   (z-index)" oben am Dateianfang; das Backdrop bekommt seine Klasse per JS
   zugewiesen (siehe elevateStackedModal() in app.js), weil Bootstrap dessen
   DOM-Element selbst erzeugt und keine eigene ID/Klasse dafuer anbietet. */
#wcpConfirmModal,
#wcpDangerConfirmModal {
    z-index: 1075;
}

.wcp-modal-stacked-backdrop {
    z-index: 1070;
}

/* --- Tabellen-Timeline ---
   Bewusst KEIN position:sticky fuer die Raumnamen-Spalte (siehe Kommentar
   in timeline.twig) - stattdessen zwei physisch getrennte Bereiche: ein
   fixer, nicht scrollender Namensblock links + ein horizontal scrollender
   Tages-Raster rechts. Beide bekommen pro Zeile exakt dieselbe Hoehe
   (--wcp-tl-row-h), dadurch bleiben sie ohne jeden JS-Sync exakt aufeinander
   ausgerichtet. */
:root {
    --wcp-tl-name-col: 11.25rem; /* 180px */
    --wcp-tl-day-col: 3.5rem; /* 56px */
    --wcp-tl-row-h: 2.75rem; /* 44px */
}

.wcp-tl-outer {
    display: flex;
    align-items: flex-start;
}

.wcp-tl-names {
    flex: 0 0 var(--wcp-tl-name-col);
    width: var(--wcp-tl-name-col);
    border-right: 2px solid #dde2ea;
}

.wcp-tl-wrap {
    flex: 1;
    min-width: 0;
    overflow-x: auto;
    overflow-y: hidden;
}

.wcp-tl-grid {
    display: grid;
    grid-template-columns: repeat(var(--wcp-tl-days, 1), var(--wcp-tl-day-col));
    grid-auto-rows: var(--wcp-tl-row-h);
}

.wcp-tl-cell {
    height: var(--wcp-tl-row-h);
    border-bottom: 1px solid #edf0f5;
    border-right: 1px solid #edf0f5;
    display: flex;
    align-items: center;
    padding: 0 .4rem;
    font-size: .78rem;
    color: #6c7688;
    box-sizing: border-box;
}

.wcp-tl-header {
    background: #fff;
    font-weight: 600;
    justify-content: center;
    text-align: center;
    flex-direction: column;
    line-height: 1.1;
}

.wcp-tl-room {
    background: #fff;
    cursor: pointer;
    gap: .4rem;
    font-size: .85rem;
    color: #1b2331;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Raumname-Text - font-size bewusst auf 1rem angehoben (statt der von
   .wcp-tl-room geerbten .85rem): soll ueberall dort, wo ein Raumname
   auftaucht (Räume-Übersicht, Administration, hier), GLEICH aussehen - der
   jeweils groesste der drei Werte gewinnt. Normale Schriftfarbe/-staerke
   (nicht mehr in Raumfarbe eingefaerbt/fett) - die Raumfarbe steckt jetzt im
   Kürzel-Böppel davor (.wcp-tl-room-chip), Text soll konsistent bleiben. */
.wcp-tl-room-name {
    font-size: 1rem;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Kuerzel-Böppel im selben Look wie die Kalender-Belegungsböppel
   (.wcp-cal-chip, siehe app.css/calendar.js) - immer sichtbar, VOR dem Namen
   (einheitlicher Aufbau wie Räume-Übersicht/Administration: Böppel + Name +
   (Standort) + Ampel). Auf Mobile bleibt NUR er stehen, siehe Media-Query
   unten (.wcp-tl-room-name wird dort ausgeblendet). */
.wcp-tl-room-chip {
    flex-shrink: 0;
}

.wcp-tl-corner {
    background: #fff;
    border-right: none;
}

@media (max-width: 767.98px) {
    :root {
        /* Schmale Namensspalte auf Mobile: nur noch Kuerzel-Böppel + Ampel
           statt vollem Raumnamen (siehe .wcp-tl-room-name/.wcp-tl-room-chip
           oben) - der gesamte mobile Aufbau wird schrittweise ueberarbeitet,
           das hier ist der erste Schritt fuer die Timeline. */
        --wcp-tl-name-col: 3.75rem; /* 60px */
    }

    .wcp-tl-room {
        justify-content: center;
        padding: 0 .2rem;
    }

    .wcp-tl-room-name {
        display: none;
    }
}

/* Senkrechte Linie je Tag ueber alle Raumzeilen (siehe render() in timeline.js) - bewusst keine
   waagerechten Linien je Raum im Raster, die Zeilen sind ueber die Namensspalte gut erkennbar. */
.wcp-tl-daycol {
    border-right: 1px solid #edf0f5;
    pointer-events: none;
}

.wcp-tl-bar {
    align-self: center;
    margin: 0 .125rem; /* 2px */
    height: 1.625rem; /* 26px */
    border-radius: 13px; /* bewusst px, kein rem-Vielfaches: fester, von der
                             Textgroesse unabhaengiger Zielwert (= halbe
                             Balkenhoehe, also ein echtes Pillenform-Rund) */
    background: var(--wcp-accent);
    color: #fff;
    font-size: .72rem;
    display: flex;
    align-items: center;
    padding: 0 .4rem;
    overflow: hidden;
    white-space: nowrap;
    cursor: pointer;
}

.wcp-tl-bar.wcp-tl-bar--blocked {
    background: var(--wcp-ampel-grau);
}

/* Komplett abgeschlossene Buchung (end_date in der Vergangenheit, siehe
   timeline.js) - optisch zurueckgenommen, aber weiterhin normal anklickbar
   (oeffnet die Bearbeiten-Maske, siehe room-modal.js). */
.wcp-tl-bar.wcp-tl-bar--past {
    opacity: .4;
}

/* Ueberschneidung mit einer anderen Buchung im selben Raum (siehe "Konflikte"):
   roter Rahmen + halbe Zeilenhoehe, oben/unten gestapelt (Spur 0/1, siehe
   timeline.js laneAssignment()) - so bleiben beide ueberschneidenden Balken
   sichtbar statt sich gegenseitig zu verdecken. */
.wcp-tl-bar.wcp-tl-bar--conflict {
    outline: 2px solid #dc3545;
    align-self: stretch;
}

.wcp-tl-bar--conflict.wcp-tl-bar--lane0 {
    align-self: start;
}

.wcp-tl-bar--conflict.wcp-tl-bar--lane1 {
    align-self: end;
}

/* Markierung der heutigen Spalte ueber alle Raumzeilen (inkl. Kopfzeile)
   hinweg - dieselbe hellgelbe Farbe wie im Kalender (--wcp-today-bg-color),
   damit beide Ansichten "aus einem Guss" wirken. */
.wcp-tl-today-marker {
    background: var(--wcp-today-bg-color);
    pointer-events: none;
}

/* FullCalendars eingebaute Toolbar ist deaktiviert (headerToolbar: false in
   calendar.js) - die Kopfzeile in calendar.twig ist stattdessen 1:1 wie die
   Timeline aus echten Bootstrap-Buttons aufgebaut (gleiche Klassen), braucht
   also keine eigenen Overrides mehr. Denselben hellgelben "heute"-Ton wie in
   der Timeline verwenden (statt FullCalendars eigenem Default). */
.fc {
    --fc-today-bg-color: var(--wcp-today-bg-color);
}

/* --- SVG-Kartenansicht (siehe public/assets/js/views/map.js) ---
   Die SVG des Standorts wird inline eingebettet; Elemente mit passendem Raum
   bekommen die Klasse .wcp-map-room (Faerbung nach Ampel setzt map.js als
   Inline-Style). Kuerzel-Boeppel/Namen (.wcp-map-label) liegen als oberste Ebene
   in der SVG, Hover-Info im schwebenden .wcp-map-tip. */
.wcp-map-wrap {
    width: 100%;
    overflow: auto;
}

.wcp-map-wrap > svg {
    display: block;
    width: 100%;
    height: auto;
    max-height: 75vh;
    margin: 0 auto;
}

.wcp-map-room {
    cursor: pointer;
    outline: none;
}

.wcp-map-room path,
.wcp-map-room rect,
.wcp-map-room polygon,
.wcp-map-room polyline,
.wcp-map-room circle,
.wcp-map-room ellipse,
path.wcp-map-room,
rect.wcp-map-room,
polygon.wcp-map-room,
polyline.wcp-map-room,
circle.wcp-map-room,
ellipse.wcp-map-room {
    transition: opacity .15s ease, filter .15s ease;
}

.wcp-map-room:hover,
.wcp-map-room:focus-visible {
    opacity: .88;
    filter: brightness(1.08);
}

.wcp-map-label__name {
    fill: #fff;
    font-weight: 600;
    stroke: rgba(0, 0, 0, .55);
    paint-order: stroke;
    stroke-linejoin: round;
}

.wcp-map-tip {
    position: fixed;
    z-index: 1080;
    max-width: 18rem;
    padding: .45rem .7rem;
    border-radius: .5rem;
    background: rgba(20, 22, 38, .94);
    color: #fff;
    font-size: .8rem;
    line-height: 1.35;
    pointer-events: none;
    box-shadow: 0 .5rem 1.5rem rgba(0, 0, 0, .35);
}

.wcp-map-tip__booking {
    margin-top: .25rem;
    padding-top: .25rem;
    border-top: 1px solid rgba(255, 255, 255, .2);
    color: #ffd84d;
}

.wcp-placeholder-view {
    background: #fff;
    border: 1px dashed #d7dce5;
    border-radius: .75rem;
    padding: 3rem 1.5rem;
    text-align: center;
    color: #6c7688;
}

/* Fliegender runder "+"-Button unten rechts (aktuell nur Kartenansicht) -
   gleicher Farbverlauf wie Logo/Uhr, damit er als Marken-Akzent erkennbar
   bleibt statt als generischer Bootstrap-Button. position: fixed statt
   absolute, damit er beim Scrollen der Kartenansicht sichtbar bleibt;
   z-index unter Bootstraps Modal-Backdrop (>=1050), damit er von Modals
   ueberdeckt wird statt darueber zu schweben (siehe "Globale Ebenen
   (z-index)" oben am Dateianfang). Liegt als Kind von .wcp-content im DOM -
   funktioniert nur korrekt, WEIL .wcp-content selbst keinen eigenen
   z-index/Stacking-Context mehr hat (sonst waere dieser Wert hier wirkungslos
   eingesperrt, siehe Kommentar an .wcp-content). */
.wcp-fab {
    position: fixed;
    right: 1.5rem;
    bottom: 1.5rem;
    width: var(--wcp-fab-size);
    height: var(--wcp-fab-size);
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--wcp-brand-primary), var(--wcp-brand-secondary));
    color: #fff;
    font-size: 1.5rem;
    box-shadow: 0 4px 14px rgba(0, 0, 0, .25);
    z-index: 1030;
    transition: transform .15s ease, box-shadow .15s ease;
}

.wcp-fab:hover {
    color: #fff;
    transform: scale(1.06);
    box-shadow: 0 6px 18px rgba(0, 0, 0, .3);
}

.wcp-fab:active {
    transform: scale(.96);
}

/* --- Scrollbars: schlank, app-artig, moeglichst plattform-/browser-
   einheitlich. Firefox nutzt die standardisierten scrollbar-*-Properties,
   WebKit/Blink (Chrome/Edge/Safari) nur die praefixierten ::-webkit-scrollbar-
   Pseudo-Elemente - es braucht beide, es gibt (Stand 2026) keine einzelne
   Eigenschaft, die auf allen Browsern gleich funktioniert. */
* {
    scrollbar-width: thin;
    scrollbar-color: #c1c7d0 transparent;
}

::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    background-color: #c1c7d0;
    border-radius: 999px;
    border: 2px solid transparent;
    background-clip: padding-box;
}

::-webkit-scrollbar-thumb:hover {
    background-color: #9aa3b1;
}

/* --- Splashscreen (siehe layout.twig) ---
   Typische App-Splash-Optik: sehr helles Grau, grosses zentriertes Logo,
   darunter ein kleiner, dezenter "Powered by"-Hinweis in dunklerem Grau -
   NICHT das Marken-Indigo/Pink fuer den Text, nur das kleine Icon bleibt
   farbig. Blendet per JS (layout.twig) kurz nach dem Laden aus. */
.wcp-splash {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.75rem;
    background: #f7f7f9;
    transition: opacity .4s ease;
}

.wcp-splash--hidden {
    opacity: 0;
    pointer-events: none;
}

/* Hoehe statt fester Quadrat-Box: ein individuelles Logo muss nicht quadratisch
   sein (z.B. Hochformat mit Schriftzug). Standard-Logo ist quadratisch, sieht
   also unveraendert aus (148px). Eigene Hoehe in custom.css per
   --wcp-splash-logo-height; die Breite folgt dem Seitenverhaeltnis der SVG. */
.wcp-splash__logo {
    height: min(var(--wcp-splash-logo-height, 9.25rem), 55vh); /* Standard 148px */
    width: auto;
    max-width: 85vw;
}

.wcp-splash__powered {
    display: flex;
    align-items: center;
    gap: .5rem;
    color: #6c7280;
    font-size: .8rem;
    font-weight: 600;
    letter-spacing: .01em;
}

.wcp-splash__powered img {
    width: 1.125rem; /* 18px */
    height: 1.125rem; /* 18px */
    flex-shrink: 0;
}

/* --- Site-Gate-Login (siehe gate_login.twig/App\Auth\SiteGate) ---
   Bewusst dieselbe Optik wie der Splashscreen oben - beide sind die
   "Basis-Identitaet" der Plattform, das Splash ist quasi diese Seite MINUS
   Formular. Login ist aber die komplette eigenstaendige Seite (nicht wie
   .wcp-splash ein Overlay ueber der ladenden App dahinter) - deshalb
   min-height statt position:fixed+inset. Die Powered-by-Zeile bleibt
   .wcp-splash__powered (1:1 wiederverwendet), nur die Positionierung
   (fix nahe der unteren Browserkante statt Teil der zentrierten Gruppe)
   kommt vom umschliessenden .wcp-gatepage__powered hier. */
.wcp-gatepage {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.75rem;
    background: #f7f7f9;
    padding: 2rem 1rem;
}

.wcp-gatepage__logo {
    /* wie .wcp-splash__logo (gleiche Variable), aber hoehenbegrenzt, damit das
       Formular darunter auch bei grossem Hochformat-Logo noch Platz hat */
    height: min(var(--wcp-splash-logo-height, 9.25rem), 36vh);
    width: auto;
    max-width: 85vw;
}

.wcp-gatepage__form {
    width: 100%;
    max-width: 20rem;
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}

/* Bewusst kein Bootstrap .form-control - "nur eine Unterlinie" statt der
   sonst app-weiten Input-Box, fuer die typische minimalistische
   Basis-Login-Optik. */
.wcp-gate-input {
    width: 100%;
    border: 0;
    border-bottom: 1px solid #d7dce5;
    border-radius: 0;
    background: transparent;
    padding: .5rem .25rem;
    font-size: 1rem;
    color: #1b2331;
    transition: border-color .15s ease;
}

.wcp-gate-input:focus {
    outline: none;
    box-shadow: none;
    border-bottom-color: var(--wcp-brand-primary);
}

.wcp-gate-input::placeholder {
    color: #9aa4b6;
}

.wcp-gate-forgot {
    display: block;
    text-align: right;
    margin-top: -.4rem;
    font-size: .78rem;
    color: #6c7688;
    text-decoration: none;
}

.wcp-gate-forgot:hover {
    color: var(--wcp-brand-primary);
    text-decoration: underline;
}

.wcp-gate-error {
    font-size: .85rem;
    color: #dc3545;
}

.wcp-gate-submit {
    width: 100%;
}

.wcp-gatepage__powered {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 1.25rem;
    display: flex;
    justify-content: center;
}

/* --- Dunkle Variante von Splashscreen + Gate-Login ---
   Rein optional, per Klasse auf <body> (gesetzt in layout.twig/gate_login.twig
   aus der Einstellung "Dunkles Theme", Administration > Anzeige-Einstellungen;
   mit der Klasse wird zugleich logo-light.svg statt logo.svg geladen).
   Betrifft NUR Splashscreen und Gate-Login, nie die eigentliche App/Sidebar. Die Farben sind bewusst eigene Variablen, damit custom.css sie
   bei Bedarf anpassen kann. */
.wcp-splash-dark .wcp-splash,
.wcp-splash-dark .wcp-gatepage {
    background: var(--wcp-splash-dark-bg, #0d0d0f);
}

/* Gate-Login ist eine eigene Seite: auch Body (Overscroll/Rand) mitfaerben und
   native Browser-Elemente (Autofill, Scrollbars, Fokus) auf dunkel stellen. */
body.wcp-splash-dark:has(.wcp-gatepage) {
    background: var(--wcp-splash-dark-bg, #0d0d0f);
    color-scheme: dark;
}

.wcp-splash-dark .wcp-splash__powered {
    color: #8b909c;
}

/* Browser-Autofill faerbt Felder sonst hell/gelb ein. */
.wcp-splash-dark .wcp-gate-input:-webkit-autofill,
.wcp-splash-dark .wcp-gate-input:-webkit-autofill:focus {
    -webkit-text-fill-color: #e8eaf0;
    caret-color: #e8eaf0;
    box-shadow: 0 0 0 1000px var(--wcp-splash-dark-bg, #0d0d0f) inset;
    transition: background-color 9999s ease-out 0s;
}

.wcp-splash-dark .wcp-gate-input {
    border-bottom-color: #3a3f4b;
    color: #e8eaf0;
}

.wcp-splash-dark .wcp-gate-input:focus {
    border-bottom-color: #ffffff;
}

.wcp-splash-dark .wcp-gate-input::placeholder {
    color: #7b8190;
}

.wcp-splash-dark .wcp-gate-forgot {
    color: #9aa3b5;
}

.wcp-splash-dark .wcp-gate-forgot:hover {
    color: #ffffff;
}

.wcp-splash-dark .wcp-gate-error {
    color: #ff6b73;
}

/* --- Nicht verlinkte Dev-Werkzeuge (siehe assets/js/dev-tools.js) ---
   Baut sein komplettes Markup per JS auf, deshalb hier nur generisches
   Overlay-Styling - keine eigenen IDs/Feinheiten noetig. Bewusst simple
   Klick-auf-Backdrop-schliesst-Logik statt Bootstrap-Modal (dev-tools.js
   soll unveraendert auf jeder Seite funktionieren, auch dem Site-Gate-Login
   OHNE Bootstrap-JS-Bundle). */
.wcp-devtools {
    position: fixed;
    inset: 0;
    z-index: 2100;
    background: rgba(27, 35, 49, .55);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}

.wcp-devtools__box {
    position: relative;
    background: #fff;
    border-radius: .5rem;
    box-shadow: 0 12px 40px rgba(0, 0, 0, .3);
    padding: 1.5rem;
    width: 100%;
    max-width: 32rem;
    max-height: 90vh;
    overflow: auto;
}

.wcp-devtools__close {
    position: absolute;
    top: .75rem;
    right: .75rem;
}

/* --- Partner-/Herkunfts-Icons einer Buchung (siehe partials/source_icon.twig) ---
   B = Booking.com (dunkelblau), a = Agoda (weiss mit den fuenf bunten Punkten),
   Sprechblase mit Personen = Direktbuchung (Symbol wie auf der WebCeption-Website,
   in der Markenfarbe), durchgestrichener Kreis = gesperrter Zeitraum. */
.wcp-src {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: .45rem;
    font-weight: 800;
    font-size: 1.05rem;
    line-height: 1;
    vertical-align: middle;
}

.wcp-src--booking {
    background: #003580;
    color: #fff;
    letter-spacing: -.02em;
}

.wcp-src--booking span {
    color: #6cc4ff;
}

.wcp-src--agoda {
    background: #fff;
    border: 1px solid #d9dde5;
    color: #3a3a46;
}

.wcp-src--agoda b {
    margin-top: .3rem;
    font-weight: 800;
    letter-spacing: -.03em;
}

.wcp-src--agoda i {
    position: absolute;
    top: .22rem;
    width: .19rem;
    height: .19rem;
    border-radius: 50%;
}

.wcp-src--agoda i:nth-of-type(1) { left: .16rem; background: #e5484d; }
.wcp-src--agoda i:nth-of-type(2) { left: .47rem; background: #9b5de5; }
.wcp-src--agoda i:nth-of-type(3) { left: .78rem; background: #2eb872; }
.wcp-src--agoda i:nth-of-type(4) { left: 1.09rem; background: #f59e0b; }
.wcp-src--agoda i:nth-of-type(5) { left: 1.4rem; background: #3b82f6; }

.wcp-src--direct {
    background: var(--wcp-accent);
    color: #fff;
}

.wcp-src--direct svg {
    width: 1.15rem;
    height: 1.15rem;
    fill: currentColor;
}

.wcp-src--blocked {
    background: #e9ecef;
    color: #6c757d;
}

/* Mehrzeiliger Tooltip der Partner-Icons (Herkunft + ggf. Ersteller + Erstelldatum, siehe
   partials/source_icon.twig): data-bs-custom-class setzt diese Klasse auf Bootstraps
   .tooltip-Wurzelelement, pre-line laesst die echten "\n" im Titel-Text als Zeilenumbrueche
   wirken statt sie wie normaler Fliesstext zu Leerzeichen zusammenzufalten. */
.wcp-src-tooltip .tooltip-inner {
    white-space: pre-line;
    text-align: left;
}

/* --- Buchungen-Uebersicht (siehe views/buchungen.twig) ---
   Die laufende Buchung bekommt links einen Akzentstrich in der Markenfarbe. */
.wcp-bk-row > td:first-child {
    border-left: 3px solid transparent;
}

.wcp-bk-row--current > td:first-child {
    border-left-color: var(--wcp-accent);
}

.wcp-bk-room {
    cursor: pointer;
}

/* Handy: jede Buchung als kleine Karte statt breiter Tabelle - Zeile 1 Name + Partner-Icon,
   Zeile 2 Raum, Zeile 3 Zeitraum (die Sortierung per Spaltenkopf entfaellt dort, per Adresse
   #buchungen?sort=... bleibt sie moeglich). */
@media (max-width: 575.98px) {
    #wcpBuchungenTable thead {
        display: none;
    }

    #wcpBuchungenTable,
    #wcpBuchungenTable tbody {
        display: block;
    }

    #wcpBuchungenTable tr.wcp-bk-row {
        display: grid;
        grid-template-columns: 1fr auto;
        column-gap: .5rem;
        row-gap: .2rem;
        padding: .6rem 0;
        border-bottom: 1px solid var(--bs-border-color);
    }

    #wcpBuchungenTable tr.wcp-bk-row > td {
        display: block;
        padding: 0 0 0 .5rem;
        border: 0;
    }

    #wcpBuchungenTable tr.wcp-bk-row > td:first-child {
        grid-column: 1;
        grid-row: 1;
        padding-left: .5rem;
        font-weight: 600;
    }

    #wcpBuchungenTable tr.wcp-bk-row {
        border-left: 3px solid transparent;
    }

    #wcpBuchungenTable tr.wcp-bk-row--current {
        border-left-color: var(--wcp-accent);
    }

    #wcpBuchungenTable tr.wcp-bk-row > td:nth-child(4) {
        grid-column: 2;
        grid-row: 1;
        align-self: center;
    }

    #wcpBuchungenTable tr.wcp-bk-row > td:nth-child(2) {
        grid-column: 1 / -1;
        grid-row: 2;
    }

    #wcpBuchungenTable tr.wcp-bk-row > td:nth-child(3) {
        grid-column: 1 / -1;
        grid-row: 3;
    }
}

/* --- Aktivitaetsprotokoll (Administration > Aktivitaet, siehe admin.js) --- */
.wcp-activity-item {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    padding: .6rem .85rem;
}

.wcp-activity-icon {
    flex: none;
    width: 1.25rem;
    margin-top: .15rem;
    text-align: center;
}

.wcp-activity-text {
    flex: 1;
    min-width: 0;
    overflow-wrap: anywhere;
}

.wcp-activity-time {
    flex: none;
    margin-left: auto;
    padding-left: .5rem;
}

/* Eintraege mit einem Sprungziel (Buchungsmaske, Raum-/Standort-/Benutzer-Formular, Admin-
   Reiter) - siehe describeActivity()/activityRow() in admin.js. */
.wcp-activity-item--link {
    cursor: pointer;
}

.wcp-activity-item--link:hover,
.wcp-activity-item--link:focus-visible {
    background: var(--bs-tertiary-bg, #f4f6fa);
}

@media (max-width: 575.98px) {
    /* Schmal: die Uhrzeit rutscht unter den Text */
    .wcp-activity-item {
        flex-wrap: wrap;
    }

    .wcp-activity-time {
        flex-basis: 100%;
        margin-left: 0;
        padding-left: 2rem;
    }
}

/* --- Timeline SENKRECHT (nur Handy, siehe timeline.js renderVertical) ---
   Spalten = Raeume, Zeilen = Tage. Ein Scroll-Container; Kopfzeile (Raeume) und
   Tagesspalte bleiben per position:sticky stehen. Farben/Balken-Stile wie die
   waagerechte Timeline (.wcp-tl-*): gleiche Hintergruende, Linien, Heute-Markierung,
   Konflikt-Rahmen, ausgegraute Vergangenheit. */
:root {
    --wcp-tlv-day-col: 3.5rem; /* 56px */
    --wcp-tlv-room-col: 4.5rem; /* 72px */
    --wcp-tlv-head-h: 4.25rem; /* 68px */
    --wcp-tlv-row-h: 2.75rem; /* 44px, wie --wcp-tl-row-h */
}

.wcp-tlv-scroll {
    height: 65vh; /* Vorgabe - die genaue Hoehe setzt sizeVertical() in timeline.js */
    overflow: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    position: relative;
}

.wcp-tlv-grid {
    display: grid;
    width: 100%;
    min-width: calc(var(--wcp-tlv-day-col) + var(--wcp-tlv-rooms, 1) * var(--wcp-tlv-room-col));
    grid-template-columns: var(--wcp-tlv-day-col) repeat(var(--wcp-tlv-rooms, 1), minmax(0, 1fr));
    grid-template-rows: var(--wcp-tlv-head-h) repeat(var(--wcp-tlv-days, 1), var(--wcp-tlv-row-h));
}

.wcp-tlv-corner {
    position: sticky;
    top: 0;
    left: 0;
    z-index: 4;
    background: #fff;
    border-bottom: 2px solid #dde2ea;
    border-right: 2px solid #dde2ea;
}

.wcp-tlv-room {
    position: sticky;
    top: 0;
    z-index: 3;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    background: #fff;
    border-bottom: 2px solid #dde2ea;
    border-right: 1px solid #edf0f5;
    cursor: pointer;
}

.wcp-day-line {
    display: block;
}

.wcp-tlv-day {
    position: sticky;
    left: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: #fff;
    border-bottom: 1px solid #edf0f5;
    border-right: 2px solid #dde2ea;
    box-sizing: border-box;
    font-size: .78rem;
    font-weight: 600;
    line-height: 1.1;
    text-align: center;
    color: #6c7688;
}

/* Die Tagesspalte ist deckend (sonst scheinen Balken durch) - die Heute-Toenung liegt deshalb
   direkt auf ihr, in derselben Farbe wie der Streifen ueber den Raum-Spalten. */
.wcp-tlv-day--today {
    background: linear-gradient(var(--wcp-today-bg-color), var(--wcp-today-bg-color)) #fff;
}

.wcp-tlv-col {
    border-right: 1px solid #edf0f5;
}

/* Waagerechte Linie je Tag ueber alle Raum-Spalten (Gegenstueck zu .wcp-tl-daycol am Desktop) */
.wcp-tlv-dayrow {
    border-bottom: 1px solid #edf0f5;
    pointer-events: none;
}

.wcp-tlv-today-marker {
    background: var(--wcp-today-bg-color);
    pointer-events: none;
}

.wcp-tlv-bar {
    z-index: 1;
    margin: 0 .125rem;
    padding: .2rem .1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    border-radius: .8rem;
    background: var(--wcp-accent);
    color: #fff;
    font-size: .66rem;
    line-height: 1.1;
    text-align: center;
    overflow-wrap: anywhere;
    cursor: pointer;
}

.wcp-tlv-bar.wcp-tlv-bar--blocked {
    background: var(--wcp-ampel-grau);
}

.wcp-tlv-bar.wcp-tlv-bar--past {
    opacity: .4;
}

/* Ueberschneidung: roter Rahmen, bei zwei Buchungen nebeneinander (Spur 0 links, Spur 1 rechts) */
.wcp-tlv-bar.wcp-tlv-bar--conflict {
    outline: 2px solid #dc3545;
}

.wcp-tlv-bar--conflict.wcp-tlv-bar--lane0 {
    justify-self: start;
    width: calc(50% - .25rem);
}

.wcp-tlv-bar--conflict.wcp-tlv-bar--lane1 {
    justify-self: end;
    width: calc(50% - .25rem);
}

/* Halbe Spaltenbreite: kleinere Schrift, damit kurze Namen noch in eine Zeile passen */
.wcp-tlv-bar--conflict.wcp-tlv-bar--lane0,
.wcp-tlv-bar--conflict.wcp-tlv-bar--lane1 {
    padding: .2rem 0;
    font-size: .58rem;
}

/* --- Administration als Zahnrad in der Icon-Reihe (nur Admin, siehe sidebar.twig) ---
   Dezent wie die anderen runden Buttons, aber in der Signalfarbe (Sekundaerfarbe) -
   wer eingeloggt ist, erkennt es auf den ersten Blick, ohne dass es schreit. */
.wcp-sidebar__toolrow .wcp-admin-btn {
    color: var(--wcp-brand-secondary);
}

.wcp-sidebar__toolrow .wcp-admin-btn:hover,
.wcp-sidebar__toolrow .wcp-admin-btn.active {
    color: var(--wcp-brand-secondary);
    background: color-mix(in srgb, var(--wcp-brand-secondary) 18%, transparent);
}

/* Eingeklappte Sidebar: alle anderen Buttons laufen unter den Pfeil - der Admin-Zahnrad
   bleibt sichtbar und rutscht dafuer unter den Pfeil (die Reihe wird dann zwei Zeilen hoch). */
.wcp-sidebar--force-collapsed .wcp-sidebar__toolrow--admin {
    height: 5.75rem;
}

.wcp-sidebar--force-collapsed .wcp-sidebar__toolrow--admin .wcp-sidebar-toggle {
    top: 1.375rem;
}

.wcp-sidebar--force-collapsed .wcp-sidebar__toolrow--admin .wcp-admin-btn {
    left: 50%;
    top: calc(100% - 1.375rem);
}

@media (min-width: 768px) and (max-width: 1199.98px) {
    .wcp-sidebar:not(.wcp-sidebar--force-expanded) .wcp-sidebar__toolrow--admin {
        height: 5.75rem;
    }

    .wcp-sidebar:not(.wcp-sidebar--force-expanded) .wcp-sidebar__toolrow--admin .wcp-sidebar-toggle {
        top: 1.375rem;
    }

    .wcp-sidebar:not(.wcp-sidebar--force-expanded) .wcp-sidebar__toolrow--admin .wcp-admin-btn {
        left: 50%;
        top: calc(100% - 1.375rem);
    }
}

/* --- Handy: Sidebar als Offcanvas ---
   - Breite 260px (--wcp-sidebar-width-mobile), damit die runden Buttons nebeneinander passen
   - faehrt animiert von links herein (die Desktop-Regel "transition: width" haette Bootstraps
     eigene transform-Animation ueberschrieben)
   - das Schliessen-X (letzter runder Button der Icon-Reihe) dreht beim Oeffnen gleichzeitig mit ein
   - Uhr/Datum entfallen (auf dem Handy ohnehin immer greifbar)
   - die Icon-Reihe ist hier eine normale Flex-Reihe statt prozentual positioniert */
@keyframes wcp-close-spin {
    from {
        transform: rotate(-270deg) scale(.2);
        opacity: 0;
    }

    to {
        transform: none;
        opacity: 1;
    }
}

@media (max-width: 767.98px) {
    .wcp-sidebar {
        --bs-offcanvas-width: var(--wcp-sidebar-width-mobile);
        width: var(--wcp-sidebar-width-mobile);
        transition: transform .38s cubic-bezier(.32, .72, 0, 1);
    }

    /* Startet gleichzeitig mit dem Einfahren des Menues: Bootstrap setzt waehrend der Fahrt
       .showing und erst NACH der Fahrt .show - nur .show wuerde die Drehung erst am Ende starten.
       Beide Selektoren tragen dieselbe Animation, der Wechsel showing -> show startet sie nicht neu. */
    .wcp-sidebar.showing .wcp-close-btn i,
    .wcp-sidebar.show .wcp-close-btn i {
        animation: wcp-close-spin .45s cubic-bezier(.34, 1.56, .64, 1) backwards;
    }

    .wcp-sidebar__clock {
        display: none;
    }

    .wcp-sidebar__toolrow {
        display: flex;
        align-items: center;
        justify-content: space-around;
        height: auto;
        margin: .75rem .5rem 1rem;
    }

    .wcp-sidebar__toolrow .wcp-lang-switch,
    .wcp-sidebar__toolrow .wcp-auth-btn,
    .wcp-sidebar__toolrow .wcp-carousel-btn,
    .wcp-sidebar__toolrow .wcp-gate-btn,
    .wcp-sidebar__toolrow .wcp-admin-btn,
    .wcp-sidebar__toolrow .wcp-sidebar-toggle {
        position: static;
        transform: none;
    }
}

/* --- Schnellaktionen-Menue (Handy, siehe partials/quick_actions.twig): Blatt von unten --- */
.wcp-quick-sheet {
    height: auto;
    max-height: 75vh;
    max-height: 75dvh;
    border-radius: 1.25rem 1.25rem 0 0;
}

.wcp-quick-item {
    display: flex;
    align-items: center;
    gap: .9rem;
    min-height: 3.25rem;
    font-size: 1.05rem;
}

.wcp-quick-item i {
    width: 1.6rem;
    font-size: 1.3rem;
    text-align: center;
    color: var(--wcp-brand-primary);
}

/* Handy: der "+" der Kartenansicht entfaellt - dort gibt es den fliegenden Neue-Buchung-Button */
@media (max-width: 767.98px) {
    .wcp-fab {
        display: none;
    }
}

/* --- Timeline: Datum an der Leseposition in der Kopfzeile (Tipp = Heute) --- */
.wcp-view-toolbar .wcp-tl-datelabel {
    --bs-btn-padding-x: .25rem;
    --bs-btn-padding-y: 0;
    color: inherit;
    font-size: .95rem;
    white-space: nowrap;
}

/* --- Ebenen-Grafik in der Hilfe (Rollen sowie Rechte- und Seitenverwaltung, siehe doku.twig) --- */
.wcp-lv {
    --lv: #6c757d;
    padding: .75rem .9rem;
    background: #fff;
    border: 1px solid #dde2ea;
    border-top: 4px solid var(--lv);
    border-radius: .6rem;
}

.wcp-lv--kiosk { --lv: #14b8a6; }
.wcp-lv--display { --lv: #0ea5e9; }
.wcp-lv--staff { --lv: var(--wcp-brand-primary); }
.wcp-lv--admin { --lv: var(--wcp-brand-secondary); }

.wcp-lv h5 {
    margin-bottom: .4rem;
    font-size: 1rem;
}

.wcp-lv h5 > i {
    color: var(--lv);
}

.wcp-lv dl {
    margin: 0;
    font-size: .85rem;
}

.wcp-lv dt {
    margin-top: .45rem;
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: #6c7688;
}

.wcp-lv dd {
    margin: 0;
}

.wcp-lv-door {
    display: flex;
    align-items: center;
    gap: .9rem;
    margin: .6rem 0 .9rem;
    padding: .7rem 1rem;
    border: 2px dashed #9aa5b8;
    border-radius: .6rem;
    background: #f8f9fc;
}

.wcp-lv-door > i {
    font-size: 1.8rem;
    color: #6c7688;
}

.wcp-lv-link {
    padding: .2rem 0 .45rem;
    font-size: .8rem;
    font-weight: 600;
    text-align: center;
    color: #6c7688;
}

.wcp-lv-link i {
    vertical-align: -.1em;
}

/* --- Timeline-Zoom: kompakte Darstellung (Klasse .wcp-tl--compact am Wurzelelement, siehe timeline.js) ---
   Zweite Stufe neben der Standard-Darstellung: kleinere Spalten/Zeilen/Schrift, damit mehr Tage und
   Raeume gleichzeitig sichtbar sind. Die Groessen haengen alle an den Variablen - hier anpassen. */
.wcp-tl--compact {
    --wcp-tl-day-col: 2.25rem; /* 36px, Standard 56px */
    --wcp-tl-row-h: 1.875rem; /* 30px, Standard 44px */
    --wcp-tlv-day-col: 3rem;
    --wcp-tlv-room-col: 3.25rem;
    --wcp-tlv-head-h: 3.25rem;
    --wcp-tlv-row-h: 1.875rem;
}

.wcp-tl--compact .wcp-tl-cell {
    font-size: .68rem;
}

.wcp-tl--compact .wcp-tl-header {
    padding: 0 .1rem;
    font-size: .6rem;
}

.wcp-tl--compact .wcp-tl-room {
    gap: .3rem;
}

.wcp-tl--compact .wcp-tl-room-name {
    font-size: .8rem;
}

.wcp-tl--compact .wcp-tl-bar {
    height: 1.2rem;
    border-radius: 10px;
    padding: 0 .3rem;
    font-size: .62rem;
}

.wcp-tl--compact .wcp-tlv-day {
    font-size: .6rem;
}

.wcp-tl--compact .wcp-tlv-bar {
    font-size: .58rem;
}

.wcp-tl--compact .wcp-tlv-room {
    gap: .25rem;
}

/* --- Kalender-Zoom: kompakte Darstellung (Klasse .wcp-cal--compact am Wurzelelement, siehe calendar.js) ---
   Kleinere Böppel, engere Zeilen und Tageszahlen - bei vielen Raeumen werden die Tageszellen
   deutlich niedriger, der Monat passt eher auf den Bildschirm. Nur innerhalb #wcpCalendar, die
   Kuerzel-Böppel in Kopfzeilen/Tabellen bleiben unberuehrt. */
.wcp-cal--compact #wcpCalendar {
    --wcp-cal-chip-size: 1.05rem;
    --wcp-cal-chip-font: .5rem;
}

/* nur oben/unten - links/rechts bleibt, sonst ginge das margin-left:auto des Checkin-Halbböppels verloren */
.wcp-cal--compact #wcpCalendar .wcp-cal-chip {
    margin-top: 0;
    margin-bottom: 0;
}

.wcp-cal--compact #wcpCalendar .wcp-cal-chip--conflict::after {
    top: -.2rem;
    right: -.2rem;
    width: .6rem;
    height: .6rem;
    font-size: .45rem;
    line-height: .6rem;
}

.wcp-cal--compact #wcpCalendar .wcp-cal-chip-pair {
    margin: 0 auto;
}

.wcp-cal--compact #wcpCalendar .fc-daygrid-dot-event {
    padding: 0;
}

.wcp-cal--compact #wcpCalendar .fc-daygrid-event-harness + .fc-daygrid-event-harness .fc-daygrid-event {
    margin-top: 0;
}

.wcp-cal--compact #wcpCalendar .wcp-cal-add-btn {
    width: 1rem;
    height: 1rem;
    font-size: .55rem;
}

/* --- Kamera-Ausschnitt (Notch), abgerundete Ecken, Statusleiste: "Safe Areas" ---
   Das Layout nutzt viewport-fit=cover (siehe layout.twig), die App darf also in installierter
   Vollbild-/Standalone-Darstellung bis an den Displayrand reichen. Die Browser melden dann, wie viel
   Rand frei bleiben muss (env(safe-area-inset-*): Kamera-Ausschnitt, Statusleiste, abgerundete Ecken,
   Gesten-Leiste, im Querformat die Seiten). Ohne solche Aussparungen sind die Werte 0 - am Desktop und
   in normalen Browser-Tabs aendert sich also nichts.
   - oben: ein fester Streifen in der Navi-Farbe hinter dem Kamera-Ausschnitt, damit Inhalte beim
     Scrollen nicht darunter laufen (wirkt wie eine dunkle Statusleiste)
   - Inhalt, fliegende Buttons, Menue und Schnellaktionen halten den jeweiligen Rand ein */
body::before {
    content: "";
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: env(safe-area-inset-top, 0px);
    background: var(--wcp-sidebar-bg);
    z-index: 1035; /* ueber dem Inhalt und den fliegenden Buttons (1030), unter dem Menue (1045) */
    pointer-events: none;
}

.btn.wcp-mfab--menu {
    left: calc(var(--wcp-fab-gap) + env(safe-area-inset-left, 0px));
}

.btn.wcp-mfab--add {
    right: calc(var(--wcp-fab-gap) + env(safe-area-inset-right, 0px));
}

@media (max-width: 767.98px) {
    .wcp-sidebar {
        padding-top: env(safe-area-inset-top, 0px);
    }

    .wcp-sidebar__fixed {
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }
}

.wcp-quick-sheet {
    padding-bottom: env(safe-area-inset-bottom, 0px);
}
