/* Markenfarben als CSS-Variablen (Standardwerte = die bisherigen fest codierten Farbtoene) - ein
   nonce'd <style>-Block in includes/header.php/header_eltern.php (render_brand_color_css_variables()
   in includes/functions.php) ueberschreibt diese Werte, sobald ein Administrator unter
   "Einstellungen -> Darstellung -> Farben" eigene Farben hinterlegt hat. NICHT angefasst: die
   semantischen Bootstrap-Farben (Erfolg/Warnung/Gefahr/Info) fuer Status-Anzeigen - die bleiben
   bewusst unveraendert, unabhaengig von der Markenfarbe. */
:root {
    --brand-primary: #1b2420;
    --brand-primary-rgb: 27, 36, 32;
    --brand-primary-hover: #141c19;
    --brand-primary-active: #111815;
    --brand-sidebar-hover: #263229;
    --brand-sidebar-active: #2c3b30;
    --brand-accent: #4f7943;
}

body {
    background-color: #f5f6f8;
}

/* Layout-Grundgeruest: feste linke Seitenleiste (Navigation, weinrot) + rechte Spalte mit einer
   schmalen Kopfzeile (Benachrichtigungen/Hilfe/Design/Profil/Abmelden) und dem Seiteninhalt
   darunter. Ersetzt die vormalige zweizeilige horizontale Navigation (Themenreiter + Menuebalken)
   auf Nutzerwunsch durch eine dauerhaft sichtbare, uebersichtlichere Seitenleiste. */
.app-shell {
    display: flex;
    align-items: stretch;
    min-height: 100vh;
}

/* Dunkelgruen wie im abgestimmten Entwurf (statt des anfaenglichen Weinrots) - bewusst dieselbe
   feste Farbe in Hell- UND Dark Mode (kein separater [data-bs-theme="dark"]-Override), die Sidebar
   ist unabhaengig vom Seiten-Farbschema immer dunkel. */
.sidebar {
    flex: 0 0 260px;
    width: 260px;
    background-color: var(--brand-primary);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    z-index: 1030;
}

/* min-height: 0 ist hier das eigentlich entscheidende Detail (haeufige Flexbox-Falle): ohne diese
   Zeile berechnet der Browser die automatische Mindesthoehe eines Flex-Kindes anhand seines
   Inhalts, wodurch .sidebar-nav den umgebenden Container sprengt statt selbst zu scrollen. */
.sidebar-nav {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 0.75rem 0.6rem 1.5rem;
    display: flex;
    flex-direction: column;
}

.sidebar-nav .nav-item,
.sidebar-nav .nav-group-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.4rem;
    width: 100%;
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.1rem;
    border-radius: 0.375rem;
    background: none;
    border: none;
    text-align: left;
    font-size: 0.92rem;
    text-decoration: none;
}

.sidebar-nav .nav-item,
.sidebar-nav .nav-item:hover,
.sidebar-nav .nav-item:focus,
.sidebar-nav .nav-group-toggle,
.sidebar-nav .nav-group-toggle:hover,
.sidebar-nav .nav-group-toggle:focus {
    color: rgba(255, 255, 255, 0.85);
}

.sidebar-nav .nav-item:hover,
.sidebar-nav .nav-item:focus,
.sidebar-nav .nav-group-toggle:hover,
.sidebar-nav .nav-group-toggle:focus {
    background-color: var(--brand-sidebar-hover);
    color: #fff;
}

.sidebar-nav .nav-item.active {
    background-color: var(--brand-sidebar-active);
    color: #fff;
    font-weight: 600;
}

/* Variante von .nav-group-toggle fuer Gruppen, die zusaetzlich zum Auf-/Zuklappen auch direkt
   anklickbar sein sollen (z.B. Vereinsverwaltung -> eigene Uebersichtsseite): Beschriftung und
   Pfeil sind zwei getrennte Klickziele nebeneinander statt eines einzigen Buttons - der Wrapper
   selbst bekommt daher kein eigenes Padding/Hover mehr (das uebernehmen die beiden Kinder). */
.sidebar-nav .nav-group-toggle.nav-group-toggle-linked {
    padding: 0;
    background: none;
}

.sidebar-nav .nav-group-toggle-linked .nav-group-toggle-label {
    flex: 1 1 auto;
    padding: 0.5rem 0.75rem;
    border-radius: 0.375rem;
    color: rgba(255, 255, 255, 0.85);
    text-decoration: none;
    font-size: 0.92rem;
}

.sidebar-nav .nav-group-toggle-linked .nav-group-toggle-label:hover,
.sidebar-nav .nav-group-toggle-linked .nav-group-toggle-label:focus {
    background-color: var(--brand-sidebar-hover);
    color: #fff;
}

.sidebar-nav .nav-group-toggle-linked .nav-group-toggle-chevron {
    padding: 0.5rem 0.6rem;
    border-radius: 0.375rem;
    background: none;
    border: none;
    color: rgba(255, 255, 255, 0.85);
}

.sidebar-nav .nav-group-toggle-linked .nav-group-toggle-chevron:hover,
.sidebar-nav .nav-group-toggle-linked .nav-group-toggle-chevron:focus {
    background-color: var(--brand-sidebar-hover);
    color: #fff;
}

.sidebar-nav .nav-group-toggle .chevron {
    margin-left: auto;
    transition: transform 0.15s ease-in-out;
    font-size: 0.75rem;
    flex-shrink: 0;
}

.sidebar-nav .nav-group.open > .nav-group-toggle .chevron {
    transform: rotate(180deg);
}

.sidebar-nav .nav-children {
    display: none;
    flex-direction: column;
    padding-left: 0.75rem;
    margin: 0.1rem 0 0.3rem;
    border-left: 2px solid rgba(255, 255, 255, 0.15);
}

.sidebar-nav .nav-group.open > .nav-children {
    display: flex;
}

.sidebar-nav .nav-children .nav-item,
.sidebar-nav .nav-children .nav-group-toggle {
    font-size: 0.87rem;
}

.sidebar-nav .nav-section-label {
    margin: 1rem 0.75rem 0.35rem;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: rgba(255, 255, 255, 0.55);
}

.sidebar-nav .admin-divider {
    margin: 1rem 0.75rem 0;
    border-top: 1px solid rgba(255, 255, 255, 0.15);
}

.sidebar-nav .nav-badge {
    font-size: 0.65rem;
}

/* Rechte Spalte: schmale Kopfzeile oben (frueher rechter Teil des weinroten Menuebalkens) + der
   eigentliche Seiteninhalt (.container-fluid, siehe includes/header.php/footer.php) darunter. */
.main-content {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

/* Kein eigener Hintergrund mehr (auf Nutzerwunsch) - .topbar liegt direkt auf dem Seitenhintergrund
   (body) auf, dadurch automatisch dieselbe Farbe wie der restliche Seiteninhalt in Hell- UND Dark
   Mode, ganz ohne eigene [data-bs-theme]-Unterscheidung fuer den Hintergrund selbst. Schrift/Icons
   bekommen bewusst KEINE eigene feste Farbe mehr (siehe .topbar-icon-link weiter unten), sondern
   erben die normale, bereits themenabhaengige Bootstrap-Textfarbe - vorher war hier feste helle
   Schrift auf dunklem Grund noetig, das waere auf dem jetzt hellen Grund unlesbar. 20px Abstand
   nach unten zum Seiteninhalt. */
.topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    margin-bottom: 20px;
    background-color: transparent;
}

/* Der Burger-Button (nur auf schmalen Bildschirmen sichtbar, siehe @media weiter unten) oeffnet die
   Seitenleiste als Offcanvas. Da die Kopfzeile jetzt keinen eigenen (dunklen) Hintergrund mehr hat,
   muss das Symbol explizit je Farbschema gesetzt werden - Bootstraps eigener Standard-Hintergrund
   fuer .navbar-toggler-icon ist IMMER hell, unabhaengig von [data-bs-theme] (der abweichende dunkle
   Standard wird nur ueber die hier nie verwendete Klasse .navbar gesetzt), waere also im hellen
   Standard-Farbschema unsichtbar. */
.topbar .navbar-toggler {
    display: none;
}

.topbar .navbar-toggler-icon {
    --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(0, 0, 0, 0.75)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

[data-bs-theme="dark"] .topbar .navbar-toggler-icon {
    --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(255, 255, 255, 0.85)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

/* Rahmen wie beim bestehenden "✏️ Anpassen"-Button (btn-outline-secondary) auf Nutzerwunsch, damit
   alle Kopfzeilen-Buttons einheitlich als abgegrenzte Chips wirken statt nur als reine Links -
   var(--bs-secondary) ist dieselbe Variable, die Bootstraps eigene .btn-outline-secondary fuer ihren
   Rahmen verwendet, dadurch automatisch passend in Hell- UND Dark-Mode. */
.topbar-icon-link {
    color: inherit;
    text-decoration: none;
    font-size: 1.1rem;
    padding: 0.3rem 0.65rem;
    border: 1px solid var(--bs-secondary, #6c757d);
    border-radius: 0.375rem;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

/* Bootstraps eigene, bereits themenabhaengige Grauflaeche (var(--bs-tertiary-bg)) statt einer
   selbst gemischten hellen/dunklen Farbe - passt sich Hell-/Dark Mode automatisch an, gleiches
   Muster wie z. B. .chat-messages weiter unten in dieser Datei. */
.topbar-icon-link:hover,
.topbar-icon-link:focus {
    background-color: var(--bs-tertiary-bg, #f1f3f5);
    color: inherit;
}

/* Textbeschriftung neben JEDEM Icon/Button in der Kopfzeile (Suche/Benachrichtigungen/Nachrichten/
   Hilfe/Design/Anpassen/Profilname) - eigene, einheitliche Schriftgroesse statt der fuer die
   Emoji-Icons gedachten 1.1rem, damit die Beschriftung ueberall gleich gross erscheint (auf
   Nutzerwunsch). Auf schmalen Bildschirmen ausgeblendet (gleiche Schwelle wie das Umschalten auf
   den Offcanvas-Burger weiter unten) - dort bleibt es bei den platzsparenden reinen Icons wie zuvor. */
.topbar-icon-label {
    font-size: 0.8rem;
    white-space: nowrap;
}

/* Die rechte Button-Gruppe bricht notfalls um, statt die Seite breiter als den Bildschirm zu machen
   (horizontales Scrollen, dabei rutschen auch Inhalte weiter unten aus dem Sichtfeld). */
.topbar-right {
    flex-wrap: wrap;
    justify-content: flex-end;
    min-width: 0;
}

.topbar-left {
    flex-shrink: 0;
}

@media (max-width: 991.98px) {
    .topbar-icon-label {
        display: none;
    }

    /* Nur Icons: enger zusammenruecken (sieben Buttons + Burger muessen auf ein Handy passen), den
       Aufklapp-Pfeil weglassen. gap-3 von Bootstrap ist !important, daher hier ebenfalls. */
    .topbar {
        padding-left: 0.5rem;
        padding-right: 0.5rem;
    }

    .topbar-right {
        gap: 0.35rem !important;
    }

    .topbar-icon-link {
        padding: 0.3rem 0.45rem;
    }

    .topbar-icon-link.dropdown-toggle::after {
        display: none;
    }
}

.sidebar-backdrop {
    display: none;
}

/* Unterhalb der Bootstrap-lg-Schwelle (wie zuvor bei navbar-expand-lg) wird die Seitenleiste zum
   Offcanvas: standardmaessig ausserhalb des sichtbaren Bereichs, per Burger-Button (.open) von
   links einschiebbar, mit abdunkelndem Hintergrund zum Schliessen per Klick daneben. */
@media (max-width: 991.98px) {
    .sidebar {
        position: fixed;
        left: -260px;
        top: 0;
        transition: left 0.2s ease-in-out;
    }

    .sidebar.open {
        left: 0;
    }

    .topbar .navbar-toggler {
        display: inline-block;
    }

    .sidebar-backdrop.open {
        display: block;
        position: fixed;
        inset: 0;
        background-color: rgba(0, 0, 0, 0.4);
        z-index: 1020;
    }
}

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

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

.login-wrapper {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
}

.clock-status {
    font-size: 1.25rem;
}

.card {
    overflow: hidden;
}

/* Alle gewoehnlichen Fliesstext-Links auf Nutzerwunsch schwarz statt der Bootstrap-Standard-Linkfarbe
   (blau) - die Unterstreichung (Bootstrap-Standard fuer <a>) bleibt unveraendert bestehen, es aendert
   sich nur die Farbe. Bewusst eine einfache color-Regel auf dem <a>-Element statt Ueberschreiben von
   Bootstraps --bs-link-color(-rgb)-Variablen (Bootstrap nutzt fuer Hover-Transparenz mehrere
   zusammenhaengende RGB-/Opacity-Variablen, die sonst einzeln nachgezogen werden muessten). Betrifft
   NUR "nackte" <a>-Links ohne eigene Komponentenklasse: Bootstrap-Komponenten wie .nav-link,
   .dropdown-item, .btn, .list-group-item-action oder .card-header-action-link (siehe direkt darunter,
   Vorlage fuer diese Regel) haben als Klassenselektoren hoehere Spezifitaet und bleiben unangetastet.
   Im Dark Mode waere reines Schwarz auf dunklem Hintergrund unlesbar, daher dort helle statt schwarze
   Schrift, wie beim bestehenden .card-header-action-link-Muster. */
a {
    color: #000;
}

a:hover,
a:focus {
    color: #000;
}

[data-bs-theme="dark"] a {
    color: #f5f5f5;
}

[data-bs-theme="dark"] a:hover,
[data-bs-theme="dark"] a:focus {
    color: #f5f5f5;
}

/* Bootstrap-Komponenten-Links (v1.274.0): Reiter/Pillen (.nav-pills/.nav-tabs, z. B. "Offen/Erledigt/Alle"), Seitenzahlen, .btn-link,
   .text-primary/.link-primary und der aufgeklappte Akkordeon-Kopf waren noch im Bootstrap-Blau. Auf Nutzerwunsch gilt dafuer app-weit das
   Dunkelgruen der Button-Schrift (--brand-primary, folgt der unter "Darstellung" eingestellten Markenfarbe). Im Dark Mode waere es auf dem
   dunklen Grund unlesbar, daher dort helle Schrift und die Akzentfarbe fuer aktive Pillen. */
.nav {
    --bs-nav-link-color: var(--brand-primary);
    --bs-nav-link-hover-color: var(--brand-primary-hover);
}

.nav-pills {
    --bs-nav-pills-link-active-color: #fff;
    --bs-nav-pills-link-active-bg: var(--brand-primary);
}

.nav-tabs {
    --bs-nav-tabs-link-active-color: var(--brand-primary);
}

.pagination {
    --bs-pagination-color: var(--brand-primary);
    --bs-pagination-hover-color: var(--brand-primary-hover);
    --bs-pagination-focus-color: var(--brand-primary-hover);
    --bs-pagination-active-color: #fff;
    --bs-pagination-active-bg: var(--brand-primary);
    --bs-pagination-active-border-color: var(--brand-primary);
}

.btn-link {
    --bs-btn-color: var(--brand-primary);
    --bs-btn-hover-color: var(--brand-primary-hover);
    --bs-btn-active-color: var(--brand-primary-active);
}

.text-primary,
.link-primary {
    color: var(--brand-primary) !important;
}

.accordion {
    --bs-accordion-active-color: var(--brand-primary);
    --bs-accordion-btn-focus-border-color: var(--brand-primary);
    --bs-accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--brand-primary-rgb), 0.25);
}

[data-bs-theme="dark"] .nav {
    --bs-nav-link-color: #f5f5f5;
    --bs-nav-link-hover-color: #fff;
}

[data-bs-theme="dark"] .nav-pills {
    --bs-nav-pills-link-active-bg: var(--brand-accent);
}

[data-bs-theme="dark"] .nav-tabs {
    --bs-nav-tabs-link-active-color: #fff;
}

[data-bs-theme="dark"] .pagination {
    --bs-pagination-color: #f5f5f5;
    --bs-pagination-hover-color: #fff;
    --bs-pagination-focus-color: #fff;
    --bs-pagination-active-bg: var(--brand-accent);
    --bs-pagination-active-border-color: var(--brand-accent);
}

[data-bs-theme="dark"] .btn-link {
    --bs-btn-color: #f5f5f5;
    --bs-btn-hover-color: #fff;
    --bs-btn-active-color: #fff;
}

[data-bs-theme="dark"] .text-primary,
[data-bs-theme="dark"] .link-primary {
    color: #f5f5f5 !important;
}

[data-bs-theme="dark"] .accordion {
    --bs-accordion-active-color: #f5f5f5;
}

/* "Alle anzeigen"/"Kalender öffnen" auf der Startseite (und künftig alle gleichartigen
   Karten-Header-Links) - auf Nutzerwunsch immer schwarz+unterstrichen statt der sonst ueblichen
   Link-Farbe, damit sie sich klar als Aktion vom Fliesstext im Karten-Header abheben. Im Dark Mode
   waere reines Schwarz auf dem dunklen Karten-Hintergrund unlesbar, daher dort helle statt
   schwarze Schrift - "immer unterstrichen" bleibt in beiden Modi erhalten. Da inzwischen alle
   gewoehnlichen Links global schwarz sind (siehe oben), ist diese Regel hier strenggenommen
   redundant, bleibt aber als expliziter, bereits validierter Spezialfall unangetastet. */
.card-header-action-link {
    color: #000;
    text-decoration: underline;
}

.card-header-action-link:hover,
.card-header-action-link:focus {
    color: #000;
    text-decoration: underline;
}

[data-bs-theme="dark"] .card-header-action-link {
    color: #f5f5f5;
}

[data-bs-theme="dark"] .card-header-action-link:hover,
[data-bs-theme="dark"] .card-header-action-link:focus {
    color: #f5f5f5;
}

.calendar-table th {
    background-color: #f5f6f8;
}

.calendar-day {
    width: 14.28%;
    height: 100px;
    vertical-align: top;
    padding: 4px;
}

.calendar-day-outside {
    background-color: #fafafa;
    --bs-table-bg: #fafafa;
    color: #aaa;
}

/* Wochenende (v1.317.0): Samstag matt hellgelb, Sonntag matt hellorange - stehen vor Heute/Feiertag/Schließtag/Ferien, damit diese Markierungen Vorrang behalten.
   Alle Tagesfarben des Monatsrasters setzen zusätzlich --bs-table-bg, weil Bootstrap Tabellenzellen über diese Variable färbt (sonst blieben die Zellen weiß). */
.calendar-day-saturday {
    background-color: #fbf8e2;
    --bs-table-bg: #fbf8e2;
}

.calendar-day-sunday {
    background-color: #fcefe3;
    --bs-table-bg: #fcefe3;
}

.calendar-day-today {
    background-color: #fef8f8;
    --bs-table-bg: #fef8f8;
}

.calendar-day-holiday {
    background-color: #fcefe3;
    --bs-table-bg: #fcefe3;
}

.calendar-day-closure {
    background-color: #e3f5e0;
    --bs-table-bg: #e3f5e0;
}

/* Schulferien (v1.319.0): diagonal hellgruen/weiss schraffiert; Schliesstage sind einfarbig hellgruen. Die Schraffur ist ein background-image und braucht kein --bs-table-bg. */
.calendar-day-school {
    background-color: #ffffff;
    --bs-table-bg: #ffffff;
    background-image: repeating-linear-gradient(45deg, #e3f5e0 0, #e3f5e0 6px, #ffffff 6px, #ffffff 12px);
}

.calendar-day-number {
    font-size: 0.8rem;
    font-weight: 600;
    margin-bottom: 2px;
}

.calendar-badge {
    display: inline-block;
    margin-bottom: 2px;
}

/* Schliesstag-Beschriftung (v1.330.0) mit demselben Hintergrund wie die Ferien-Beschriftung (text-bg-success); die Tageszelle selbst bleibt hellgruen (.calendar-day-closure).
   text-bg-* setzt Farben mit !important, deshalb hier ebenfalls */
.calendar-badge-closure {
    background-color: RGBA(var(--bs-success-rgb), 1) !important;
    color: #fff !important;
}

/* Legende unter dem Kalender (v1.319.0): die Farbfelder tragen dieselben Klassen wie die Tageszellen und zeigen damit immer die echte Farbe */
/* Mein Dienstplan (v1.320.0): Uhrzeit steht direkt neben dem Datum; feste Mindestbreite haelt die Schichtkuerzel untereinander buendig (auch bei geteilten Diensten) */
.my-shift-time {
    min-width: 7.5rem;
}

.calendar-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.25rem;
    align-items: center;
}

.calendar-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
}

.calendar-legend-swatch {
    display: inline-block;
    width: 1.5rem;
    height: 1.1rem;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 3px;
}

/* Termine im Kalender (v1.326.0): hellgruen wie ein aktiver Menuepunkt (--ui-pill im modernen Design, sonst dieselbe Mischung aus Akzentfarbe und Weiss), schwarze Schrift.
   Der duenne Rand haelt den Termin auch auf gruen eingefaerbten Tagen (Schliesstag, Ferien) erkennbar. */
.calendar-event {
    background-color: var(--ui-pill, color-mix(in srgb, var(--brand-accent, #4f7943) 16%, #ffffff));
    color: #000;
    border: 1px solid color-mix(in srgb, var(--brand-accent, #4f7943) 35%, transparent);
    font-size: 0.7rem;
    padding: 1px 4px;
    border-radius: 3px;
    margin-bottom: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

[data-bs-theme="dark"] .calendar-event {
    background-color: var(--ui-pill, color-mix(in srgb, var(--brand-accent, #4f7943) 30%, #1f2226));
    color: #e7eee9;
}

/* Termine im Monatsraster stehen untereinander als Balken (Ellipse bei langen Titeln); als Inline-Element liefen sie ineinander und die Polsterung wirkte nicht */
.calendar-table .calendar-event {
    display: block;
}

/* Auf dem Handy bleibt der Kategorie-Streifen schmal (sonst bleibt in den schmalen Spalten kein Platz fuer den Titel) */
@media (max-width: 767.98px) {
    .calendar-table .calendar-event[style*="border-left"] {
        border-left-width: 4px !important;
    }
}

/* Monatsraster am Computer (v1.326.0): hoehere Tageskaestchen, groessere Termine, breiterer Kategorie-Streifen (7 px statt 4 px) */
@media (min-width: 768px) {
    .calendar-table .calendar-day {
        height: 130px;
    }
    .calendar-table .calendar-event {
        font-size: 0.82rem;
        line-height: 1.3;
        padding: 3px 6px;
        margin-bottom: 3px;
        border-radius: 4px;
    }
}

/* Kalender-Kopfzeile (v1.328.0): Vor-/Zurück-Knöpfe und Monatsname in einem Kasten fester Breite (der Monatsname verschiebt die Knöpfe nicht, die Maus bleibt an derselben Stelle);
   alle Knöpfe der Kopfzeile immer mit dunkelgrünem Rand (nicht nur beim Darüberfahren). */
.calendar-toolbar {
    --calendar-btn-border: var(--brand-primary, #1b2420);
}

[data-bs-theme="dark"] .calendar-toolbar {
    --calendar-btn-border: var(--ui-accent, #7fa874);
}

html body .calendar-toolbar .btn:not(.btn-link) {
    --bs-btn-border-color: var(--calendar-btn-border);
    --bs-btn-hover-border-color: var(--calendar-btn-border);
    --bs-btn-active-border-color: var(--calendar-btn-border);
    --bs-btn-disabled-border-color: var(--calendar-btn-border);
    border-color: var(--calendar-btn-border);
}

.calendar-nav-box {
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    box-sizing: border-box;
    width: 17rem;
    max-width: 100%;
    padding: 0.3rem 0.4rem;
    border: 1px solid var(--calendar-btn-border, var(--brand-primary, #1b2420));
    border-radius: 0.5rem;
}

.calendar-nav-box-wide {
    width: 25rem;
}

.calendar-nav-box .btn {
    flex: 0 0 auto;
    width: 2.2rem;
}

.calendar-nav-title {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    font-size: 1.2rem;
    font-weight: 600;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Kleiner Dialog am angeklickten Termin (v1.327.0, assets/js/event-popover.js): weisse Karte mit Pfeil auf den Termin, Kategorie-Streifen neben Titel, Datum, Uhrzeit und Ort,
   Gruppen-Hinweis, darunter "Termin bearbeiten" und "Termin anzeigen". */
.event-popover {
    --event-popover-bg: var(--ui-surface, var(--bs-body-bg, #ffffff));
    position: absolute;
    z-index: 1080;
    box-sizing: border-box;
    padding: 1.1rem 1.25rem 1.1rem;
    background: var(--event-popover-bg);
    color: var(--bs-body-color);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 1.1rem;
    box-shadow: 0 14px 44px rgba(0, 0, 0, 0.2);
    outline: none;
}

.event-popover-close {
    position: absolute;
    top: 1rem;
    right: 1rem;
}

.event-popover-head {
    display: flex;
    gap: 0.85rem;
    padding-right: 2rem;
}

.event-popover-bar {
    flex: 0 0 auto;
    align-self: stretch;
    width: 0.4rem;
    border-radius: 0.25rem;
}

.event-popover-bar-neutral {
    background-color: var(--bs-border-color, #ced4da);
}

.event-popover-info {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.event-popover-title {
    margin: 0 0 0.15rem;
    font-size: 1.2rem;
    font-weight: 700;
    line-height: 1.25;
    overflow-wrap: anywhere;
}

.event-popover-row {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    overflow-wrap: anywhere;
}

.event-popover-row .bi {
    flex: 0 0 auto;
    color: var(--bs-secondary-color, #6c757d);
}

.event-popover-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.9rem;
    padding: 0.2rem 0.85rem 0.2rem 0.25rem;
    border-radius: 999px;
    background: var(--bs-tertiary-bg, #f1f3f2);
    border: 1px solid var(--bs-border-color, #dee2e6);
    font-size: 0.85rem;
}

.event-popover-chip-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.6rem;
    height: 1.6rem;
    border-radius: 50%;
    background: var(--bs-secondary-bg, #e9ecef);
    color: var(--bs-secondary-color, #6c757d);
}

.event-popover-divider {
    margin: 1rem 0;
    opacity: 0.2;
}

.event-popover-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.6rem;
}

.event-popover-arrow {
    position: absolute;
    width: 1rem;
    height: 1rem;
    margin-left: -0.5rem;
    background: var(--event-popover-bg);
    border: 1px solid var(--bs-border-color, #dee2e6);
}

.event-popover-above .event-popover-arrow {
    bottom: -0.55rem;
    border-top: 0;
    border-left: 0;
    transform: rotate(45deg);
}

.event-popover-below .event-popover-arrow {
    top: -0.55rem;
    border-bottom: 0;
    border-right: 0;
    transform: rotate(45deg);
}

@media print {
    .event-popover {
        display: none;
    }
}

[data-bs-theme="dark"] body {
    background-color: #16181b;
}

[data-bs-theme="dark"] .calendar-table th {
    background-color: #1f2226;
}

[data-bs-theme="dark"] .calendar-day-outside {
    background-color: #1a1c1f;
    --bs-table-bg: #1a1c1f;
    color: #666;
}

[data-bs-theme="dark"] .calendar-day-saturday {
    background-color: #24241c;
    --bs-table-bg: #24241c;
}

[data-bs-theme="dark"] .calendar-day-sunday {
    background-color: #2b241d;
    --bs-table-bg: #2b241d;
}

[data-bs-theme="dark"] .calendar-day-today {
    background-color: #2c1e21;
    --bs-table-bg: #2c1e21;
}

[data-bs-theme="dark"] .calendar-day-holiday {
    background-color: #2b241d;
    --bs-table-bg: #2b241d;
}

[data-bs-theme="dark"] .calendar-day-closure {
    background-color: #1e3626;
    --bs-table-bg: #1e3626;
}

[data-bs-theme="dark"] .calendar-day-school {
    background-color: #1a1c1f;
    --bs-table-bg: #1a1c1f;
    background-image: repeating-linear-gradient(45deg, #1e3626 0, #1e3626 6px, #1a1c1f 6px, #1a1c1f 12px);
}

.absence-overview-table {
    table-layout: fixed;
}

.absence-overview-table .absence-sticky-col {
    position: sticky;
    left: 0;
    background-color: var(--bs-table-bg, var(--bs-body-bg));
    z-index: 1;
    width: 50px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.absence-overview-table .absence-sticky-col-2 {
    left: 50px;
    width: 65px;
}

.absence-overview-table .absence-date-col {
    width: 24px;
    height: 92px;
    vertical-align: middle;
    padding: 4px 0;
    text-align: center;
}

.absence-overview-table .absence-date-weekday {
    font-size: 0.7rem;
    font-weight: normal;
    color: var(--bs-secondary-color, #6c757d);
    margin-bottom: 2px;
}

.absence-overview-table .absence-date-label {
    display: inline-block;
    margin-top: 12px;
    transform: rotate(-90deg);
    white-space: nowrap;
    font-weight: normal;
}

.absence-overview-table .absence-weekend {
    background-color: #e3f6e3;
}

.absence-overview-table .absence-holiday {
    background-color: #fbdede;
}

[data-bs-theme="dark"] .absence-overview-table .absence-weekend {
    background-color: #1c3320;
}

[data-bs-theme="dark"] .absence-overview-table .absence-holiday {
    background-color: #3d1f1f;
}

.shift-planning-table {
    table-layout: fixed;
}

.shift-planning-table .shift-sticky-col {
    position: sticky;
    left: 0;
    background-color: var(--bs-table-bg, var(--bs-body-bg));
    z-index: 1;
    width: 163px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.shift-planning-table .shift-date-col {
    width: 36px;
    padding: 0.75rem 0.2rem !important;
    vertical-align: middle;
    text-align: center;
    position: relative;
    min-height: 52px;
}

.shift-planning-table .shift-date-header {
    height: 70px;
    position: relative;
}

.shift-planning-table .shift-date-rotate {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) rotate(-90deg);
    white-space: nowrap;
}

.shift-planning-table .shift-date-weekday {
    font-size: 0.7rem;
    color: var(--bs-secondary-color, #6c757d);
}

.shift-planning-table .shift-date-label {
    font-size: 0.8rem;
}

.shift-planning-table .shift-weekend {
    background-color: #e3f6e3;
}

.shift-planning-table .shift-holiday {
    background-color: #fbdede;
}

[data-bs-theme="dark"] .shift-planning-table .shift-weekend {
    background-color: #1c3320;
}

[data-bs-theme="dark"] .shift-planning-table .shift-holiday {
    background-color: #3d1f1f;
}

.shift-cell-btn,
.shift-cell-btn2 {
    position: absolute !important;
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important;
    width: 34px;
    height: 28px;
    padding: 0 !important;
    margin: 0;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: var(--bs-border-radius-sm, 0.25rem);
    background-color: var(--bs-body-bg);
    color: var(--bs-body-color);
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    text-align: center;
    line-height: 1;
}

.shift-cell-btn.shift-drop-target,
.shift-cell-btn2.shift-drop-target {
    outline: 2px dashed #0d6efd;
    outline-offset: -2px;
}

/* Zwei Dienste pro Tag (v1.266.0): sobald ein Dienst eingetragen ist, sitzt darunter ein zweites Kaestchen (Klick- und Ablageziel fuer den zweiten Dienst) */
.shift-planning-table td.shift-cell-two {
    height: 46px;
}

.shift-planning-table .shift-cell-two .shift-cell-btn {
    top: 27% !important;
    height: 19px;
    font-size: 0.7rem;
}

.shift-planning-table .shift-cell-two .shift-cell-btn2 {
    top: 74% !important;
    height: 19px;
    font-size: 0.7rem;
}

.shift-cell-btn2.shift-cell-btn2-empty {
    border-style: dashed;
    background-color: transparent;
    color: var(--bs-secondary-color, #6c757d);
    font-weight: 400;
}

.shift-cell-btn2.shift-cell-btn2-empty:hover {
    border-color: #0d6efd;
    color: #0d6efd;
}

.shift-day-row-second {
    border-top: none;
    background-color: transparent;
}

.shift-day-row-second .shift-day-track-2 {
    height: 26px;
}

.shift-day-row-second .shift-day-bar {
    top: 2px;
    bottom: 2px;
}

.shift-chip-tray {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.shift-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 28px;
    cursor: grab;
    user-select: none;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: var(--bs-border-radius-sm, 0.25rem);
    background-color: var(--bs-body-bg);
    color: var(--bs-body-color);
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
}

.shift-chip:active {
    cursor: grabbing;
}

.shift-badge {
    color: #fff;
    font-size: 0.7rem;
}

.shift-planning-table .shift-understaffed {
    background-color: #fbdede;
    color: #842029;
    font-weight: 600;
}

.shift-planning-table .shift-staffed-ok {
    background-color: #e3f6e3;
    color: #146c2e;
}

[data-bs-theme="dark"] .shift-planning-table .shift-understaffed {
    background-color: #3d1f1f;
    color: #ea868f;
}

[data-bs-theme="dark"] .shift-planning-table .shift-staffed-ok {
    background-color: #1c3320;
    color: #75b798;
}

/* Dienstplan-Tagesansicht (admin/shift_planning.php?view=day): ein Zeitstrahl statt eines
   Tabellenrasters, da Schichten hier nach tatsaechlicher Uhrzeit positioniert werden (nicht nur
   nach Kalendertag wie in der Monatsansicht) - siehe shift_day_view_bar_geometry() in
   includes/shift_planning.php fuer die Positionsberechnung (left/width in Prozent). */
.shift-day-timeline {
    overflow-x: auto;
}

.shift-day-row {
    display: flex;
    align-items: stretch;
    border-bottom: 1px solid var(--bs-border-color, #dee2e6);
}

.shift-day-row:last-child {
    border-bottom: none;
}

.shift-day-header-row {
    border-bottom: 2px solid var(--bs-border-color, #dee2e6);
    padding-bottom: 4px;
}

.shift-day-name-col {
    flex: 0 0 150px;
    width: 150px;
    padding: 6px 8px;
    display: flex;
    align-items: center;
    font-size: 0.85rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.shift-day-track {
    position: relative;
    flex: 1 1 auto;
    min-width: 600px;
    height: 40px;
    background-color: var(--bs-tertiary-bg, #f8f9fa);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: var(--bs-border-radius-sm, 0.25rem);
    cursor: pointer;
}

.shift-day-header-row .shift-day-track {
    height: 20px;
    background-color: transparent;
    border: none;
    cursor: default;
}

.shift-day-track.shift-drop-target {
    outline: 2px dashed #0d6efd;
    outline-offset: -2px;
}

.shift-day-open-band {
    position: absolute;
    top: 0;
    bottom: 0;
    background-color: #fff7d6;
}

[data-bs-theme="dark"] .shift-day-open-band {
    background-color: #3a3320;
}

.shift-day-hour-line {
    position: absolute;
    top: 0;
    bottom: 0;
    border-left: 1px dashed var(--bs-border-color, #dee2e6);
}

.shift-day-hour-label {
    position: absolute;
    top: 0;
    font-size: 0.7rem;
    color: var(--bs-secondary-color, #6c757d);
    transform: translateX(-50%);
}

.shift-day-bar {
    position: absolute;
    top: 3px;
    bottom: 3px;
    color: #fff;
    font-size: 0.75rem;
    font-weight: 600;
    display: flex;
    align-items: center;
    padding: 0 6px;
    border-radius: var(--bs-border-radius-sm, 0.25rem);
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.shift-day-vacation-band {
    position: absolute;
    inset: 3px;
    background-color: #ffc107;
    color: #000;
    font-size: 0.75rem;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--bs-border-radius-sm, 0.25rem);
}

/* Administration-Startseite: Links in normaler Textfarbe statt Bootstrap-Blau - color: inherit
   statt eines festen Farbwerts, damit es automatisch zur jeweiligen Textfarbe in Hell-/Dark-Mode
   passt (kein separater [data-bs-theme="dark"]-Block noetig). Farbbadges (text-danger/text-warning
   auf den Kennzahlen) bleiben unberuehrt, da die betroffenen <a>-Elemente selbst keine solche
   Klasse tragen - nur ihre Kind-<div>s. */
.admin-dashboard a {
    color: inherit;
}

.admin-dashboard a:hover,
.admin-dashboard a:focus {
    color: inherit;
    text-decoration: underline;
}

/* Shop-Produktkarte (orders.php): responsives Grid (4 Spalten auf Desktop/Laptop, automatischer
   Umbruch auf schmaleren Viewports ueber Bootstraps row-cols-* im Markup). Bild max. 120x120px,
   skaliert kleinere Bilder nicht hoch und verzerrt sie nicht (max-width/-height statt fester
   Groesse). */
.shop-product-image {
    max-width: 120px;
    max-height: 120px;
    width: auto;
    height: auto;
    object-fit: contain;
}

/* "Zum Shop"-Link in normaler Textfarbe statt Bootstrap-Blau - gleiches color:inherit-Muster wie
   .admin-dashboard a oben, passt sich automatisch an Hell-/Dark-Mode an. */
.shop-product-link {
    color: inherit;
}

.shop-product-link:hover,
.shop-product-link:focus {
    color: inherit;
    text-decoration: underline;
}

/* Quill.js (assets/js/rich-text.js) liefert im Snow-Theme feste helle Farben - im Dark Mode auf die
   Bootstrap-Body-Farben umstellen, damit der Editor nicht als heller Block auffaellt. */
[data-bs-theme="dark"] .ql-toolbar.ql-snow,
[data-bs-theme="dark"] .ql-container.ql-snow {
    border-color: var(--bs-border-color);
}

[data-bs-theme="dark"] .ql-toolbar.ql-snow {
    background-color: var(--bs-tertiary-bg);
}

[data-bs-theme="dark"] .ql-editor {
    color: var(--bs-body-color);
    background-color: var(--bs-body-bg);
}

[data-bs-theme="dark"] .ql-snow .ql-stroke {
    stroke: var(--bs-body-color);
}

[data-bs-theme="dark"] .ql-snow .ql-fill {
    fill: var(--bs-body-color);
}

[data-bs-theme="dark"] .ql-snow .ql-picker {
    color: var(--bs-body-color);
}

/* Fertig gerenderter Rich-Text-Inhalt (z. B. Nachrichten, Informationen, Termine, Kommentare) -
   sorgt fuer sinnvolle Abstaende zwischen Absaetzen/Listen, da der Standard-Browser-Stil dafuer
   ausreicht, aber letztes Element keinen unnoetigen unteren Rand haben soll. */
.rich-text-content > *:last-child {
    margin-bottom: 0;
}

/* Ueberschriften innerhalb von Rich-Text-Inhalt (Quill erlaubt h1/h2/h3) sollen sich optisch wie
   die uebrigen kleinen Abschnittstitel der Anwendung einfuegen (z. B. <h2 class="h6"> in
   datenschutz.php/impressum.php), statt in der vollen Browser-Standardgroesse zu erscheinen. */
.rich-text-content h1 {
    font-size: 1.25rem;
    margin-top: 1rem;
}

.rich-text-content h2 {
    font-size: 1.1rem;
    margin-top: 1rem;
}

.rich-text-content h3 {
    font-size: 1rem;
    margin-top: 1rem;
}

.rich-text-content h1:first-child,
.rich-text-content h2:first-child,
.rich-text-content h3:first-child {
    margin-top: 0;
}

/* Formular-Builder (admin/document_template_form.php) - Drag&Drop-Feldtypen-Palette + Baustein-
   Karten, gleiches Muster wie .shift-chip/.shift-drop-target im Dienstplan-Raster. */
.form-builder-chip {
    display: block;
    padding: 0.6rem 0.9rem;
    margin: 0.25rem 0.25rem 0.75rem;
    cursor: grab;
    user-select: none;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.6rem;
    background-color: var(--bs-tertiary-bg, #f8f9fa);
    color: var(--bs-body-color);
    font-size: 0.85rem;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.form-builder-chip:hover {
    border-color: #0d6efd;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.form-builder-chip:active {
    cursor: grabbing;
}

.form-builder-field-card {
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: var(--bs-border-radius-sm, 0.25rem);
    padding: 0.75rem;
    margin-bottom: 0.75rem;
    cursor: grab;
    background-color: var(--bs-tertiary-bg, #f8f9fa);
}

.form-builder-field-card:active {
    cursor: grabbing;
}

.form-builder-section-header {
    cursor: grab;
}

.form-builder-end-drop-zone {
    border: 1px dashed var(--bs-border-color, #dee2e6);
    border-radius: var(--bs-border-radius-sm, 0.25rem);
    padding: 0.5rem;
    text-align: center;
}

.form-builder-drop-target {
    outline: 2px dashed #0d6efd;
    outline-offset: -2px;
}

.upload-dropzone {
    border: 2px dashed var(--brand-primary);
    border-radius: var(--bs-border-radius, 0.375rem);
    padding: 1.75rem 1.5rem;
    text-align: center;
    cursor: pointer;
    color: var(--bs-secondary-color, #6c757d);
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

.upload-dropzone:hover {
    border-color: var(--brand-accent);
}

.upload-dropzone-active {
    border-color: var(--brand-accent);
    background-color: rgba(var(--brand-primary-rgb), 0.06);
}

/* Digitale Unterschrift (informationen.php/eltern/portal.php, assets/js/signature-pad.js). */
.signature-pad-canvas {
    display: block;
    width: 100%;
    height: 180px;
    border: 2px dashed var(--brand-primary);
    border-radius: var(--bs-border-radius, 0.375rem);
    background-color: #fff;
    cursor: crosshair;
    touch-action: none;
}

/* Kompaktere Variante innerhalb einer Chat-Bubble (nachrichten.php/eltern/nachrichten.php) - eine
   feste Breite statt 100% vermeidet Sizing-Eigenheiten von <canvas> in einem shrink-to-fit-Flex-Item. */
.signature-pad-canvas-compact {
    width: 260px;
    max-width: 100%;
    height: 130px;
}

/* Fortschrittsliste beim Datei-Upload (cloud.php, assets/js noch nicht ausgelagert) - je Datei ein
   eigener Balken, da ein einzelner Multipart-Request im Browser nur einen Gesamtfortschritt liefert. */
.cloud-upload-item {
    margin-bottom: 0.6rem;
}

.cloud-upload-item .progress {
    height: 6px;
}

.cloud-upload-item-name {
    max-width: 75%;
}

/* Ordner-Namen in der Cloud (Ordnerliste + Breadcrumb) sollen wie normaler Text wirken statt wie
   ein Hyperlink - Farbe folgt der normalen Textfarbe (hell/dunkel-Modus-faehig ueber die
   Bootstrap-Variable statt eines festen Schwarz, das im Dark Mode unlesbar waere). */
.cloud-folder-link {
    color: var(--bs-body-color);
    text-decoration: none;
}

/* Dateiname-Link bei Bildern in der Listenansicht (oeffnet die Lightbox) - gleiches
   "wirkt wie normaler Text statt Hyperlink"-Muster wie .cloud-folder-link oben. */
.cloud-file-link {
    color: var(--bs-body-color);
    text-decoration: none;
}

/* Dateien (cloud.php): Ordnerbaum links, Inhalt rechts. Auf schmalen Bildschirmen steht der Baum einklappbar ueber dem Inhalt. */
.cloud-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
}
@media (min-width: 992px) {
    .cloud-layout { grid-template-columns: 17rem minmax(0, 1fr); align-items: start; }
    .cloud-layout-side { position: sticky; top: 1rem; }
    .cloud-tree { max-height: calc(100vh - 2rem); overflow: auto; }
}
.cloud-layout-main { min-width: 0; }
.cloud-tree { padding: 0.5rem; }
.cloud-tree-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0 0.25rem 0.5rem;
    border-bottom: 1px solid var(--bs-border-color);
    margin-bottom: 0.5rem;
}
.cloud-tree-list { list-style: none; margin: 0; padding: 0; }
.cloud-tree-children { margin-left: 0.9rem; border-left: 1px solid var(--bs-border-color); }
.cloud-tree-row { display: flex; align-items: center; gap: 0.1rem; border-radius: 0.375rem; min-height: 2rem; }
.cloud-tree-row:hover { background: var(--bs-tertiary-bg); }
.cloud-tree-row.is-current { background: var(--bs-secondary-bg); font-weight: 600; }
.cloud-tree-row.is-department > .cloud-tree-link { font-weight: 600; }
.cloud-tree-toggle,
.cloud-tree-spacer { flex: 0 0 1.75rem; width: 1.75rem; height: 1.75rem; }
.cloud-tree-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    background: transparent;
    color: var(--bs-secondary-color);
    border-radius: 0.375rem;
    padding: 0;
}
.cloud-tree-toggle:hover { color: var(--bs-body-color); background: var(--bs-secondary-bg); }
.cloud-tree-toggle .bi { transition: transform 0.15s ease; font-size: 0.75rem; }
.cloud-tree-toggle[aria-expanded="true"] .bi { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) { .cloud-tree-toggle .bi { transition: none; } }
.cloud-tree-link {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    padding: 0.2rem 0.35rem 0.2rem 0;
    color: var(--bs-body-color);
    text-decoration: none;
}
.cloud-tree-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Chat-UI (nachrichten.php, eltern/nachrichten.php): Bubble-Optik + sticky Eingabe unten +
   Listen/Detail-Umschaltung auf schmalen Bildschirmen (siehe assets/js/chat.js). Bewusst als
   eigener Block statt Wiederverwendung der generischen .card-Klassen, da die feste Hoehe und das
   interne Scrollen (Nachrichtenliste) vom sonstigen Seiten-Scrollverhalten abweicht. */
.chat-layout {
    height: calc(100vh - 12rem);
    min-height: 26rem;
}

.chat-sidebar-card,
.chat-panel-card {
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.chat-sidebar-list {
    overflow-y: auto;
    flex: 1 1 auto;
}

.chat-messages {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 1rem;
    background-color: var(--bs-tertiary-bg, #f8f9fa);
}

[data-bs-theme="dark"] .chat-messages {
    background-color: rgba(255, 255, 255, 0.02);
}

.chat-bubble-row {
    display: flex;
    margin-bottom: 0.5rem;
}

.chat-bubble-row-own {
    justify-content: flex-end;
}

.chat-bubble {
    max-width: 78%;
}

.chat-bubble-content {
    padding: 0.4rem 0.7rem;
    border-radius: 1rem;
    background-color: var(--bs-secondary-bg, #e9ecef);
}

/* Kompakter Zeilenabstand in den Sprechblasen (v1.198.1): Quill legt je Enter einen <p> an, und der Bootstrap-Standard (1 rem
   Absatzabstand, Zeilenhoehe 1.5) wirkte im Chat viel zu luftig. Gilt fuer Chat-Seite, Chat-Fenster und per JS nachgeladene Nachrichten. */
.chat-bubble-content {
    line-height: 1.3;
}

.chat-bubble-content p,
.chat-bubble-content ul,
.chat-bubble-content ol,
.chat-bubble-content blockquote,
.chat-bubble-content pre {
    margin-bottom: 0.15rem;
}

.chat-bubble-content > *:last-child {
    margin-bottom: 0;
}

.chat-bubble-content h1,
.chat-bubble-content h2,
.chat-bubble-content h3 {
    margin-top: 0.35rem;
    margin-bottom: 0.15rem;
}

.chat-bubble-content h1:first-child,
.chat-bubble-content h2:first-child,
.chat-bubble-content h3:first-child {
    margin-top: 0;
}

.chat-bubble-row-own .chat-bubble-content {
    background-color: var(--brand-primary);
    color: #fff;
    border-bottom-right-radius: 0.25rem;
}

.chat-bubble-row:not(.chat-bubble-row-own) .chat-bubble-content {
    border-bottom-left-radius: 0.25rem;
}

.chat-bubble-meta {
    font-size: 0.75rem;
    margin-bottom: 0.15rem;
}

/* Nachrichten bearbeiten/loeschen (v1.213.0): kleine Symbole in der Meta-Zeile der Sprechblase */
.chat-bubble-actions {
    margin-left: 0.35rem;
    white-space: nowrap;
}

.chat-action-btn {
    background: none;
    border: 0;
    padding: 0 0.2rem;
    color: inherit;
    opacity: 0.65;
    line-height: 1;
}

.chat-action-btn:hover,
.chat-action-btn:focus-visible {
    opacity: 1;
}

.chat-deleted-note {
    opacity: 0.8;
}

.chat-read-info {
    white-space: nowrap;
    cursor: default;
}

.chat-input-bar {
    flex: 0 0 auto;
    border-top: 1px solid var(--bs-border-color, #dee2e6);
    padding: 0.75rem;
}

/* Kompakte Dropzone in der schmalen Antwort-Leiste (nachrichten.php/eltern/nachrichten.php) statt
   der grossen, fuer Modals gedachten .upload-dropzone-Standardgroesse. */
.chat-attachment-dropzone {
    padding: 0.4rem 0.75rem;
    text-align: left;
}

.chat-back-link {
    display: none;
}

/* Unter 768px: nur eines der beiden Panels zeigen (Liste ODER aktive Unterhaltung), analog zu
   Signal/WhatsApp auf dem Handy - .chat-conversation-active wird server- bzw. link-seitig ueber die
   vorhandene ?conversation=ID-Navigation gesetzt (kein zusaetzlicher State noetig). */
@media (max-width: 767.98px) {
    .chat-layout.chat-conversation-active .chat-sidebar-col {
        display: none;
    }

    .chat-layout:not(.chat-conversation-active) .chat-panel-col {
        display: none;
    }

    .chat-back-link {
        display: inline-flex;
    }

    .chat-bubble {
        max-width: 88%;
    }
}

/* Cloud (cloud.php): Thumbnail-Ansichten (klein/groß) als Alternative zur Listenansicht - Kachelgroesse
   ueber --cloud-thumb-size je nach gewaehlter Groesse, damit .cloud-thumb-image/.cloud-thumb-icon
   dieselbe Regel fuer beide Varianten nutzen koennen. Bilder werden per object-fit:cover zugeschnitten
   statt verzerrt - es werden keine echten Server-Thumbnails erzeugt (wie auch sonst im Projekt nicht,
   z. B. child_portfolio.php), die volle Bilddatei wird nur per CSS verkleinert dargestellt. */
.cloud-thumb-grid {
    --cloud-thumb-size: 110px;
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    padding: 1rem;
}

.cloud-thumb-grid.cloud-thumb-lg {
    --cloud-thumb-size: 200px;
}

.cloud-thumb-card {
    position: relative;
    width: calc(var(--cloud-thumb-size) + 1.5rem);
    border: 1px solid var(--bs-border-color);
    border-radius: var(--bs-border-radius, 0.375rem);
    padding: 0.5rem;
    text-align: center;
}

.cloud-thumb-checkbox {
    position: absolute;
    top: 0.5rem;
    left: 0.5rem;
}

.cloud-thumb-image {
    width: var(--cloud-thumb-size);
    height: var(--cloud-thumb-size);
    margin: 0 auto;
    cursor: pointer;
    border-radius: var(--bs-border-radius-sm, 0.25rem);
    overflow: hidden;
    background-color: var(--bs-tertiary-bg, #f8f9fa);
}

.cloud-thumb-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.cloud-thumb-icon {
    width: var(--cloud-thumb-size);
    height: var(--cloud-thumb-size);
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background-color: var(--bs-tertiary-bg, #f8f9fa);
    border-radius: var(--bs-border-radius-sm, 0.25rem);
}

.cloud-thumb-icon .bi {
    font-size: calc(var(--cloud-thumb-size) * 0.35);
    color: var(--bs-secondary-color, #6c757d);
}

.cloud-thumb-ext {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--bs-secondary-color, #6c757d);
}

.cloud-thumb-name {
    margin-top: 0.4rem;
    font-size: 0.8rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cloud-thumb-actions {
    margin-top: 0.35rem;
    display: flex;
    justify-content: center;
    gap: 0.25rem;
}

/* Lightbox (cloud.php): Bild bewusst nicht ueber das Bootstrap-modal-body-Padding hinaus begrenzt -
   max-height ueber Viewport-Hoehe abzueglich Platz fuer Kopfzeile, damit auch Hochformat-Bilder auf
   kleinen Bildschirmen vollstaendig sichtbar bleiben. */
.cloud-lightbox-content {
    background-color: rgba(0, 0, 0, 0.92);
}

.cloud-lightbox-content .modal-header {
    border-bottom: none;
}

.cloud-lightbox-content #cloudLightboxTitle {
    color: #fff;
}

.cloud-lightbox-body {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.5rem;
}

.cloud-lightbox-body img {
    max-width: 100%;
    max-height: 80vh;
    object-fit: contain;
}

.cloud-lightbox-body #cloudLightboxPdf {
    width: 100%;
    height: 80vh;
    border: none;
    background-color: #fff;
}

.cloud-lightbox-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 1;
    opacity: 0.85;
}

.cloud-lightbox-prev {
    left: 0.75rem;
}

.cloud-lightbox-next {
    right: 0.75rem;
}

/* Einklappbarer Karten-Pfeil (Rechnungslauf-Seiten): nur der kleine Pfeil-Button rechts in der
   Kartenüberschrift ist klickbar, nicht der gesamte Header - im Unterschied zum Bootstrap
   .accordion-button-Muster (siehe z. B. profile.php), das den ganzen Header als Toggle nutzt. */
.card-collapse-toggle {
    border: none;
    background: none;
    padding: 0.15rem 0.3rem;
    line-height: 1;
    color: var(--bs-secondary-color, #6c757d);
}

.card-collapse-toggle:hover {
    color: var(--bs-body-color);
}

.card-collapse-icon {
    display: inline-block;
    transition: transform 0.2s ease;
}

.card-collapse-toggle.collapsed .card-collapse-icon {
    transform: rotate(-90deg);
}

/* Bücherverzeichnis: Cover-Vorschau in Katalog und Detailseite */
.book-cover {
    width: 80px;
    height: 120px;
    object-fit: cover;
    border-radius: 0.25rem;
    border: 1px solid var(--bs-border-color, #dee2e6);
    background-color: var(--bs-tertiary-bg, #f1f3f5);
}

.book-cover-lg {
    width: 180px;
    height: 270px;
}

.book-cover-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2rem;
    color: var(--bs-secondary-color, #6c757d);
}

.book-cover-lg.book-cover-placeholder {
    font-size: 4rem;
}

.min-w-0 {
    min-width: 0;
}

/* Basar: Kartenraster, Detail-Galerie */
.basar-card {
    overflow: hidden;
}

.basar-thumb {
    position: relative;
    aspect-ratio: 4 / 3;
    background-color: var(--bs-tertiary-bg, #f1f3f5);
}

.basar-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.basar-thumb-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2.5rem;
    color: var(--bs-secondary-color, #6c757d);
}

.basar-thumb-badge {
    position: absolute;
    top: 0.5rem;
    left: 0.5rem;
}

.basar-gallery-main {
    aspect-ratio: 4 / 3;
    background-color: var(--bs-tertiary-bg, #f1f3f5);
    border-radius: 0.375rem;
    overflow: hidden;
}

.basar-gallery-main img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

.basar-gallery-thumb {
    width: 72px;
    height: 54px;
    padding: 0;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.25rem;
    overflow: hidden;
    background: none;
}

.basar-gallery-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.basar-form-photo {
    width: 110px;
    height: 82px;
    object-fit: cover;
    border-radius: 0.25rem;
    border: 1px solid var(--bs-border-color, #dee2e6);
}

/* Schnellzugriff-Kacheln der Startseite: so viele Kacheln nebeneinander, wie in die (per "Anpassen"
   gewaehlte) Blockbreite passen - erst wenn der Block zu schmal wird, rutschen sie untereinander. */
.quick-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(104px, 1fr));
    gap: 0.75rem;
}
.quick-tile-label {
    font-size: 0.85rem;
    overflow-wrap: anywhere;
}

/* Anmeldebildschirm der installierten App (login.php, is_app_mode()): kein Hintergrundbild, sondern eine
   ruhige Farbflaeche in den Markenfarben mit dem Logo, darunter ein abgerundetes "Blatt" mit dem Formular.
   Farben kommen aus den Marken-Variablen (Einstellungen -> Darstellung -> Farben), Hell-/Dunkelmodus ueber
   die Bootstrap-Variablen. */
/* Vollflaechig ueber dem normalen Seitenrahmen (position: fixed) - die rechtlichen Links stehen deshalb im Blatt selbst. */
.app-login {
    position: fixed;
    inset: 0;
    z-index: 1000;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    background:
        radial-gradient(circle at 88% 6%, rgba(255, 255, 255, 0.16) 0, rgba(255, 255, 255, 0) 42%),
        radial-gradient(circle at 4% 34%, rgba(255, 255, 255, 0.08) 0, rgba(255, 255, 255, 0) 38%),
        linear-gradient(165deg, var(--brand-primary) 0%, var(--brand-accent) 100%);
}

.app-login-hero {
    flex: 0 0 auto;
    padding: calc(2.25rem + env(safe-area-inset-top, 0px)) 1.5rem 2.5rem;
    text-align: center;
    color: #fff;
}

.app-login-logo {
    width: 92px;
    height: 92px;
    margin: 0 auto 1.25rem;
    padding: 12px;
    border-radius: 28px;
    background: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.28);
    color: var(--brand-accent);
    font-size: 2.75rem;
}

.app-login-logo img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.app-login-hero h1 {
    margin: 0;
    font-size: 1.65rem;
    font-weight: 700;
    letter-spacing: -0.01em;
}

.app-login-hero p {
    margin: 0.35rem 0 0;
    opacity: 0.85;
}

.app-login-sheet {
    flex: 1 1 auto;
    background: var(--bs-body-bg);
    border-radius: 30px 30px 0 0;
    padding: 2rem 1.5rem calc(1.75rem + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -10px 34px rgba(0, 0, 0, 0.18);
}

.app-login-inner {
    max-width: 420px;
    margin: 0 auto;
}

.app-login-field .input-group-text,
.app-login-field .form-control,
.app-login-field .app-login-eye {
    background-color: var(--bs-tertiary-bg);
    border: 1px solid transparent;
}

.app-login-field .input-group-text {
    border-radius: 16px 0 0 16px;
    color: var(--bs-secondary-color);
    padding-left: 1rem;
}

.app-login-field .form-control {
    border-radius: 0 16px 16px 0;
    box-shadow: none;
}

.app-login-field .form-control:focus {
    border-color: var(--brand-accent);
    background-color: var(--bs-body-bg);
}

.app-login-field:focus-within .input-group-text,
.app-login-field:focus-within .app-login-eye {
    color: var(--brand-accent);
}

/* Auge-Schaltflaeche rechts im Passwortfeld: die Rundung wandert an die rechte Seite */
.app-login-field .app-login-eye {
    border-radius: 0 16px 16px 0;
    color: var(--bs-secondary-color);
}

.app-login-field .app-login-eye + .form-control,
.app-login-field:has(.app-login-eye) .form-control {
    border-radius: 0;
}

.app-login-submit {
    border-radius: 16px;
    padding: 0.85rem 1rem;
    font-weight: 600;
}

.app-login-bio {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    padding: 1rem;
    border: 1px solid rgba(var(--brand-primary-rgb), 0.18);
    border-radius: 16px;
    background: rgba(var(--brand-primary-rgb), 0.07);
    color: var(--bs-body-color);
    font-weight: 600;
    font-size: 1.05rem;
}

.app-login-bio i {
    font-size: 1.75rem;
    color: var(--brand-accent);
}

.app-login-bio:disabled {
    opacity: 0.6;
}

[data-bs-theme="dark"] .app-login-bio {
    border-color: rgba(255, 255, 255, 0.18);
    background: rgba(255, 255, 255, 0.07);
}

.app-login-legal {
    margin-top: 1.5rem;
    text-align: center;
    font-size: 0.8rem;
    color: var(--bs-secondary-color);
}

.app-login-legal a {
    color: inherit;
}

.app-login-divider {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 1.5rem 0;
    color: var(--bs-secondary-color);
    font-size: 0.85rem;
}

.app-login-divider::before,
.app-login-divider::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: var(--bs-border-color);
}

/* Sortierbare Tabellenkoepfe (Benutzerverwaltung) */
th.sortable {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}
th.sortable:hover {
    text-decoration: underline;
}

/* Dienstplan: Zelle mit Regelverstoss (Ruhezeit, Urlaub/Krank, Schichtlaenge) */
.shift-planning-table .shift-cell-btn.shift-rule-violation {
    border: 2px solid #dc3545 !important;
}

/* Aufklapp-Menue in einer scrollbaren Tabelle bzw. Karte darf nicht am unteren Rand abgeschnitten werden (z. B.
   "⋮"-Aktionen beim letzten/einzigen Eintrag einer Liste) - siehe unobtrusive-events.js
   (show.bs.dropdown/hidden.bs.dropdown). Gilt fuer .table-responsive (overflow-x: auto) UND .card (overflow:
   hidden, siehe oben), da ein Dropdown haeufig in einer Tabelle innerhalb einer Karte steckt. */
.table-responsive.dropdown-open-overflow-visible,
.card.dropdown-open-overflow-visible {
    overflow: visible;
}

/* Anpassbares Raster (siehe includes/dashboard_blocks.php: render_dashboard_grid(), assets/js/dashboard-grid.js):
   echtes CSS-Grid statt Bootstrap-Zeilenfluss, Bloecke lassen sich direkt verschieben und in Breite/Hoehe
   veraendern und werden automatisch gespeichert. --dashboard-row-h ist die Hoehe EINER Rasterzeile in Pixeln;
   ein Block "span H" ist deshalb IMMER exakt H * --dashboard-row-h + (H-1) * Zwischenraum hoch (keine
   automatische Anpassung an den Inhalt) - passt der Inhalt nicht hinein, scrollt NUR der Block selbst
   (.dashboard-grid-item-surface). Griffe: gepunktetes Eck links oben = verschieben, schraffiertes Eck rechts
   unten = Groesse, ✕ rechts oben = ausblenden. */
.dashboard-grid {
    --dashboard-row-h: 64px;
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    grid-auto-rows: var(--dashboard-row-h);
    /* Bewusst NICHT "dense": sparse haelt neu verschobene Bloecke naeher an ihrer abgelegten Position in der
       Dokumentreihenfolge, statt wie "dense" aggressiv fruehere Luecken mit spaeteren, kleineren Bloecken
       aufzufuellen (wuerde sich beim Ziehen unerwartet anfuehlen). */
    grid-auto-flow: row;
    gap: 1rem;
}

/* Freie Positionen (v1.210.0, siehe dashboard-grid.js): Bloecke mit gespeicherter Rasterposition stehen fest (grid-column/
   grid-row "X / span B"); Bloecke ohne Position (z. B. neu hinzugekommene) fuellen mit "dense" die freien Luecken. */
.dashboard-grid.dashboard-grid-positioned {
    grid-auto-flow: row dense;
}

/* Folgt dem Raster direkt eine eigene Karte (Dashboard "Meine Zeiten", Dienstplanung), bekommt sie denselben
   Abstand wie die Bloecke untereinander (= gap des Rasters). */
.dashboard-grid + .card {
    margin-top: 1rem;
}

.dashboard-grid-item {
    position: relative;
    min-width: 0;
    border-radius: var(--bs-border-radius);
    transition: box-shadow 0.2s ease, transform 0.2s ease, opacity 0.2s ease;
}

/* Bearbeitungsmodus (Dropdown "Blöcke" -> "Bearbeiten"): nur dann sind Griffe und ✕ sichtbar; die Bloecke
   bekommen einen dezenten Rahmen in der eingestellten Akzentfarbe (--brand-accent), beim Darueberfahren
   kraeftiger. Ausserhalb des Bearbeitungsmodus bleibt die Seite voellig ruhig. */
.dashboard-grid-editing .dashboard-grid-item {
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--brand-accent) 35%, transparent);
}

.dashboard-grid-editing .dashboard-grid-item:hover {
    box-shadow: 0 0 0 2px var(--brand-accent);
}

.dashboard-grid-item.dashboard-grid-item-hidden {
    display: none;
}

.dashboard-grid-item.dashboard-grid-item-dragging {
    z-index: 20;
    opacity: 0.92;
    transform: scale(1.015);
    box-shadow: 0 1.25rem 2.5rem rgba(0, 0, 0, 0.25), 0 0 0 2px var(--brand-accent);
}

.dashboard-grid-item.dashboard-grid-item-resizing {
    box-shadow: 0 0 0 2px var(--brand-accent);
}

.dashboard-grid-item.dashboard-grid-item-revealed {
    animation: dashboard-grid-reveal 1.4s ease-out;
}

@keyframes dashboard-grid-reveal {
    0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--brand-accent) 70%, transparent); }
    60%  { box-shadow: 0 0 0 0.6rem color-mix(in srgb, var(--brand-accent) 0%, transparent); }
    100% { box-shadow: 0 0 0 0 transparent; }
}

.dashboard-grid-item-surface {
    height: 100%;
    overflow-y: auto;
    border-radius: inherit;
    scrollbar-width: thin;
}

/* Einklappbare Bloecke der Dienstplanung (Filter, Dienste; v1.243.0): eingeklappt zeigt die Karte nur ihre Kopfzeile, und der Rasterblock
   schrumpft auf eine Zeile (nur ausserhalb des Anpassen-Modus), damit die folgenden Bloecke nachruecken. */
.shift-collapsible.is-collapsed .shift-collapsible-body {
    display: none;
}
.shift-collapsible .shift-collapse-arrow {
    display: inline-block;
    transition: transform 0.15s ease;
    font-size: 1.05rem;
    line-height: 1;
}
.shift-collapsible.is-collapsed .shift-collapse-arrow {
    transform: rotate(-90deg);
}
/* Block mit gespeicherter Position ("grid-row: Y / span H"): nur das Ende auf eine Zeile setzen. */
.dashboard-grid:not(.dashboard-grid-editing) .dashboard-grid-item:has(> .dashboard-grid-item-surface > .shift-collapsible.is-collapsed) {
    grid-row-end: span 1 !important;
}
/* Block ohne Position ("grid-row: span H"): die Hoehe steckt im Start, daher ganz auf eine Zeile setzen. */
.dashboard-grid:not(.dashboard-grid-editing) .dashboard-grid-item[style*="grid-row: span"]:has(> .dashboard-grid-item-surface > .shift-collapsible.is-collapsed) {
    grid-row-start: span 1 !important;
    grid-row-end: auto !important;
}

/* Karten mit h-100 wachsen mit ihrem Inhalt (statt ihn am unteren Rand ueberstehen zu lassen); der Block selbst scrollt dann (v1.242.0). */
.dashboard-grid-item-surface > .card.h-100 {
    height: auto !important;
    min-height: 100%;
}

/* Platz fuer das ✕ rechts oben, damit es keine Kopfzeilen-Links (z. B. "Alle anzeigen") verdeckt (nur beim Bearbeiten). */
.dashboard-grid-editing .dashboard-grid-item .card-header {
    padding-right: 2.75rem;
}

/* Gepunktetes Eck links oben: Griff zum Verschieben. */
.dashboard-grid-handle {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 5;
    width: 28px;
    height: 28px;
    border-top-left-radius: var(--bs-border-radius);
    color: var(--bs-secondary-color);
    background:
        radial-gradient(circle, currentColor 1.1px, transparent 1.5px) 4px 4px / 6px 6px,
        var(--bs-tertiary-bg);
    clip-path: polygon(0 0, 100% 0, 0 100%);
    cursor: grab;
    touch-action: none;
    user-select: none;
    transition: opacity 0.15s ease, color 0.15s ease;
}

/* Schraffiertes Eck rechts unten: Griff zur Groessenaenderung. */
.dashboard-grid-resize {
    position: absolute;
    right: 0;
    bottom: 0;
    z-index: 5;
    width: 28px;
    height: 28px;
    border-bottom-right-radius: var(--bs-border-radius);
    color: var(--bs-secondary-color);
    background:
        repeating-linear-gradient(135deg, currentColor 0 1.5px, transparent 1.5px 5px),
        var(--bs-tertiary-bg);
    clip-path: polygon(100% 0, 100% 100%, 0 100%);
    cursor: nwse-resize;
    touch-action: none;
    user-select: none;
    transition: opacity 0.15s ease, color 0.15s ease;
}

.dashboard-grid-handle:hover,
.dashboard-grid-resize:hover,
.dashboard-grid-item-dragging .dashboard-grid-handle,
.dashboard-grid-item-resizing .dashboard-grid-resize {
    color: var(--brand-accent);
}

.dashboard-grid-handle:active {
    cursor: grabbing;
}

/* Tastatur-Fokus: die Eckgriffe sind per clip-path beschnitten (ein Fokus-Rahmen waere dort unsichtbar) - darum Akzentfarbe, groesseres Eck
   und ein deutlicher Rahmen um den ganzen Block. */
.dashboard-grid-handle:focus,
.dashboard-grid-resize:focus {
    outline: none;
}

.dashboard-grid-handle:focus-visible,
.dashboard-grid-resize:focus-visible {
    width: 40px;
    height: 40px;
    color: var(--brand-accent);
}

.dashboard-grid-editing .dashboard-grid-item:has(:focus-visible) {
    box-shadow: 0 0 0 3px var(--brand-accent);
}

/* ✕ rechts oben: Block ausblenden (Wiedereinblenden ueber das "Bloecke"-Dropdown in der Kopfzeile). */
.dashboard-grid-hide {
    position: absolute;
    top: 0.4rem;
    right: 0.4rem;
    z-index: 5;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 1px solid var(--bs-border-color);
    border-radius: 50%;
    background: var(--bs-body-bg);
    color: var(--bs-secondary-color);
    font-size: 0.7rem;
    line-height: 1;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
    transition: opacity 0.15s ease, color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}

.dashboard-grid-hide:hover,
.dashboard-grid-hide:focus-visible {
    background: var(--bs-danger);
    border-color: var(--bs-danger);
    color: #fff;
}

/* Griffe und ✕ gibt es nur im Bearbeitungsmodus. */
.dashboard-grid-handle,
.dashboard-grid-resize,
.dashboard-grid-hide {
    display: none;
}

.dashboard-grid-editing .dashboard-grid-handle,
.dashboard-grid-editing .dashboard-grid-resize {
    display: block;
}

.dashboard-grid-editing .dashboard-grid-hide {
    display: inline-flex;
}

/* Waehrend des Ziehens/Skalierens: durchgehender Cursor und keine Textmarkierung auf der ganzen Seite. */
body.dashboard-grid-busy-drag,
body.dashboard-grid-busy-drag * {
    cursor: grabbing !important;
    user-select: none !important;
}

body.dashboard-grid-busy-resize,
body.dashboard-grid-busy-resize * {
    cursor: nwse-resize !important;
    user-select: none !important;
}

/* Kleine Rueckmeldung unten rechts: "Gespeichert" bzw. Fehlermeldung beim automatischen Speichern. */
.dashboard-grid-toast {
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    z-index: 1080;
    max-width: min(24rem, calc(100vw - 2rem));
    padding: 0.5rem 0.9rem;
    border-radius: 2rem;
    background: var(--bs-emphasis-color);
    color: var(--bs-body-bg);
    font-size: 0.85rem;
    box-shadow: 0 0.5rem 1.25rem rgba(0, 0, 0, 0.25);
    opacity: 0;
    transform: translateY(0.5rem);
    pointer-events: none;
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.dashboard-grid-toast.dashboard-grid-toast-visible {
    opacity: 1;
    transform: translateY(0);
}

.dashboard-grid-toast.dashboard-grid-toast-error {
    background: var(--bs-danger);
    color: #fff;
    border-radius: 0.75rem;
}

.dashboard-hidden-count {
    font-size: 0.65rem;
    vertical-align: middle;
    background-color: var(--brand-accent);
    color: #fff;
}

/* Bearbeitungsmodus aktiv: der Knopf "Bloecke" in der Kopfzeile zeigt es in der Akzentfarbe. */
.topbar-icon-link.dashboard-edit-on {
    border-color: var(--brand-accent);
    color: var(--brand-accent);
}

@media (prefers-reduced-motion: reduce) {
    .dashboard-grid-item,
    .dashboard-grid-handle,
    .dashboard-grid-resize,
    .dashboard-grid-hide,
    .dashboard-grid-toast {
        transition: none;
    }
    .dashboard-grid-item.dashboard-grid-item-revealed {
        animation: none;
    }
}

/* Auf schmalen Bildschirmen stehen die Bereiche immer in voller Breite untereinander (siehe help.php) -
   Verschieben/Groesse aendern/Ausblenden ist dort nicht verfuegbar (Touch-Drag auf einer einspaltigen Liste
   bringt keinen Mehrwert und die Griffe wuerden nur Platz wegnehmen). */
@media (max-width: 767.98px) {
    .dashboard-grid {
        grid-template-columns: 1fr;
        grid-auto-rows: auto;
    }
    .dashboard-grid-item {
        grid-column: 1 / -1 !important;
        grid-row: auto !important;
    }
    .dashboard-grid-item-surface {
        overflow-y: visible;
        height: auto;
    }
    .dashboard-grid-handle,
    .dashboard-grid-resize,
    .dashboard-grid-hide,
    .dashboard-grid-editing .dashboard-grid-handle,
    .dashboard-grid-editing .dashboard-grid-resize,
    .dashboard-grid-editing .dashboard-grid-hide {
        display: none;
    }
    .dashboard-grid-editing .dashboard-grid-item .card-header {
        padding-right: 1rem;
    }
}

/* Chat-Fenster (v1.196.0, includes/chat_widget.php + assets/js/chat-widget.js): schwebendes Popup rechts unten auf jeder Seite
   fuer angemeldete Nutzer. Drei Zustaende: nur runder Knopf (.chat-widget-launcher), Fenster mit Nachrichten, minimiert
   (.is-minimized, nur Kopfleiste). Die Nachrichten selbst sind nachrichten.php?popup=1 im iframe (Layout dort: .chat-embed-*
   weiter unten). z-index unter den Bootstrap-Modals (1055) und -Offcanvas (1045), ueber Sticky-Leisten (1020-1030). */
.chat-widget {
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    z-index: 1035;
}

.chat-widget-launcher {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3.5rem;
    height: 3.5rem;
    border: none;
    border-radius: 50%;
    background: var(--brand-accent, var(--bs-primary));
    color: #fff;
    font-size: 1.5rem;
    box-shadow: 0 0.35rem 1rem rgba(0, 0, 0, 0.3);
    cursor: pointer;
    transition: transform 0.15s ease;
}

.chat-widget-launcher[hidden],
.chat-widget-panel[hidden],
.chat-widget [data-chat-unread-badge][hidden] {
    display: none;
}

.chat-widget-launcher:hover {
    transform: scale(1.06);
}

.chat-widget-launcher .badge {
    position: absolute;
    top: -0.25rem;
    right: -0.25rem;
    font-size: 0.7rem;
}

.chat-widget-panel {
    display: flex;
    flex-direction: column;
    width: 24rem;
    max-width: calc(100vw - 2rem);
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 0.75rem;
    box-shadow: 0 0.6rem 2rem rgba(0, 0, 0, 0.3);
    overflow: hidden;
}

.chat-widget-panel.is-minimized {
    width: 17.5rem;
}

.chat-widget-header {
    display: flex;
    align-items: center;
    gap: 0.15rem;
    padding: 0.35rem 0.4rem 0.35rem 0.5rem;
    background: var(--brand-primary, var(--bs-primary));
    color: #fff;
}

.chat-widget-title {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    padding: 0.3rem 0.35rem;
    border: none;
    border-radius: 0.4rem;
    background: transparent;
    color: inherit;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}

.chat-widget-title:hover,
.chat-widget-iconbtn:hover {
    background: rgba(255, 255, 255, 0.18);
}

.chat-widget-iconbtn {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border: none;
    border-radius: 0.4rem;
    background: transparent;
    color: #fff;
    text-decoration: none;
    cursor: pointer;
}

.chat-widget-title:focus-visible,
.chat-widget-iconbtn:focus-visible,
.chat-widget-launcher:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
    box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.35);
}

.chat-widget-body {
    height: min(34rem, calc(100vh - 7rem));
    background: var(--bs-body-bg);
}

.chat-widget-body iframe {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
}

.chat-widget-panel.is-minimized .chat-widget-body {
    display: none;
}

/* Kachel-Menue auf dem Smartphone: die feste Tab-Leiste unten (tiles.css) darf nicht ueberdeckt werden. */
@media (max-width: 991.98px) {
    html[data-menu="tiles"] .chat-widget {
        bottom: calc(var(--tile-tabbar-height, 3.75rem) + 0.75rem + env(safe-area-inset-bottom, 0px));
    }
}

@media (max-width: 575.98px) {
    .chat-widget {
        right: 0.5rem;
        bottom: 0.5rem;
    }
    .chat-widget-panel {
        width: calc(100vw - 1rem);
        max-width: none;
    }
    .chat-widget-panel.is-minimized {
        width: 14rem;
    }
    .chat-widget-body {
        height: min(34rem, calc(100vh - 5rem));
    }
}

/* Der Hinweis "Gespeichert" des Rasters (.dashboard-grid-toast) liegt sonst genau auf dem Chat-Knopf. */
body:has(.chat-widget) .dashboard-grid-toast {
    bottom: 5.5rem;
}

@media (prefers-reduced-motion: reduce) {
    .chat-widget-launcher {
        transition: none;
    }
}

/* Chat-Ansicht im Fenster (nachrichten.php?popup=1, iframe, includes/chat_embed.php): fuellt die ganze Hoehe; Unterhaltungsliste
   ODER Unterhaltung (die schmale Breite loest die Mobil-Ansicht des Chats aus, siehe .chat-conversation-active oben). */
body.chat-embed-body {
    height: 100vh;
    margin: 0;
    padding: 0;
    overflow: hidden;
    background: var(--bs-body-bg);
}

.chat-embed-root {
    display: flex;
    flex-direction: column;
    height: 100vh;
    padding: 0.5rem;
}

.chat-embed-root > .chat-layout {
    flex: 1 1 auto;
    height: auto;
    min-height: 0;
}

.chat-embed-root > .d-flex.mb-3 {
    margin-bottom: 0.5rem !important;
}

.chat-embed-root .chat-layout .card {
    border-radius: 0.5rem;
}

/* Fenster-Ansicht: die Bootstrap-Zeile umbricht und liess die Spalte mit dem Inhalt wachsen (Eingabeleiste ragte unten aus dem
   Fenster) - ohne Umbruch und ohne Zeilenabstand bleibt die Spalte so hoch wie das Fenster, die Nachrichten scrollen intern. */
.chat-embed-root > .chat-layout {
    --bs-gutter-y: 0;
    margin-top: 0;
    flex-wrap: nowrap;
}

.chat-embed-root > .chat-layout > * {
    min-height: 0;
    margin-top: 0;
}

/* Eingabefeld im Chat-Fenster (assets/js/rich-text.js, Chat-Modus): ohne Formatierungsleiste, mit Smiley-Auswahl. Der Knopf sitzt
   unten rechts im Feld, die Auswahl klappt nach oben auf. */
.chat-editor-wrap {
    position: relative;
}

.chat-editor-wrap .ql-container.ql-snow {
    border-radius: var(--bs-border-radius);
    border-color: var(--bs-border-color);
    font-family: inherit;
}

.chat-editor-wrap .ql-editor {
    padding-right: 2.75rem;
}

.chat-emoji-toggle {
    position: absolute;
    right: 0.4rem;
    bottom: 0.35rem;
    z-index: 2;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
}

.chat-emoji-toggle:hover,
.chat-emoji-toggle[aria-expanded="true"] {
    background: var(--bs-secondary-bg);
}

.chat-emoji-toggle:focus-visible,
.chat-emoji-item:focus-visible {
    outline: 2px solid var(--brand-accent, var(--bs-primary));
    outline-offset: 1px;
}

.chat-emoji-panel {
    position: absolute;
    right: 0;
    bottom: calc(100% + 0.25rem);
    z-index: 5;
    width: min(19rem, 100%);
    max-height: 12rem;
    padding: 0.4rem 0.5rem 0.5rem;
    overflow-y: auto;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.6rem;
    background: var(--bs-body-bg);
    box-shadow: 0 0.4rem 1.2rem rgba(0, 0, 0, 0.25);
}

.chat-emoji-panel[hidden] {
    display: none;
}

.chat-emoji-heading {
    margin: 0.25rem 0 0.1rem;
    color: var(--bs-secondary-color);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
}

.chat-emoji-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(2rem, 1fr));
    gap: 0.1rem;
}

.chat-emoji-item {
    height: 2rem;
    padding: 0;
    border: none;
    border-radius: 0.4rem;
    background: transparent;
    font-size: 1.2rem;
    line-height: 1;
    cursor: pointer;
}

.chat-emoji-item:hover {
    background: var(--bs-secondary-bg);
}

/* Mitgliedschafts-Block auf der Startseite (eltern/portal.php, eltern/mitgliedschaft.php): angefragt orange, aktiv gruen, abgelehnt rot. */
.membership-state-requested { color: #d9730d; }
.membership-state-active { color: var(--bs-success); }
.membership-state-rejected { color: var(--bs-danger); }
[data-bs-theme="dark"] .membership-state-requested { color: #f0902f; }

/* Anhang per Bueroklammer (assets/js/rich-text.js): im Chat-Fenster links neben dem Smiley-Knopf, sonst am Ende der Formatierungsleiste. */
.chat-editor-wrap.has-attach .ql-editor {
    padding-right: 5rem;
}

.chat-attach-toggle {
    position: absolute;
    right: 2.5rem;
    bottom: 0.35rem;
    z-index: 2;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--bs-body-color);
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
}

.chat-attach-toggle:hover,
.chat-attach-toggle[aria-expanded="true"] {
    background: var(--bs-secondary-bg);
}

.chat-attach-toggle:focus-visible {
    outline: 2px solid var(--brand-accent, var(--bs-primary));
    outline-offset: 1px;
}

.chat-attach-toggle.has-file,
.chat-attach-toolbar-button.has-file {
    color: var(--brand-accent, var(--bs-primary));
}

.chat-attach-toolbar-button i {
    pointer-events: none;
}

.chat-attachment-field[hidden],
[data-signature-option][hidden] {
    display: none !important;
}

.chat-mute-button {
    line-height: 1;
    padding: 0.3rem 0.5rem;
}

.chat-bubble-avatar {
    flex: 0 0 auto;
    align-self: flex-end;
    margin: 0 0.5rem 0.25rem 0;
}

.chat-bubble-row-own .chat-bubble-avatar {
    order: 2;
    margin: 0 0 0.25rem 0.5rem;
}

/* Kachel-Uebersicht der Kommunikation (v1.277.0): alle Unterpunkte des Menues als Kacheln mit Symbol und Beschriftung. */
.comm-tile {
    min-height: 7.5rem;
    transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.comm-tile:hover,
.comm-tile:focus-visible {
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.12) !important;
    transform: translateY(-2px);
}

.comm-tile-icon {
    font-size: 2rem;
    line-height: 1;
    color: var(--brand-primary);
}

[data-bs-theme="dark"] .comm-tile-icon {
    color: #f5f5f5;
}

.comm-tile-badge {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
}

.chat-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    padding: 0;
    font-size: 1.1rem;
}

/* Kanaele (v1.276.0): zuklappbarer Abschnitt, Summe neuer Nachrichten nur im zugeklappten Zustand */
#channelsSectionToggle:not(.collapsed) .channels-total-unread {
    display: none;
}

#channelsSectionToggle .channels-chevron {
    transition: transform 0.15s ease;
}

#channelsSectionToggle.collapsed .channels-chevron {
    transform: rotate(-90deg);
}

/* Textbausteine (nachrichten.php): Bereich per Symbol links neben "Senden" ein-/ausblenden. */
.chat-snippet-bar[hidden] {
    display: none !important;
}

.chat-actions-menu .dropdown-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.chat-snippet-toggle {
    /* gleiche Hoehe wie "Senden" (Standard-Button: Zeilenhoehe 1,5 + Innenabstand + Rahmen), Symbol mittig */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.75rem;
    height: calc(1.5 * 1rem + 0.75rem + 2px);
}

/* Cloud: sortierbare Spaltenkoepfe (Ordner-/Dateitabelle). Kleine Hoch-/Runter-Pfeile, aktive Spalte voll sichtbar. */
.cloud-sort-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    cursor: pointer;
    text-align: left;
}

.cloud-sort-btn:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

.cloud-sort-icon {
    font-size: 0.7em;
    opacity: 0.5;
}

th[aria-sort="ascending"] .cloud-sort-icon,
th[aria-sort="descending"] .cloud-sort-icon {
    opacity: 1;
}

/* Startseite: Titelbild-Block - das Bild fuellt den Block in Breite UND Hoehe aus (object-fit: cover), egal wie gross der Block im Raster ist.
   Vorher begrenzte eine feste Maximalhoehe das Bild, sodass bei hoeheren Bloecken ein leerer Streifen blieb. */
.startseite-titelbild {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
}

/* Die Karte des Titelbilds hat feste Blockhoehe (die allgemeine Regel ".card.h-100 waechst mit dem Inhalt" gilt hier nicht) - sonst bestimmte die
   Bildhoehe die Kartenhoehe und der Block musste gescrollt werden. Das Bild liegt absolut in der Karte und wird zugeschnitten (cover). */
.dashboard-grid-item-surface > .card.startseite-titelbild-card {
    position: relative;
    height: 100% !important;
    min-height: 0;
}
.startseite-titelbild-card .startseite-titelbild {
    position: absolute;
    inset: 0;
}
/* Schmale Bildschirme: Bloecke stehen untereinander ohne feste Hoehe - dort bestimmt das Bild (mit Obergrenze) die Hoehe. */
@media (max-width: 767.98px) {
    .dashboard-grid-item-surface > .card.startseite-titelbild-card {
        height: auto !important;
    }
    .startseite-titelbild-card .startseite-titelbild {
        position: static;
        height: auto;
        max-height: 16rem;
    }
}

/* Ampel fuer Plus-/Minusstunden (includes/traffic_light.php): Punkt vor dem Mitarbeiter und Saldo in der Ampelfarbe. Die Farbe steht nie
   allein - der Punkt hat eine Textalternative (aria-label/title). Der Text bekommt kraeftigere Toene als der Punkt, damit er auf hellem
   und dunklem Grund lesbar bleibt (Gelb als Schriftfarbe waere sonst kaum zu erkennen). */
.traffic-light-dot {
    display: inline-block;
    width: 0.8rem;
    height: 0.8rem;
    margin-right: 0.45rem;
    border-radius: 50%;
    vertical-align: middle;
    flex: none;
}

.traffic-light-dot.traffic-light-green {
    background-color: #198754;
    box-shadow: 0 0 0 0.18rem rgba(25, 135, 84, 0.25);
}

.traffic-light-dot.traffic-light-yellow {
    background-color: #ffc107;
    box-shadow: 0 0 0 0.18rem rgba(255, 193, 7, 0.35);
}

.traffic-light-dot.traffic-light-red {
    background-color: #dc3545;
    box-shadow: 0 0 0 0.18rem rgba(220, 53, 69, 0.3);
}

.traffic-light-text.traffic-light-green { color: #146c43; font-weight: 600; }
.traffic-light-text.traffic-light-yellow { color: #8a6500; font-weight: 600; }
.traffic-light-text.traffic-light-red { color: #b02a37; font-weight: 600; }

[data-bs-theme="dark"] .traffic-light-text.traffic-light-green { color: #75b798; }
[data-bs-theme="dark"] .traffic-light-text.traffic-light-yellow { color: #ffda6a; }
[data-bs-theme="dark"] .traffic-light-text.traffic-light-red { color: #ea868f; }

/* Reaktionen auf Nachrichten (v1.249.0) */
.chat-reactions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem;
    margin-top: 0.25rem;
}

.chat-reaction {
    background: var(--bs-body-bg, #fff);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 999px;
    color: var(--bs-body-color, #212529);
    font-size: 0.8rem;
    line-height: 1.2;
    padding: 0.05rem 0.45rem;
}

.chat-reaction.is-mine {
    border-color: var(--bs-primary, #0d6efd);
    background: var(--bs-primary-bg-subtle, #cfe2ff);
}

.chat-reaction-add {
    opacity: 0.6;
}

.chat-reaction-add:hover,
.chat-reaction-add:focus-visible {
    opacity: 1;
}

.chat-reaction-picker {
    display: inline-flex;
    gap: 0.25rem;
}

.chat-reaction-picker[hidden] {
    display: none;
}

/* Umfragen (v1.252.0): eine Frage pro Seite, Fortschrittsbalken, oeffentliche Link-Seite im Portal-Design */
.poll-card {
    background: var(--bs-body-bg, #fff);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 1rem;
    padding: 1.5rem;
    box-shadow: 0 0.25rem 1rem rgba(0, 0, 0, 0.06);
}

.poll-progress {
    height: 0.6rem;
    border-radius: 999px;
}

.poll-question {
    font-size: 1.25rem;
    font-weight: 600;
    line-height: 1.35;
    margin-bottom: 1rem;
}

.poll-options {
    display: grid;
    gap: 0.6rem;
}

.poll-option {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.85rem 1rem;
    border: 2px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.75rem;
    cursor: pointer;
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

.poll-option:hover {
    border-color: var(--brand-primary, #0d6efd);
}

.poll-option.is-selected,
.poll-option:has(input:checked) {
    border-color: var(--brand-primary, #0d6efd);
    background: var(--bs-primary-bg-subtle, rgba(13, 110, 253, 0.08));
}

.poll-option input {
    flex: 0 0 auto;
    width: 1.25rem;
    height: 1.25rem;
    margin: 0;
}

.poll-done-icon {
    font-size: 3rem;
    color: var(--brand-primary, #0d6efd);
    line-height: 1;
    margin-bottom: 0.75rem;
}

.poll-public {
    max-width: 760px;
    margin: 1rem auto 2rem;
}

.poll-public-hero {
    text-align: center;
    color: #fff;
    padding: 2rem 1.5rem 3.5rem;
    border-radius: 1.5rem;
    background:
        radial-gradient(circle at 88% 8%, rgba(255, 255, 255, 0.18) 0, rgba(255, 255, 255, 0) 45%),
        linear-gradient(160deg, var(--brand-primary, #0d6efd) 0%, var(--brand-accent, #6610f2) 100%);
}

.poll-public-logo {
    width: 84px;
    height: 84px;
    margin: 0 auto 0.9rem;
    padding: 10px;
    border-radius: 24px;
    background: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.25);
    color: var(--brand-accent, #6610f2);
    font-size: 2.4rem;
}

.poll-public-logo img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.poll-public-portal {
    font-size: 0.9rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    opacity: 0.85;
}

.poll-public-hero h1 {
    font-size: 1.7rem;
    font-weight: 700;
    margin: 0.25rem 0 0;
    text-wrap: balance;
}

.poll-public-description {
    margin: 0.75rem auto 0;
    max-width: 34rem;
    opacity: 0.92;
}

.poll-public-body {
    margin: -2.25rem 0.75rem 0;
    position: relative;
}

.poll-public-footer {
    text-align: center;
    font-size: 0.8rem;
    color: var(--bs-secondary-color, #6c757d);
    margin: 1.25rem 0 0;
}

/* Umfragen (v1.254.0): Editor mit Ziehen, Schieberegler, Erlaeuterung */
.poll-drag-handle {
    cursor: grab;
    color: var(--bs-secondary-color, #6c757d);
    font-size: 1.25rem;
    line-height: 1;
    padding: 0.1rem 0.15rem;
}

.poll-drag-handle:active {
    cursor: grabbing;
}

.poll-question-editor.poll-dragging {
    opacity: 0.5;
    outline: 2px dashed var(--brand-primary, #0d6efd);
}

.poll-question-help {
    color: var(--bs-secondary-color, #6c757d);
    margin: -0.5rem 0 1rem;
}

.poll-slider {
    padding: 0.5rem 0.25rem 0;
}

.poll-range {
    height: 2rem;
}

.poll-slider-value {
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--brand-primary, #0d6efd);
    min-width: 4rem;
    text-align: center;
}

.poll-slider-value.is-unset {
    font-size: 0.95rem;
    font-weight: 500;
    color: var(--bs-secondary-color, #6c757d);
}
/* Umfragen v1.256.0: Sterne-Bewertung und Matrix */
.poll-rating {
    position: relative;
    display: inline-flex;
    flex-direction: row-reverse;
    gap: 0.25rem;
}
.poll-rating-input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    pointer-events: none;
}
.poll-rating-star {
    font-size: 2.4rem;
    line-height: 1;
    cursor: pointer;
    color: var(--bs-border-color, #ced4da);
    transition: color 0.12s ease;
}
.poll-rating-input:checked ~ .poll-rating-star,
.poll-rating-star:hover,
.poll-rating-star:hover ~ .poll-rating-star {
    color: #f2b400;
}
.poll-rating-input:focus-visible + .poll-rating-star {
    outline: 2px solid var(--bs-primary, #0d6efd);
    outline-offset: 2px;
    border-radius: 6px;
}
.poll-matrix th,
.poll-matrix td {
    padding: 0.6rem 0.5rem;
}
.poll-matrix td .form-check-input {
    width: 1.25rem;
    height: 1.25rem;
    cursor: pointer;
}

/* Umfragen v1.257.0: NPS-Skala, Rangfolge, Bilder zu Antworten, Diagramme */
.poll-nps {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}
.poll-nps-input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    pointer-events: none;
}
.poll-nps-item {
    min-width: 2.6rem;
    padding: 0.55rem 0.4rem;
    text-align: center;
    border: 1px solid var(--bs-border-color, #ced4da);
    border-radius: 0.5rem;
    cursor: pointer;
    font-weight: 600;
    user-select: none;
}
.poll-nps-item:hover {
    border-color: var(--bs-primary, #0d6efd);
}
.poll-nps-input:checked + .poll-nps-item {
    background: var(--bs-primary, #0d6efd);
    border-color: var(--bs-primary, #0d6efd);
    color: #fff;
}
.poll-nps-input:focus-visible + .poll-nps-item {
    outline: 2px solid var(--bs-primary, #0d6efd);
    outline-offset: 2px;
}
.poll-rank-item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.55rem 0.7rem;
    margin-bottom: 0.4rem;
    border: 1px solid var(--bs-border-color, #ced4da);
    border-radius: 0.5rem;
    background: var(--bs-body-bg, #fff);
    cursor: grab;
}
.poll-rank-item.is-dragging {
    opacity: 0.5;
}
.poll-rank-number {
    min-width: 1.6rem;
    font-weight: 700;
    color: var(--bs-secondary-color, #6c757d);
}
.poll-option.has-image {
    flex-wrap: wrap;
}
.poll-option-image {
    width: 100%;
    max-height: 11rem;
    object-fit: cover;
    border-radius: 0.4rem;
    margin: 0.4rem 0;
}
.poll-donut {
    width: 9rem;
    height: 9rem;
    transform: none;
}
.poll-chart-swatch {
    display: inline-block;
    width: 0.8rem;
    height: 0.8rem;
    border-radius: 2px;
    vertical-align: -1px;
}
.poll-columns {
    width: 100%;
    max-width: 28rem;
    height: auto;
    color: var(--bs-body-color, #212529);
}
.poll-resume summary {
    cursor: pointer;
}

/* "App installieren" (v1.259.0, assets/js/pwa-install.js + includes/footer.php): ein Knopf links unten - in der Seitenleiste,
   wo es eine sichtbare gibt, sonst schwebend (Anmeldeseite, Kachel-Menue auf dem Smartphone). */
.pwa-install[hidden] {
    display: none !important;
}

.pwa-install-in-sidebar {
    flex: 0 0 auto;
    padding: 0.6rem 0.75rem 0.75rem;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.pwa-install-in-sidebar .btn {
    width: 100%;
    text-align: left;
    --bs-btn-color: #fff;
    --bs-btn-border-color: rgba(255, 255, 255, 0.35);
    --bs-btn-hover-bg: var(--brand-sidebar-hover);
    --bs-btn-hover-border-color: rgba(255, 255, 255, 0.6);
    --bs-btn-hover-color: #fff;
    --bs-btn-active-bg: var(--brand-sidebar-active);
    --bs-btn-active-color: #fff;
}

.pwa-install-floating {
    position: fixed;
    left: 0.75rem;
    bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
    z-index: 1025;
}

.pwa-install-floating .btn {
    box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.18);
}

/* Mit sichtbarer Seitenleiste braucht es den schwebenden Knopf nicht. */
html.pwa-has-sidebar .pwa-install-floating {
    display: none;
}

@media (max-width: 991.98px) {
    /* Kachel-Menue: Seitenleiste ist ausgeblendet -> schwebender Knopf ueber der Tab-Leiste. */
    html.pwa-has-sidebar[data-menu="tiles"] .pwa-install-floating {
        display: block;
        bottom: calc(var(--tile-tabbar-height, 3.75rem) + 0.75rem + env(safe-area-inset-bottom, 0px));
    }
}

/* Nachrichten-Komfort (v1.269.0): Zitat-Antwort, Erwaehnung, Merken, Schnellumfrage, Antwortleiste, geplante Nachrichten */
.chat-quote {
    display: block;
    border-left: 3px solid var(--brand-primary, #0d6efd);
    background: rgba(0, 0, 0, 0.06);
    border-radius: 0.25rem;
    padding: 0.15rem 0.5rem;
    margin-bottom: 0.3rem;
    font-size: 0.8rem;
    line-height: 1.25;
    color: inherit;
    text-decoration: none !important;
}

.chat-quote-own {
    border-left-color: #fff;
    background: rgba(255, 255, 255, 0.18);
}

.chat-quote-sender {
    display: block;
    font-weight: 600;
}

.chat-quote-text {
    display: block;
    opacity: 0.85;
}

.chat-mention {
    font-weight: 600;
    background: rgba(255, 193, 7, 0.35);
    border-radius: 0.2rem;
    padding: 0 0.15rem;
}

.chat-bubble-row-own .chat-mention {
    background: rgba(255, 255, 255, 0.25);
}

.chat-bookmark-btn.is-on {
    opacity: 1;
    color: #f0ad00;
}

.chat-bubble-flash .chat-bubble-content {
    outline: 3px solid #f0ad00;
    outline-offset: 1px;
    transition: outline-color 0.4s;
}

.chat-poll {
    margin-top: 0.4rem;
    min-width: 14rem;
}

.chat-poll-option {
    position: relative;
    display: flex;
    justify-content: space-between;
    gap: 0.75rem;
    width: 100%;
    margin-bottom: 0.25rem;
    padding: 0.25rem 0.5rem;
    border: 1px solid rgba(128, 128, 128, 0.45);
    border-radius: 0.35rem;
    background: transparent;
    color: inherit;
    text-align: left;
    overflow: hidden;
    font-size: 0.85rem;
}

.chat-poll-option .chat-poll-bar {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    background: rgba(13, 110, 253, 0.22);
    z-index: 0;
}

.chat-poll-option .chat-poll-label,
.chat-poll-option .chat-poll-count {
    position: relative;
    z-index: 1;
}

.chat-poll-option .chat-poll-count {
    white-space: nowrap;
    opacity: 0.8;
}

.chat-poll-option.is-mine {
    border-color: currentColor;
    font-weight: 600;
}

.chat-poll-foot a {
    color: inherit;
    text-decoration: underline;
}

.chat-reply-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    padding: 0.25rem 0.6rem;
    border-left: 3px solid var(--brand-primary, #0d6efd);
    background: var(--bs-secondary-bg, #e9ecef);
    border-radius: 0.25rem;
}

.chat-reply-bar[hidden],
.chat-input-tools [hidden] {
    display: none !important;
}

.chat-scheduled-bar .list-group-item {
    background: transparent;
}

.chat-translate .form-text {
    font-size: 0.7rem;
}

/* Sprachnachrichten und Kanaele (v1.269.0) */
.chat-voice-audio {
    height: 2.2rem;
    max-width: 100%;
    min-width: 12rem;
}

.chat-voice-deleted {
    opacity: 0.8;
}

/* Druckansicht Sitzungsprotokoll (v1.272.0): Menues und Hinweise ausblenden, solange protokoll.php druckt */
@media print {
    body.print-minutes .sidebar,
    body.print-minutes .sidebar-backdrop,
    body.print-minutes .topbar,
    body.print-minutes .alert,
    body.print-minutes .emergency-banner {
        display: none !important;
    }

    body.print-minutes .app-shell {
        display: block;
    }

    body.print-minutes .main-content {
        margin: 0;
        padding: 0;
    }
}

/* Räume im Aufgaben-Modul (v1.285.0): Kommunikationsansicht */
.task-feed-post .chat-mention {
    background: var(--bs-primary-bg-subtle, #e2eefb);
    color: var(--bs-primary-text-emphasis, #0a58ca);
    border-radius: 0.25rem;
    padding: 0 0.2rem;
    font-weight: 600;
}
.task-feed-body {
    overflow-wrap: anywhere;
}
.task-feed-reply > summary {
    cursor: pointer;
    list-style: none;
}
.task-feed-reply > summary::-webkit-details-marker {
    display: none;
}
.task-feed-reply-level {
    border-color: var(--bs-border-color) !important;
}
.task-mention-list {
    position: absolute;
    z-index: 2000;
    max-width: 320px;
}
.min-w-0 {
    min-width: 0;
}
.task-feed-body a.task-ref {
    background: var(--bs-secondary-bg, #e9ecef);
    border-radius: 0.25rem;
    padding: 0 0.25rem;
    text-decoration: none;
    font-weight: 600;
}

/* Naki-Handbuch (v1.291.0): Kategorienbaum links, aufklappbar bis Stufe 4 */
.wiki-tree ul {
    list-style: none;
    margin: 0 0 0 0.9rem;
    padding: 0 0 0 0.4rem;
    border-left: 1px solid var(--bs-border-color);
}
.wiki-tree li { padding: 0.1rem 0; }
.wiki-tree-link {
    display: inline-block;
    padding: 0.1rem 0.35rem;
    border-radius: 0.25rem;
    text-decoration: none;
}
.wiki-tree-link:hover, .wiki-tree-link.active {
    background: var(--bs-secondary-bg, #e9ecef);
}
.wiki-tree-node > summary { cursor: pointer; }
mark { padding: 0 0.15rem; }

/* Kalender: Uhrzeit am Termin und Klick auf freie Tagesflaeche (v1.293.0) */
.calendar-day {
    position: relative;
}
td[data-create-date] {
    cursor: pointer;
}
.calendar-day-add {
    position: absolute;
    top: 2px;
    right: 4px;
    width: 1.5rem;
    height: 1.5rem;
    padding: 0;
    line-height: 1.4rem;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 50%;
    background: var(--bs-body-bg, #fff);
    color: var(--bs-secondary-color, #6c757d);
    font-size: 1rem;
    opacity: 0;
    transition: opacity 0.12s;
}
.calendar-day:hover .calendar-day-add,
.calendar-day-add:focus-visible {
    opacity: 1;
}
.calendar-day-add:hover {
    color: var(--bs-primary, #0d6efd);
    border-color: var(--bs-primary, #0d6efd);
}
@media (hover: none) {
    .calendar-day-add {
        opacity: 0.55;
    }
}
.calendar-event-time {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* Kalender: Wochen-/Tages-/Agenda-Ansicht, Verschieben per Ziehen (v1.296.0) */
.calendar-week {
    display: grid;
    grid-template-columns: 3.5rem repeat(var(--cw-cols), minmax(7rem, 1fr));
    min-width: calc(3.5rem + var(--cw-cols) * 7rem);
}
.calendar-week-corner,
.calendar-week-head {
    border-bottom: 1px solid var(--bs-border-color, #dee2e6);
    border-left: 1px solid var(--bs-border-color, #dee2e6);
    padding: 4px;
    min-height: 2.5rem;
}
.calendar-week-corner {
    border-left: 0;
}
.calendar-week-daylabel {
    font-weight: 600;
    font-size: 0.85rem;
}
.calendar-week-gutter {
    display: flex;
    flex-direction: column;
}
.calendar-week-hourlabel {
    height: var(--cw-hour-px);
    font-size: 0.7rem;
    color: var(--bs-secondary-color, #6c757d);
    text-align: right;
    padding-right: 6px;
    font-variant-numeric: tabular-nums;
}
.calendar-week-column {
    position: relative;
    height: calc(var(--cw-hours) * var(--cw-hour-px));
    border-left: 1px solid var(--bs-border-color, #dee2e6);
    background-image: repeating-linear-gradient(to bottom, transparent 0, transparent calc(var(--cw-hour-px) - 1px), var(--bs-border-color, #dee2e6) calc(var(--cw-hour-px) - 1px), var(--bs-border-color, #dee2e6) var(--cw-hour-px));
    cursor: pointer;
}
.calendar-week-event {
    position: absolute;
    overflow: hidden;
    box-sizing: border-box;
    padding: 2px 4px;
    font-size: 0.75rem;
    line-height: 1.2;
    background: var(--bs-primary-bg-subtle, #cfe2ff);
    color: var(--bs-body-color, #212529);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-left: 4px solid var(--bs-primary, #0d6efd);
    border-radius: 4px;
}
.calendar-week-event:hover {
    z-index: 2;
    overflow: visible;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
.calendar-week-event-place {
    display: block;
    color: var(--bs-secondary-color, #6c757d);
}
.calendar-agenda-event {
    border-left: 4px solid var(--bs-border-color, #dee2e6);
    padding-left: 8px;
    margin: 2px 0;
}
.calendar-agenda-time {
    display: inline-block;
    min-width: 7.5rem;
    font-variant-numeric: tabular-nums;
    color: var(--bs-secondary-color, #6c757d);
}
.calendar-drop-target {
    outline: 2px dashed var(--bs-primary, #0d6efd);
    outline-offset: -3px;
}
.calendar-event[draggable="true"] {
    cursor: grab;
}

/* App-Kalender (v1.300.0): gleich grosse Tageskaestchen, Mo-So in einer Zeile, abgeschnittene Titel */
.calendar-app-grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 2px;
}
.calendar-app-weekday {
    padding: 0.25rem 0;
    text-align: center;
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--bs-secondary-color, #6c757d);
}
.calendar-app-day {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
    height: min(calc((100vw - 1.5rem) / 7 + 1.25rem), 6.5rem);
    padding: 2px;
    overflow: hidden;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.4rem;
    background-color: var(--bs-body-bg, #fff);
    color: var(--bs-body-color, #212529);
    text-decoration: none;
}
.calendar-app-day:hover,
.calendar-app-day:focus-visible {
    color: var(--bs-body-color, #212529);
    border-color: var(--brand-accent, var(--bs-primary, #0d6efd));
}
.calendar-app-daynum {
    flex: 0 0 auto;
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 1.2;
}
.calendar-app-day.calendar-day-today .calendar-app-daynum {
    color: var(--brand-accent, var(--bs-primary, #0d6efd));
    text-decoration: underline;
}
.calendar-app-event {
    display: block;
    flex: 0 0 auto;
    min-width: 0;
    padding: 0 2px;
    border-radius: 2px;
    background-color: var(--brand-primary, #0d6efd);
    color: #fff;
    font-size: 0.6rem;
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.calendar-app-event-holiday {
    background-color: #b02a37;
}
.calendar-app-event-closure {
    background-color: #2f7d3c;
}
.calendar-app-event-vacation {
    background-color: #997404;
}
[data-bs-theme="dark"] .calendar-app-day.calendar-day-outside {
    background-color: #1b1d20;
    color: #777;
}
[data-bs-theme="dark"] .calendar-app-day.calendar-day-saturday {
    background-color: #24241c;
}
[data-bs-theme="dark"] .calendar-app-day.calendar-day-sunday {
    background-color: #2b241d;
}
[data-bs-theme="dark"] .calendar-app-day.calendar-day-today {
    background-color: #231e20;
}
[data-bs-theme="dark"] .calendar-app-day.calendar-day-holiday {
    background-color: #2b241d;
}
[data-bs-theme="dark"] .calendar-app-day.calendar-day-closure {
    background-color: #1e3626;
}
[data-bs-theme="dark"] .calendar-app-day.calendar-day-school {
    background-color: #1a1c1f;
}
.calendar-app-day.calendar-day-outside {
    background-color: #fafafa;
    color: #aaa;
}
.calendar-app-day.calendar-day-saturday {
    background-color: #fbf8e2;
}
.calendar-app-day.calendar-day-sunday {
    background-color: #fcefe3;
}
.calendar-app-day.calendar-day-today {
    background-color: #fef8f8;
}
.calendar-app-day.calendar-day-holiday {
    background-color: #fcefe3;
}
.calendar-app-day.calendar-day-closure {
    background-color: #e3f5e0;
}
.calendar-app-day.calendar-day-school {
    background-color: #ffffff;
}

/* Termin: Bild und Karte nebeneinander (v1.301.0, v1.303.1): das Bild steht in voller Hoehe (nichts wird abgeschnitten), die Karte passt sich der Bildhoehe an */
.calendar-media-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: stretch;
    gap: 0.75rem;
    margin-bottom: 0.25rem;
}
.calendar-media-image img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 0.375rem;
}
.calendar-media-map {
    position: relative;
    min-height: 0;
    overflow: hidden;
    border-radius: 0.375rem;
}
.calendar-media-map iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}
@media (max-width: 575.98px) {
    .calendar-media-row {
        grid-template-columns: minmax(0, 1fr);
    }
    .calendar-media-map {
        min-height: 0;
        aspect-ratio: 16 / 9;
    }
}
/* App-Kalender: Wochenzeilen und durchgehende Balken fuer mehrtaegige Termine (v1.303.0) */
.calendar-app-grid {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.calendar-app-weekdays,
.calendar-app-week {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 2px;
}
.calendar-app-week {
    position: relative;
}
.calendar-app-lanes {
    display: block;
    flex: 0 0 auto;
    height: calc(var(--lanes, 0) * 0.95rem);
}
.calendar-app-bar {
    position: absolute;
    top: calc(0.9rem + 4px + var(--lane, 0) * 0.95rem);
    left: calc((100% - 12px) / 7 * var(--col, 0) + 2px * var(--col, 0) + 2px);
    width: calc((100% - 12px) / 7 * var(--span, 1) + 2px * (var(--span, 1) - 1) - 4px);
    height: 0.85rem;
    padding: 0 3px;
    overflow: hidden;
    border-radius: 3px;
    background-color: var(--brand-primary, #0d6efd);
    color: #fff;
    font-size: 0.6rem;
    line-height: 0.85rem;
    text-overflow: ellipsis;
    white-space: nowrap;
    pointer-events: none;
}
.calendar-app-bar.bar-left-open {
    left: calc((100% - 12px) / 7 * var(--col, 0) + 2px * var(--col, 0));
    width: calc((100% - 12px) / 7 * var(--span, 1) + 2px * (var(--span, 1) - 1) - 2px);
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}
.calendar-app-bar.bar-right-open {
    width: calc((100% - 12px) / 7 * var(--span, 1) + 2px * (var(--span, 1) - 1) - 2px);
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}
.calendar-app-bar.bar-left-open.bar-right-open {
    width: calc((100% - 12px) / 7 * var(--span, 1) + 2px * (var(--span, 1) - 1));
}

/* Funktionen & Module (v1.305.0) */
.feature-row + .feature-row {
    border-top: 1px solid var(--bs-border-color, #dee2e6);
}
.feature-row[data-enabled="0"] label.fw-semibold {
    color: var(--bs-secondary-color, #6c757d);
}
.feature-row .min-w-0 {
    min-width: 0;
}
.feature-sub + .feature-row {
    border-top: 0;
}
.feature-row:target {
    background-color: color-mix(in srgb, var(--brand-accent, #0d6efd) 10%, transparent);
}

/* Suche mit sichtbarem Tastenkuerzel und Favoriten-Stern in der Kopfzeile (v1.312.0) */
.topbar-search-hint {
    display: none;
    font-size: 0.7rem;
    padding: 0.05rem 0.35rem;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.3rem;
    background: transparent;
    color: var(--bs-secondary-color, #6c757d);
}
@media (min-width: 1200px) {
    .topbar-search-trigger {
        display: inline-flex;
        align-items: center;
        gap: 0.4rem;
        min-width: 13rem;
        padding: 0.2rem 0.6rem;
        border: 1px solid var(--bs-border-color, #dee2e6);
        border-radius: 999px;
    }
    .topbar-search-hint {
        display: inline-block;
        margin-left: auto;
    }
}
.page-favorite-star {
    font-size: 1.1rem;
    line-height: 1;
}
#pageFavoriteToggle[aria-pressed="true"] .page-favorite-star {
    color: #e0a800;
}

/* Massenaktionen: Aktionsleiste klebt am unteren Bildschirmrand, solange etwas ausgewaehlt ist (v1.312.0) */
.bulk-bar {
    position: sticky;
    bottom: 0.75rem;
    z-index: 5;
    margin-top: 0.75rem;
    border: 1px solid var(--bs-border-color, #dee2e6);
}
.bulk-col {
    width: 2rem;
}

/* Kalender-Monatsraster auf dem Handy (v1.312.0): sieben gleich breite Spalten, lange Terminnamen werden mit "..." gekuerzt statt die Spalten aufzuziehen
   (vorher waren Samstag/Sonntag abgeschnitten); die "+"-Knoepfe entfallen dort (Termine legt man ueber "Neuer Termin" an). */
.calendar-table {
    table-layout: fixed;
    width: 100%;
}
@media (max-width: 767.98px) {
    .calendar-day {
        height: 72px;
        padding: 2px;
        overflow: hidden;
    }
    .calendar-day-add {
        display: none;
    }
    .calendar-table th {
        padding: 0.25rem 0;
        font-size: 0.75rem;
        text-align: center;
    }
    .calendar-event {
        font-size: 0.62rem;
        padding: 0 2px;
    }
}

/* Untergruppen der Seitenleiste (3. Ebene) sind wie die erste Ebene verlinkt: Beschriftung -> Kachel-Seite, Pfeil -> auf-/zuklappen (v1.313.0) */
.sidebar-nav .nav-children .nav-group-toggle-linked .nav-group-toggle-label {
    font-size: 0.87rem;
}
.sidebar-nav .nav-group-toggle-linked .nav-group-toggle-label.active {
    background-color: var(--brand-sidebar-active);
    color: #fff;
    font-weight: 600;
}

/* QR-Scanner beim Check-in (v1.318.0): Kamerabild mit Zielrahmen */
.checkin-scan-frame {
    position: relative;
    width: 100%;
    aspect-ratio: 4 / 3;
    max-height: 60vh;
    overflow: hidden;
    border-radius: 0.5rem;
    background: #111;
}
.checkin-scan-frame video {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
/* Ergebnis des letzten Scans liegt als Einblendung auf dem Kamerabild, damit es auf dem Handy nicht aus dem Sichtbereich rutscht */
.checkin-scan-result {
    position: absolute;
    right: 0.5rem;
    bottom: 0.5rem;
    left: 0.5rem;
}
.checkin-scan-result .alert {
    --bs-alert-padding-y: 0.5rem;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
}
.checkin-scan-aim {
    position: absolute;
    top: 50%;
    left: 50%;
    width: min(60%, 18rem);
    aspect-ratio: 1 / 1;
    transform: translate(-50%, -50%);
    border: 3px solid rgba(255, 255, 255, 0.85);
    border-radius: 0.75rem;
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.35);
    pointer-events: none;
}

/* Webinare (v1.331.0): Mediathek-Karten, Player-Bühne, Fenster-Ansicht */
.webinar-thumb {
    position: relative;
    display: block;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: #1b2420;
    border-radius: var(--bs-card-inner-border-radius, 0.375rem) var(--bs-card-inner-border-radius, 0.375rem) 0 0;
}
.webinar-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.webinar-thumb-empty { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 3rem; color: rgba(255, 255, 255, 0.55); }
.webinar-duration { position: absolute; right: 0.4rem; bottom: 0.4rem; padding: 0.05rem 0.4rem; border-radius: 0.25rem; background: rgba(0, 0, 0, 0.75); color: #fff; font-size: 0.78rem; font-variant-numeric: tabular-nums; }
.webinar-progress { position: absolute; left: 0; bottom: 0; height: 4px; background: #2f9e5f; }
.webinar-card-hidden { opacity: 0.8; border-style: dashed; }
.webinar-excerpt { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.webinar-fav .bi { font-size: 1.15rem; }
.webinar-stage { position: relative; background: #000; border-radius: var(--bs-card-inner-border-radius, 0.375rem) var(--bs-card-inner-border-radius, 0.375rem) 0 0; overflow: hidden; }
.webinar-stage video { display: block; width: 100%; max-height: 75vh; background: #000; }
.webinar-stage:fullscreen { border-radius: 0; display: flex; align-items: center; justify-content: center; }
.webinar-stage:fullscreen video { max-height: 100vh; height: 100%; }
.webinar-popout-note { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.88); color: #fff; text-align: center; }
.webinar-popout-note[hidden] { display: none; }
.webinar-poster-preview { width: 8rem; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 0.25rem; border: 1px solid var(--bs-border-color); }
.webinar-chapters li { padding: 0.1rem 0; }
.webinar-playlist li + li { border-top: 1px solid var(--bs-border-color-translucent); }
.webinar-popup-body { margin: 0; background: #0b0f0d; color: #fff; display: flex; flex-direction: column; height: 100vh; }
.webinar-popup-title { padding: 0.4rem 0.75rem; font-size: 0.9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; background: #1b2420; }
.webinar-stage-popup { flex: 1 1 auto; min-height: 0; border-radius: 0; display: flex; align-items: center; justify-content: center; }
.webinar-stage-popup video { max-height: 100%; height: 100%; }
.webinar-embed { position: relative; width: 100%; aspect-ratio: 16 / 9; background: #0b0f0d; color: #fff; }
.webinar-embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.webinar-embed-poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0.3; }
.webinar-embed-poster[hidden], .webinar-embed-gate[hidden] { display: none; }
.webinar-embed-gate { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 1rem; text-align: center; }
.webinar-embed-gate a { color: #fff; }
.webinar-stage:fullscreen .webinar-embed { height: 100%; aspect-ratio: auto; }
/* Schmale Bildschirme: der Zustimmungshinweis braucht mehr Höhe als 16:9; mit geladenem Video gilt wieder 16:9 */
@media (max-width: 767.98px) {
    .webinar-embed:not(.webinar-embed-loaded) { aspect-ratio: auto; min-height: 19rem; display: flex; }
    .webinar-embed:not(.webinar-embed-loaded) .webinar-embed-gate { position: relative; inset: auto; width: 100%; padding: 1.25rem 1rem; }
}
.webinar-stage-popup .webinar-embed { height: 100%; aspect-ratio: auto; }
.webinar-public-body { margin: 0; min-height: 100vh; }
[data-bs-theme="dark"] .webinar-public-body { background-color: #14181a; color: #e6e8e7; }
.webinar-public-band { height: 0.4rem; background: var(--brand-primary, #1b2420); }
.webinar-public-tools { display: flex; align-items: center; gap: 0.75rem; flex: 0 0 auto; }
.webinar-public-langs { display: flex; flex-wrap: wrap; gap: 0.25rem 0.9rem; align-items: center; margin: -0.4rem 0 1rem; font-size: 0.9rem; }
.webinar-public-langs a { color: inherit; }
.webinar-public-qr summary { list-style: none; cursor: pointer; display: inline-block; }
.webinar-public-qr summary::-webkit-details-marker { display: none; }
.webinar-public-qr img { background: #fff; padding: 0.4rem; border-radius: 0.25rem; }
.webinar-public-sibling:hover { border-color: var(--brand-accent, #4f7943); }
.webinar-public-contact { border-inline-start: 0.3rem solid var(--brand-accent, #4f7943); }
.webinar-public-footer { margin-top: 1rem; border-top: 1px solid var(--bs-border-color); padding-top: 1rem; }
.webinar-public-footer a { text-decoration: underline; }
.webinar-public-wrap { max-width: 64rem; margin: 0 auto; padding: 1rem; }
.webinar-public-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.5rem 0 1rem; }
.webinar-public-title { min-width: 0; }
.webinar-public-portal { font-size: 0.8rem; color: var(--bs-secondary-color); text-transform: uppercase; letter-spacing: 0.04em; }
.webinar-public-category { margin-top: 0.15rem; font-size: 0.9rem; color: var(--bs-secondary-color); }
.webinar-public-logo { flex: 0 0 auto; max-height: 3.5rem; max-width: 9rem; width: auto; object-fit: contain; }
.webinar-public-link-input { font-size: 0.85rem; }
.webinar-next-note { z-index: 3; }
.webinar-transcript { position: relative; max-height: 18rem; overflow-y: auto; }
.webinar-transcript li { padding: 0.1rem 0.25rem; }
.webinar-transcript li[hidden] { display: none; }
.webinar-cue-active { background: rgba(var(--bs-primary-rgb), 0.12); border-radius: 0.25rem; font-weight: 600; }
.webinar-stars { display: inline-flex; flex-direction: row-reverse; gap: 0.15rem; }
.webinar-stars label { cursor: pointer; font-size: 1.5rem; line-height: 1; color: var(--bs-secondary-color); opacity: 0.45; }
.webinar-stars label:hover, .webinar-stars label:hover ~ label, .webinar-stars input:checked ~ label { color: #e0a100; opacity: 1; }
.webinar-stars input:focus-visible + label { outline: 2px solid var(--bs-primary); outline-offset: 2px; border-radius: 0.2rem; }
/* Quill setzt height:100% auf den Editor; in einer Bootstrap-Spalte (flex, stretch) wird die Spalte aber nach der Höhe OHNE Editor bemessen - der Editor ragte unten aus der Karte. */
.row > [class*="col"] > .ql-container.ql-snow { height: auto; }
.webinar-popup-bar { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; padding: 0.4rem 0.75rem; background: #1b2420; }
@media print { .webinar-stage, .webinar-controls { display: none; } }

/* Zeitplan (Gantt) der Aufgaben: Balken, Abhängigkeits-Pfeile, Wochenenden, Heute-Linie (assets/js/task-gantt.js) */
.gantt-chart { font-size: 0.85rem; }
.gantt-label { height: 36px; display: flex; align-items: center; padding-right: 0.5rem; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; border-bottom: 1px solid var(--bs-border-color-translucent); }
.gantt-header-label { height: 28px; }
.gantt-row { position: relative; height: 36px; border-bottom: 1px solid var(--bs-border-color-translucent); }
.gantt-header-row { height: 28px; line-height: 28px; }
.gantt-overlay { position: absolute; left: 0; top: 0; pointer-events: none; }
.gantt-weekend { fill: rgba(127, 127, 127, 0.12); }
.gantt-today { stroke: var(--bs-danger); stroke-width: 2; }
.gantt-milestone-line { stroke: var(--bs-info); stroke-width: 1.5; stroke-dasharray: 4 3; }
.gantt-arrow { fill: none; stroke: var(--bs-secondary-color); stroke-width: 1.5; }
.gantt-arrow-late { stroke: var(--bs-danger); }
.gantt-arrow-head { fill: var(--bs-secondary-color); }
.gantt-arrow-head-late { fill: var(--bs-danger); }
.gantt-bar { position: absolute; top: 7px; height: 22px; border-radius: 0.35rem; cursor: grab; touch-action: none; user-select: none; }
.gantt-bar[data-closed="1"] { opacity: 0.5; cursor: pointer; }
.gantt-bar:focus-visible { outline: 2px solid var(--bs-primary); outline-offset: 2px; }
.gantt-dragging { cursor: grabbing; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35); z-index: 3; }
.gantt-handle { position: absolute; top: 0; bottom: 0; width: 7px; cursor: ew-resize; }
.gantt-handle[data-handle="start"] { left: 0; }
.gantt-handle[data-handle="end"] { right: 0; }
.gantt-handle:hover { background: rgba(255, 255, 255, 0.45); }
.gantt-diamond { position: absolute; top: 11px; width: 14px; height: 14px; background: var(--bs-info); transform: translateX(-7px) rotate(45deg); }
.gantt-diamond-label { position: absolute; top: 8px; margin-left: 6px; white-space: nowrap; color: var(--bs-info-text-emphasis, inherit); }

/* Titelbild einer Aufgaben-Karte */
.task-cover { width: 100%; max-height: 120px; object-fit: cover; }

/* Räume und Spalten der Aufgaben mit Farbe: Raum-Reiter dezent (aktiv kräftiger), Streifen über dem Spaltennamen */
.nav-pills .nav-link.task-room-pill { background-color: color-mix(in srgb, var(--room-color) 14%, transparent); color: var(--bs-body-color); border: 1px solid color-mix(in srgb, var(--room-color) 28%, transparent); }
.nav-pills .nav-link.task-room-pill:hover { background-color: color-mix(in srgb, var(--room-color) 24%, transparent); }
.nav-pills .nav-link.task-room-pill.active { background-color: color-mix(in srgb, var(--room-color) 42%, transparent); color: var(--bs-body-color); border-color: var(--room-color); font-weight: 600; }
.task-column-color { height: 6px; margin: -0.5rem -0.5rem 0.5rem; border-radius: 0.375rem 0.375rem 0 0; }

/* Aufgaben & Planer, Listenansicht (v1.351.0): schmale Spalte fuer die Sammelauswahl */
.task-list-table .task-bulk-col { width: 2rem; }
/* Sammelleiste (Liste und Kanban, v1.352.0): bleibt am unteren Rand sichtbar, auch wenn viele Karten darueber stehen (nur bei genug Fensterhoehe) */
@media (min-height: 760px) { .task-bulk-bar { position: sticky; bottom: 0.75rem; z-index: 5; } }
.task-bulk-pick { display: inline-flex; padding-top: 0.1rem; cursor: default; }

/* Aufgaben & Planer (v1.353.0): Antwort-, Bearbeiten- und Kommentarfelder nutzen die volle Breite des Blocks, Dropzones sind gross genug zum Treffen */
.task-feed-reply[open] { flex: 1 1 100%; min-width: 0; }
.task-feed-reply[open] form { width: 100%; }
.task-feed-reply textarea, .task-comment-form textarea { width: 100%; min-height: 7.5rem; resize: vertical; }
.task-wide-dropzone { width: 100%; max-width: none; padding: 1.1rem 1rem; }
