:root {
    --color-bg: #f4f6f8;
    --color-surface: #ffffff;
    --color-primary: #005baa;
    --color-primary-rgb: 0, 91, 170;
    --color-primary-dark: #00447f;
    --color-secondary: #ed1c24;
    --color-secondary-rgb: 237, 28, 36;
    --color-secondary-dark: #c8151b;
    --color-text: #1c2430;
    --color-muted: #5b6472;
    --color-border: #e1e5ea;
    --color-danger: var(--color-secondary);
    --color-danger-bg: #fdecea;
    --color-danger-border: #f6c6c4;
    --color-success-bg: #e9f8ee;
    --color-success-text: #1c7c37;
    --color-success-border: #bfe9cb;
    --color-info-bg: #eaf2fd;
    --color-info-text: #1c5cab;
    --color-info-border: #c6dafc;
    --color-badge-bg: #e6f0fa;
    --color-lightning-bg: rgba(245, 158, 11, 0.15);
    --color-lightning-text: #b45309;
    --radius: 10px;
    /* Fallback-Wert für Browser ohne JS/ResizeObserver - wird zur Laufzeit
       durch assets/js/topbar-height.js mit der tatsächlich gerenderten Höhe
       von nav.topbar überschrieben, da diese je nach Bildschirmbreite
       schwankt (z. B. zweizeiliger Umbruch der Hauptnav auf mittleren
       Breiten). Dient als Offset für andere sticky Elemente, die sonst unter
       der jetzt sticky Topbar verschwinden würden (siehe
       .offers-filter-sidebar in offers.php). */
    --topbar-height: 64px;
}

/* Dark Mode: Werte werden per Attribut auf <html> aktiviert, das
   assets/js/theme.js so früh wie möglich (vor dem ersten Paint) setzt -
   entweder aus einer gespeicherten Nutzerwahl (localStorage) oder, ohne
   gespeicherte Wahl, aus der Geräte-/Browser-Einstellung
   (prefers-color-scheme). Reine CSS-Variablen-Umdefinition, kein
   zusätzlicher Selektor-Aufwand in den restlichen Regeln nötig, da praktisch
   der gesamte Rest dieser Datei bereits über var(--color-*) läuft. */
:root[data-theme="dark"] {
    --color-bg: #0d1117;
    --color-surface: #161b22;
    --color-primary: #4da3ff;
    --color-primary-rgb: 77, 163, 255;
    --color-primary-dark: #79bbff;
    --color-secondary: #ff6b6b;
    --color-secondary-rgb: 255, 107, 107;
    --color-secondary-dark: #ff9494;
    --color-text: #e6edf3;
    --color-muted: #8b949e;
    --color-border: #30363d;
    --color-danger-bg: #3d1f1f;
    --color-danger-border: #6e2f2f;
    --color-success-bg: #142e1d;
    --color-success-text: #56d364;
    --color-success-border: #234a2c;
    --color-info-bg: #12233b;
    --color-info-text: #79c0ff;
    --color-info-border: #1f3f66;
    --color-badge-bg: #17283b;
    --color-lightning-bg: rgba(245, 158, 11, 0.18);
    --color-lightning-text: #f0a742;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    background: var(--color-bg);
    color: var(--color-text);
    line-height: 1.5;
}

.container {
    max-width: 720px;
    margin: 0 auto;
    padding: 2rem 1.25rem;
}

nav.topbar {
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    padding: 0.9rem 1.25rem;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 1rem;
    /* Bleibt beim Scrollen permanent oben sichtbar - auch auf Mobile (siehe
       @media (max-width: 600px) unten, dort wird keine abweichende position
       gesetzt, die Regel gilt unverändert weiter). z-index hoch genug, um
       über sämtlichem Seiteninhalt inkl. der sticky .offers-filter-sidebar
       und ihrem mobilen Overlay (siehe dort) zu liegen; der oben fixierte
       #cookie-banner (z-index: 1000) bleibt unbetroffen, da er am unteren
       Rand verankert ist und sich damit nie mit der Topbar überschneidet. */
    position: sticky;
    top: 0;
    z-index: 100;
}

nav.topbar a {
    color: var(--color-primary);
    text-decoration: none;
    font-weight: 600;
    margin-left: 1rem;
}

nav.topbar a:hover { text-decoration: underline; }

.brand-link {
    justify-self: start;
    display: inline-flex;
    align-items: center;
}

.topbar__nav {
    justify-self: center;
    display: flex;
    align-items: center;
    gap: 1.75rem;
}

.topbar__nav-link {
    margin-left: 0 !important;
    color: var(--color-muted) !important;
    font-weight: 600;
    padding: 0.4rem 0.9rem;
    border-radius: 999px;
    background: transparent;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.topbar__nav-link:hover {
    color: var(--color-primary) !important;
    background: var(--color-bg);
    text-decoration: none;
}

.topbar__nav-link--active {
    color: var(--color-primary) !important;
    background: rgba(var(--color-primary-rgb), 0.1);
}

.profile-link {
    display: inline-flex;
    align-items: center;
    color: var(--color-muted) !important;
    text-decoration: none !important;
}

.profile-link:hover {
    color: var(--color-primary) !important;
}

.profile-menu {
    position: relative;
}

.profile-menu > summary {
    list-style: none;
    cursor: pointer;
    color: var(--color-primary) !important;
}

.profile-menu > summary::-webkit-details-marker {
    display: none;
}

.profile-menu__dropdown {
    position: absolute;
    right: 0;
    top: calc(100% + 0.6rem);
    display: flex;
    flex-direction: column;
    min-width: 200px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.1);
    padding: 0.5rem 0;
    z-index: 10;
}

.profile-menu__email {
    padding: 0.2rem 1rem 0.6rem;
    margin-bottom: 0.3rem;
    border-bottom: 1px solid var(--color-border);
    color: var(--color-muted);
    font-size: 0.85rem;
    font-weight: 600;
    word-break: break-all;
}

.profile-menu__item {
    margin-left: 0 !important;
    padding: 0.5rem 1rem;
    color: var(--color-text) !important;
    font-weight: 400 !important;
    text-decoration: none !important;
}

.profile-menu__item:hover {
    background: var(--color-bg);
}

.profile-menu__logout-form {
    margin: 0;
}

.profile-menu__logout-btn {
    display: block;
    width: 100%;
    background: none;
    border: none;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.topbar__right {
    justify-self: end;
    display: flex;
    align-items: center;
    gap: 0.9rem;
    flex-wrap: wrap;
}

.lang-switch {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.85rem;
    border-left: 1px solid var(--color-border);
    padding-left: 0.8rem;
}

.lang-switch__select {
    background: var(--color-surface);
    color: var(--color-muted);
    border: 1px solid var(--color-border);
    border-radius: 4px;
    padding: 0.2rem 0.4rem;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
}

/* Umschalter Hell-/Dunkelmodus (siehe assets/js/theme.js für das Setzen von
   data-theme auf <html>) - zeigt je nach aktuellem Zustand Sonne oder Mond,
   analog zum reinen currentColor-SVG-Stil von .profile-link oben. */
.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    padding: 0;
    color: var(--color-muted);
    cursor: pointer;
}

.theme-toggle:hover {
    color: var(--color-primary);
}

.theme-toggle__icon--moon {
    display: none;
}

:root[data-theme="dark"] .theme-toggle__icon--sun {
    display: none;
}

:root[data-theme="dark"] .theme-toggle__icon--moon {
    display: block;
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1.75rem;
    margin-bottom: 1.5rem;
}

/* Startseite: Karten liegen über der Foto-Diashow (.cb-slideshow) und
   bekommen hier absichtlich 15% Transparenz, damit die Fotos leicht
   durchscheinen, statt die Karten komplett deckend zu zeigen. */
.page-home .card {
    background: color-mix(in srgb, var(--color-surface) 85%, transparent);
}

/* Eigener Absatz statt an den Beschreibungstext angehängt, damit der Link
   nicht wie ein nachträglich angeklebter Halbsatz wirkt, sondern als klar
   erkennbarer nächster Schritt nach dem Lesefluss (siehe section_organizer
   auf index.php). */
.card-cta {
    margin-top: 1rem;
    margin-bottom: 0;
}

.card-cta-link {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--color-primary);
    font-weight: 600;
    text-decoration: none;
}

.card-cta-link:hover {
    text-decoration: underline;
}

.card-cta-link::after {
    content: "\2192";
    transition: transform 0.15s ease;
}

.card-cta-link:hover::after {
    transform: translateX(3px);
}

h1 { font-size: 1.6rem; margin-top: 0; }
h2 { font-size: 1.25rem; }

/* Nur wenn ein <h2> das erste Kind einer .card ist (z. B. jede der
   Content-Karten auf index.php) wird sein Standard-margin-top entfernt -
   analog zu h1 oben, gleicher Grund: die .card-Innenabstand (padding) sorgt
   bereits für Abstand zum Kartenrand, das zusätzliche Browser-Default-
   margin des <h2> addierte sich sonst obendrauf und ließ jede Karte oben
   deutlich luftiger wirken als unten (Text "sackt" optisch nach unten).
   Bewusst NICHT als globale h2-Regel, da mehrere <h2> INNERHALB einer
   einzigen .card (z. B. die nummerierten Abschnitte in agb.php/
   datenschutz.php) den Standardabstand zum vorherigen Absatz brauchen, um
   sich optisch als neuer Abschnitt abzusetzen - dort ist das <h2> nie
   :first-child. */
.card > h2:first-child {
    margin-top: 0;
}

/* Anker-Ziele des Inhaltsverzeichnisses (datenschutz.php) - ohne
   scroll-margin-top würde die sticky Topbar die angesprungene
   Überschrift verdecken, siehe gleicher Grund bei .news-section. */
[id^="section-"] {
    scroll-margin-top: calc(var(--topbar-height) + 1rem);
}

form label {
    display: block;
    font-weight: 600;
    margin: 1rem 0 0.35rem;
    font-size: 0.9rem;
}

form input[type="text"],
form input[type="email"],
form input[type="password"],
form input[type="tel"],
form input[type="date"],
form select,
form textarea {
    width: 100%;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-size: 1rem;
    font-family: inherit;
}

form textarea {
    resize: vertical;
}

/* Zielflughafen-Feld auf booking-inquiry.php, wenn per "Zur Buchungsanfrage"-
   Button aus einem Angebot vorbelegt (siehe offer-details-book-btn in
   offers.php) - visuell erkennbar gesperrt statt wie ein normales, editierbares
   Feld auszusehen. */
form input[readonly] {
    background: var(--color-bg);
    color: var(--color-muted);
    cursor: not-allowed;
}

/* Markiert leere Pflichtfelder nach einem fehlgeschlagenen Absenden (z. B.
   booking-inquiry.php, siehe booking_missing_fields() in includes/booking.php)
   - dieselbe helle Rot-Töne wie .alert-error oben, nur auf einzelne Felder
   statt einer ganzen Meldung angewendet. Muss nach der Basis-Feldregel oben
   stehen bzw. mindestens gleich spezifisch sein (form input.field-invalid
   statt nur .field-invalid), sonst gewinnt dort border-color: var(--color-border). */
form input.field-invalid,
form select.field-invalid,
form textarea.field-invalid {
    border-color: var(--color-danger-border);
    background: var(--color-danger-bg);
}

/* Einzelne Checkbox mit Beschriftung in einer Zeile (z. B. Zwei-Faktor-Auth-
   Toggle auf account.php) - überschreibt die block/bold-Vorgabe von
   "form label" oben, die eigentlich für Feld-Beschriftungen gedacht ist. */
form label.checkbox-field {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 400;
}

.field-row {
    display: flex;
    gap: 0.6rem;
    align-items: center;
}

.field-row__wide {
    flex: 2 1 0;
}

.field-row__narrow {
    flex: 1 1 0;
}

.traveler-fields__heading {
    margin-top: 1.5rem;
}

.traveler-row {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1rem;
    margin-top: 1rem;
}

.traveler-row__label {
    display: block;
    font-weight: 600;
    font-size: 0.85rem;
    color: var(--color-muted);
    margin-bottom: 0.5rem;
}

.traveler-row .field-row {
    margin-top: 0.35rem;
}

.password-field {
    position: relative;
    display: flex;
}

.password-field input {
    padding-right: 2.5rem !important;
}

.password-toggle {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 2.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    padding: 0;
    color: var(--color-muted);
    cursor: pointer;
}

.password-toggle:hover {
    color: var(--color-primary);
}

.password-toggle svg.is-hidden {
    display: none;
}

/* Für Menschen unsichtbar (per CSS versteckt statt display:none, da
   einfache Registrierungs-Bots display:none-Felder oft überspringen). */
.hp-field {
    position: absolute;
    left: -9999px;
    top: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

button, .btn {
    display: inline-block;
    border: none;
    border-radius: 6px;
    padding: 0.65rem 1.25rem;
    font-family: inherit;
    font-size: 0.95rem;
    font-weight: 600;
    line-height: 1.5;
    cursor: pointer;
    text-decoration: none;
    /* <button> zentriert seinen Inhalt per Default, ein als .btn gestylter
       <a>-Link (z. B. "Zurücksetzen" in der Filter-Sidebar, siehe
       .offers-filter-sidebar__actions in offers.php) nicht - ohne das würde
       dessen Text am linken statt zentriert am Rand kleben, sobald der Link
       durch einen umgebenden Flex-/Grid-Container in die Breite gestreckt
       wird. */
    text-align: center;
}

.btn-primary { background: var(--color-primary); color: #fff; margin-top: 1.25rem; }

.brand-logo { display: block; height: 34px; width: auto; }

.mt-0 { margin-top: 0 !important; }

.card-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.import-offers-details {
    margin: 0.75rem 0 0;
}
.import-offers-details summary {
    cursor: pointer;
    font-weight: 600;
    font-size: 0.9rem;
}
.import-offers-list {
    margin: 0.5rem 0 0;
    padding-left: 1.25rem;
    font-size: 0.9rem;
    color: var(--color-text);
}
.import-offers-list li + li {
    margin-top: 0.4rem;
}
.mt-1 { margin-top: 1rem !important; }
.mt-125 { margin-top: 1.25rem !important; }
.btn-primary:hover { background: var(--color-primary-dark); }

.btn-secondary { background: var(--color-border); color: var(--color-text); }

.btn-danger { background: var(--color-danger); color: #fff; margin-top: 1.25rem; }
.btn-danger:hover { background: var(--color-secondary-dark); }

.alert {
    padding: 0.75rem 1rem;
    border-radius: 6px;
    margin-bottom: 1rem;
    font-size: 0.92rem;
}

.alert-error { background: var(--color-danger-bg); color: var(--color-danger); border: 1px solid var(--color-danger-border); }
.alert-success { background: var(--color-success-bg); color: var(--color-success-text); border: 1px solid var(--color-success-border); }
.alert-info { background: var(--color-info-bg); color: var(--color-info-text); border: 1px solid var(--color-info-border); }

.muted { color: var(--color-muted); font-size: 0.9rem; }

.account-choice {
    display: flex;
    gap: 1rem;
    margin-top: 1.5rem;
    flex-wrap: wrap;
}

.account-choice__btn {
    flex: 1 1 200px;
    text-align: center;
    padding: 1.1rem 1rem;
    line-height: 1.4;
    margin-top: 0;
}

.account-choice__sub {
    font-weight: 400;
    font-size: 0.85rem;
    opacity: 0.85;
}

@media (max-width: 600px) {
    .account-choice {
        flex-direction: column;
    }
}

/* Kundennummer auf account.php - bewusst als eigener, farblich abgesetzter
   Block statt als weitere Zeile neben "Erstellt am"/"Letzter Login" (dort
   ging sie in der grauen .muted-Metadaten-Liste unter), da Kund:innen diese
   Nummer bei Rückfragen (Telefon/E-Mail an den Support) aktiv wiederfinden
   und angeben müssen. */
.customer-number-box {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem 0.75rem;
    margin: 1rem 0;
    padding: 0.9rem 1.25rem;
    background: rgba(var(--color-primary-rgb), 0.08);
    border: 1px solid rgba(var(--color-primary-rgb), 0.35);
    border-radius: var(--radius);
}

.customer-number-box__label {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--color-primary);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.customer-number-box__value {
    font-size: 1.3rem;
    font-weight: 700;
    color: var(--color-text);
    font-family: "Courier New", Courier, monospace;
    letter-spacing: 0.04em;
}

.customer-number-box__hint {
    flex-basis: 100%;
    margin: 0;
    font-size: 0.85rem;
    color: var(--color-muted);
}

/* PDF-Downloadliste auf invoices.php/tickets.php/travels.php (siehe
   documents.php + includes/documents.php). */
.documents-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.documents-list li {
    padding: 0.3rem 0;
    border-bottom: 1px solid var(--color-border);
}

.documents-list li:last-child {
    border-bottom: none;
}

/* --- Startseite (index.php) --- */
/* Vollflächige, fest positionierte Foto-Diashow hinter der GESAMTEN Seite
   (nicht nur im Hero oben) - 1:1 nachgebaut nach dem "cb-slideshow"-Effekt,
   der aktuell auf instant.de läuft: 12 Bilder (1.jpg-12.jpg im gemeinsamen
   images/-Ordner, ausgeliefert über images.php wie jedes andere Bild - siehe
   images.php für die Begründung, warum dieser Ordner außerhalb des Web-Roots
   liegt), die sich alle 6s im Crossfade mit leichtem Kamerazoom
   ablösen (72s Gesamtzyklus / 12 Bilder). Jedes <li><span> ist einzeln
   position:fixed und deckt den ganzen Viewport ab, statt die Diashow nur
   als Hintergrund von .home-hero zu rendern - so bleibt sie beim Scrollen
   hinter dem restlichen Seiteninhalt sichtbar. Negative z-index statt wie
   im Original über die DOM-Reihenfolge positionierter Elemente, da unsere
   .container kein position:relative setzt und die Diashow sich sonst vor
   den Seiteninhalt legen würde. */
.cb-slideshow,
.cb-slideshow li {
    margin: 0;
    padding: 0;
    list-style: none;
}

.cb-slideshow li span {
    position: fixed;
    inset: 0;
    z-index: -2;
    color: transparent;
    background-size: cover;
    background-position: 50% 50%;
    opacity: 0;
    animation: cb-slideshow-image 72s linear infinite 0s;
}

.cb-slideshow li:nth-child(1) span { background-image: url('../../images.php?file=slideshow/1.jpg'); }
.cb-slideshow li:nth-child(2) span { background-image: url('../../images.php?file=slideshow/2.jpg'); animation-delay: 6s; }
.cb-slideshow li:nth-child(3) span { background-image: url('../../images.php?file=slideshow/3.jpg'); animation-delay: 12s; }
.cb-slideshow li:nth-child(4) span { background-image: url('../../images.php?file=slideshow/4.jpg'); animation-delay: 18s; }
.cb-slideshow li:nth-child(5) span { background-image: url('../../images.php?file=slideshow/5.jpg'); animation-delay: 24s; }
.cb-slideshow li:nth-child(6) span { background-image: url('../../images.php?file=slideshow/6.jpg'); animation-delay: 30s; }
.cb-slideshow li:nth-child(7) span { background-image: url('../../images.php?file=slideshow/7.jpg'); animation-delay: 36s; }
.cb-slideshow li:nth-child(8) span { background-image: url('../../images.php?file=slideshow/8.jpg'); animation-delay: 42s; }
.cb-slideshow li:nth-child(9) span { background-image: url('../../images.php?file=slideshow/9.jpg'); animation-delay: 48s; }
.cb-slideshow li:nth-child(10) span { background-image: url('../../images.php?file=slideshow/10.jpg'); animation-delay: 54s; }
.cb-slideshow li:nth-child(11) span { background-image: url('../../images.php?file=slideshow/11.jpg'); animation-delay: 60s; }
.cb-slideshow li:nth-child(12) span { background-image: url('../../images.php?file=slideshow/12.jpg'); animation-delay: 66s; }

@keyframes cb-slideshow-image {
    0% { opacity: 0; animation-timing-function: ease-in; }
    8% { opacity: 1; transform: scale(1.05); animation-timing-function: ease-out; }
    17% { opacity: 1; transform: scale(1.1); }
    25% { opacity: 0; transform: scale(1.1); }
    100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .cb-slideshow li span {
        animation: none;
        opacity: 0;
    }

    .cb-slideshow li:first-child span {
        opacity: 1;
        transform: none;
    }
}

/* Abdunkelndes Overlay über der ganzen Diashow, damit der weiße Hero-Text
   unabhängig vom gerade eingeblendeten Foto lesbar bleibt. Die Karten weiter
   unten (.card, weiß/deckend) brauchen das nicht - sie liegen ohnehin über
   der Diashow. */
.cb-slideshow::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    background: linear-gradient(180deg, rgba(0, 15, 35, 0.55) 0%, rgba(0, 15, 35, 0.4) 45%, rgba(0, 15, 35, 0.6) 100%);
}

.home-brand {
    text-align: center;
    margin-bottom: 1.5rem;
}

.home-brand__logo {
    width: 100%;
    max-width: 320px;
    height: auto;
}

.home-hero {
    text-align: center;
}

.home-hero__lead {
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--color-primary);
    margin-bottom: 0.5rem;
}

.home-hero__tagline {
    font-size: 1.15rem;
    font-weight: 700;
    margin-bottom: 0;
}

.home-hero__actions {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    justify-content: center;
    margin-top: 1.5rem;
}

.home-hero__actions .btn {
    margin-top: 0;
}

.home-hero__login-hint {
    margin-top: 1rem;
    margin-bottom: 0;
    font-size: 0.9rem;
}

.home-section > h2,
.home-section > h3 {
    text-align: center;
}

.home-highlights-list {
    margin: 1rem 0 0;
    padding-left: 1.25rem;
}

.home-highlights-list li {
    margin-bottom: 0.4rem;
}

.home-highlights-list li:last-child {
    margin-bottom: 0;
}

/* --- Partner-Logoleiste (index.php) --- */
.trusted-by__heading {
    text-align: center;
    color: var(--color-muted);
    font-size: 1rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin: 0 0 1.5rem;
}

.trusted-by__logos {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 2.5rem;
}

.trusted-by__logo {
    display: inline-flex;
}

.trusted-by__logo img {
    height: 40px;
    max-width: 160px;
    object-fit: contain;
    filter: grayscale(1);
    opacity: 0.6;
    transition: filter 0.15s ease, opacity 0.15s ease;
}

.trusted-by__logo:hover img,
.trusted-by__logo:focus-visible img {
    filter: grayscale(0);
    opacity: 1;
}

/* --- News-Sektion (index.php) --- */
/* Lässt Platz für die jetzt sticky nav.topbar (siehe dort), wenn per
   index.php#news direkt zu dieser Sektion gesprungen wird - ohne das würde
   der Anker-Sprung den Kartentitel unter der Topbar verstecken. */
.news-section {
    scroll-margin-top: calc(var(--topbar-height) + 1rem);
}

.news-section__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1rem;
    margin-bottom: 1rem;
}

.news-section__header h2 {
    margin: 0;
}

.news-section__header h2 .info-icon {
    margin-left: 0.4rem;
    vertical-align: middle;
}

.news-list {
    display: flex;
    flex-direction: column;
}

.news-item {
    padding: 1.25rem 0;
    border-bottom: 1px solid var(--color-border);
    /* Eigener Anker (id="news-<id>", siehe index.php) - dieselbe Begründung
       wie bei .news-section oben, nur pro einzelnem Eintrag statt für die
       ganze Sektion. */
    scroll-margin-top: calc(var(--topbar-height) + 1rem);
}

.news-list > .news-item:last-child {
    border-bottom: none;
}

/* --- Newsletter-Sektion (account.php) --- */
/* Gleicher Grund wie bei .news-section oben: nach dem Abbestellen springt
   das Formular per account.php#newsletter zurück zu dieser Sektion statt an
   den Seitenanfang - ohne scroll-margin-top würde die sticky Topbar den
   Kartentitel verdecken. */
.newsletter-section {
    scroll-margin-top: calc(var(--topbar-height) + 1rem);
}

/* "Allgemeine News & Blitzangebote"-Umschalter oberhalb der zielort-basierten
   Anmeldungsliste - eigener Rahmen, damit klar erkennbar eine unabhängige
   Einstellung ist (login.notify_general_updates), keine weitere Reiseziel-
   Anmeldung. */
.newsletter-general-updates {
    padding: 1rem;
    margin: 1rem 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}

.newsletter-general-updates h3 {
    margin: 0 0 0.35rem;
    font-size: 1rem;
}

.news-item__headline {
    margin: 0 0 0.25rem;
    font-size: 1.05rem;
    color: var(--color-primary);
}

.news-item__date {
    display: block;
    color: var(--color-muted);
    font-size: 0.8rem;
    margin-bottom: 0.5rem;
}

.news-item__content {
    margin: 0;
    /* Tabs/mehrfache Leerzeichen aus dem Textarea sollen als Struktur
       (Einrückung) sichtbar bleiben statt wie normales HTML kollabiert zu
       werden - nl2br() in index.php übernimmt weiterhin die Zeilenumbrüche. */
    white-space: pre-wrap;
}

.news-item__actions {
    display: flex;
    gap: 0.75rem;
    margin-top: 0.9rem;
}

.news-item__edit-btn,
.news-item__delete-btn {
    margin-top: 0;
    padding: 0.4rem 0.9rem;
    font-size: 0.8rem;
}

.news-item__delete-form {
    margin: 0;
}

/* --- Reiseinfos-Hub (travel-info.php) --- */
.travelinfo-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1.25rem;
    margin-top: 1.25rem;
}

.travelinfo-card {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 1.25rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    color: var(--color-text) !important;
    text-decoration: none !important;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.travelinfo-card:hover {
    border-color: var(--color-primary);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.08);
}

.travelinfo-card__icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 999px;
    background: rgba(var(--color-primary-rgb), 0.1);
    color: var(--color-primary);
}

.travelinfo-card__title {
    margin: 0;
    font-size: 1.05rem;
}

.travelinfo-card__text {
    margin: 0;
    color: var(--color-muted);
    font-size: 0.9rem;
}

/* --- Online-Check-In (checkin.php) --- */
.checkin-select {
    width: 100%;
    max-width: 420px;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-size: 1rem;
    font-family: inherit;
}

.checkin-links {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-top: 1.25rem;
}

.checkin-links__btn {
    flex: 1 1 200px;
    text-align: center;
    margin-top: 0;
}

.checkin-links__btn.is-disabled {
    opacity: 0.5;
    cursor: default;
}

.checkin-visa-list {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    margin: 1rem 0 0;
    padding: 0;
}

.checkin-visa-list__link {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    /* Feste Breite statt Shrink-to-fit - ohne sie zieht ein langer
       Ländername (z. B. "Vereinigtes Königreich") die ganze Kachel in die
       Breite statt umzubrechen, wodurch dieser eine Eintrag deutlich breiter
       als die übrigen wird. Bricht der Name jetzt auf zwei Zeilen um, bleibt
       die Kachelbreite für alle Länder gleich. */
    width: 5rem;
    text-align: center;
    color: var(--color-text) !important;
    text-decoration: none !important;
    font-size: 0.85rem;
    font-weight: 600;
}

/* Feste Breite UND Höhe (statt height: auto) - die Quell-Flaggenbilder haben
   je nach Land unterschiedliche Seitenverhältnisse (z. B. AU/CA 2:1, CN/GH
   3:2, GB 5:3), wodurch die Länderzeilen sonst pro Flagge unterschiedlich
   hoch wären und die Ländernamen darunter nicht in einer Zeile fluchten.
   object-fit: cover füllt die feste Box, statt sie zu verzerren oder
   Leerraum an den Rändern zu lassen. */
.checkin-visa-list__flag {
    width: 2.5rem;
    height: 1.75rem;
    object-fit: cover;
    border: 1px solid var(--color-border);
    border-radius: 3px;
}

.checkin-visa-list__link:hover {
    color: var(--color-primary) !important;
}

/* --- Angebot-anlegen-Modal (offers.php, nur Admins) --- */
dialog.modal {
    width: calc(100% - 2.5rem);
    max-width: 640px;
    max-height: calc(100% - 4rem);
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1.75rem;
    box-shadow: 0 10px 40px rgba(0,0,0,0.18);
}

dialog.modal::backdrop {
    background: rgba(0,0,0,0.5);
}

.modal__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.5rem;
}

.modal__header h2 {
    margin: 0;
}

.modal__close {
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    padding: 0;
    margin: 0;
    width: 2rem;
    height: 2rem;
    line-height: 1;
    font-size: 1.5rem;
    color: var(--color-muted);
    flex-shrink: 0;
}

.modal__close:hover {
    color: var(--color-text);
}

.modal__actions {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-top: 1.25rem;
}

/* --- Cookie-Banner --- */
#cookie-banner {
    display: none;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1000;
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    box-shadow: 0 -4px 18px rgba(0,0,0,0.08);
    padding: 1.1rem 1.25rem;
    transition: opacity 0.3s ease, transform 0.3s ease;
}

.cookie-banner--hidden {
    opacity: 0;
    transform: translateY(20px);
    pointer-events: none;
}

.cookie-banner-inner {
    width: 100%;
    max-width: 960px;
    margin: 0 auto;
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
}

#cookie-banner p {
    margin: 0;
    max-width: 560px;
    font-size: 0.9rem;
    color: var(--color-text);
}

#cookie-banner .cookie-actions {
    display: flex;
    gap: 0.6rem;
    flex-shrink: 0;
}

footer.site-footer {
    /* .container ist selbst 720px breit inkl. seines eigenen Innenabstands
       (box-sizing: border-box), die .card-Boxen darin sind dadurch effektiv
       nur 720px - 2*1.25rem breit. Denselben Abzug hier anwenden, sonst wäre
       die Fußzeile trotz gleichem max-width sichtbar breiter als die Boxen. */
    max-width: calc(720px - 2 * 1.25rem);
    margin: 2rem auto;
    text-align: center;
    color: var(--color-muted);
    font-size: 0.85rem;
    padding: 1.75rem 1.25rem;
    /* Deckender Hintergrund statt direkt auf dem Seitenhintergrund - auf der
       Startseite läuft dort die fest positionierte Foto-Diashow (siehe
       .cb-slideshow), auf der der graue --color-muted-Text sonst kaum lesbar
       war. */
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}

footer.site-footer a { color: var(--color-muted); }

.site-footer__iata {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.site-footer__iata-logo {
    height: 22px;
    width: auto;
}

/* --- Angebots-Filter (offers.php) --- */
/* Zweispaltiges Layout: linke Filter-Sidebar (Akkordeon, siehe unten) plus
   rechte Hauptspalte mit Ergebnissen - angelehnt an die Jobsuche-Filterleiste
   auf otto.de/jobs (Wunsch des Nutzers). Auf schmalen Bildschirmen wird die
   Sidebar per Default ausgeblendet und stattdessen als Vollbild-Overlay
   eingeblendet (siehe @media (max-width: 600px) unten). */
.offers-layout {
    display: flex;
    align-items: flex-start;
    gap: 2rem;
    /* Sidebar (260px) + gap (2rem) + Trefferliste (720px, siehe .offers-list)
       ergeben die tatsächlich genutzte Breite - ohne diese Deckelung zieht
       .offers-main als flex:1-Kind sich bis zum Rand des breiten
       .container--wide (1400px) und die 720px schmale Liste/newsletter-cta
       häng(t)en dadurch sichtbar links, mit viel Leerraum rechts daneben. */
    max-width: 1012px;
    margin: 0 auto;
}

.offers-filter-sidebar {
    flex: 0 0 260px;
    position: sticky;
    /* Zusätzlich zum ursprünglichen 1rem-Abstand auch die Höhe der sticky
       nav.topbar einrechnen, sonst würde die Sidebar beim Hochscrollen
       darunter verschwinden statt stehen zu bleiben. */
    top: calc(var(--topbar-height) + 1rem);
    max-height: calc(100vh - var(--topbar-height) - 2rem);
    overflow-y: auto;
}

/* Nur im mobilen Overlay sichtbar (siehe @media (max-width: 600px) unten) -
   auf Desktop steht die Sidebar direkt im Seitenfluss und braucht keinen
   eigenen Titel/Schließen-Button. */
.offers-filter-sidebar__header {
    display: none;
}

.offers-filter-backdrop {
    display: none;
}

.offers-main {
    flex: 1 1 0;
    min-width: 0;
}

/* "Filter anzeigen"-Button, öffnet die Sidebar als Vollbild-Overlay - nur
   auf schmalen Bildschirmen sichtbar (siehe @media (max-width: 600px)
   unten), auf Desktop übernimmt die immer sichtbare Sidebar dieselbe
   Aufgabe. */
.offers-filter-toggle {
    display: none;
}

.offers-results-header {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-bottom: 1.25rem;
}

.offers-results-count {
    margin: 0;
    font-size: 1.1rem;
    font-weight: 700;
}

/* Ein Chip pro aktuell angewendetem Filterwert plus ein "Alle Filter
   löschen"-Link (siehe $activeFilterChips in offers.php) - entspricht den
   entfernbaren Filter-Chips über der Trefferliste auf otto.de/jobs. Jeder
   Chip ist ein einfacher Link auf dieselbe Auswahl ohne den einen Wert (siehe
   offers_filter_chip_url() in offers.php), funktioniert also auch ohne JS. */
.offers-active-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.offers-active-filters__chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.7rem;
    background: var(--color-primary);
    color: #fff;
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 600;
    text-decoration: none;
}

.offers-active-filters__chip:hover {
    background: var(--color-primary-dark);
}

.offers-active-filters__clear {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--color-muted);
    text-decoration: underline;
}

.offers-active-filters__clear:hover {
    color: var(--color-text);
}

/* --- Filter-Akkordeon (linke Sidebar) --- */
/* Jeder Filterabschnitt ist ein natives <details> (siehe offers.php), damit
   sich mehrere Abschnitte unabhängig voneinander und ohne eigenes JS
   auf-/zuklappen lassen - wie die Akkordeon-Filter auf otto.de/jobs. Die
   Auswahl selbst wird weiterhin erst per "Filter anwenden"-Button
   übernommen, nicht live bei jedem Kontrollkästchen-Klick. */
.offers-accordion {
    display: flex;
    flex-direction: column;
}

.offers-accordion__item {
    border-bottom: 1px solid var(--color-border);
}

.offers-accordion__item:first-child {
    border-top: 1px solid var(--color-border);
}

.offers-accordion__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.9rem 0;
    font-weight: 700;
    cursor: pointer;
    list-style: none;
}

.offers-accordion__header::-webkit-details-marker {
    display: none;
}

.offers-accordion__chevron {
    flex-shrink: 0;
    color: var(--color-muted);
    transition: transform 0.15s ease;
}

.offers-accordion__item[open] .offers-accordion__chevron {
    transform: rotate(180deg);
}

.offers-accordion__panel {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 0.1rem 0 1rem 0.75rem;
    margin-bottom: 0.25rem;
    border-left: 2px solid var(--color-border);
}

.offers-accordion__options {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-height: 220px;
    overflow-y: auto;
}

.offers-accordion__option {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 400;
    font-size: 0.9rem;
    cursor: pointer;
}

.offers-accordion__option-label {
    flex: 1;
}

.offers-accordion__option-country {
    color: var(--color-muted);
    font-size: 0.8rem;
    white-space: nowrap;
}

.offers-accordion__search {
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-size: 0.9rem;
}

.offers-accordion__empty {
    margin: 0;
    color: var(--color-muted);
    font-size: 0.85rem;
}

.offers-filter-sidebar__actions {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding-top: 1rem;
}

.offers-filter-sidebar__actions .btn {
    margin-top: 0;
}

.filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    align-items: flex-end;
}

.filter-field {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    min-width: 200px;
}

/* Zwingt zwei Felder (z. B. Start-/Enddatum im "Neues Angebot"-Formular) in
   eine gemeinsame Reihe, unabhängig davon, wie die übrigen .filter-field-
   Elemente im umgebenden .filter-bar umbrechen. */
.filter-field-pair {
    display: flex;
    flex: 1 1 100%;
    flex-wrap: wrap;
    gap: 1.25rem;
}

.filter-field-pair .filter-field {
    flex: 1 1 0;
    min-width: 140px;
}

/* --- Flughafen-Suche (Angebot-anlegen-Formular) --- */
.airport-picker {
    position: relative;
}

.airport-picker__results {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 20;
    margin: 0;
    padding: 0.35rem;
    list-style: none;
    max-height: 240px;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 6px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.18);
}

.airport-picker__option {
    display: block;
    width: 100%;
    text-align: left;
    background: none;
    border: none;
    padding: 0.5rem 0.6rem;
    border-radius: 4px;
    font-size: 0.9rem;
    font-weight: 400;
    color: var(--color-text);
    cursor: pointer;
}

.airport-picker__option:hover,
.airport-picker__option.is-active {
    background: var(--color-bg);
}

.airport-picker__empty {
    padding: 0.5rem 0.6rem;
    font-size: 0.85rem;
    color: var(--color-muted);
}

/* --- Ziel-Stadtsuche (booking-inquiry.php, assets/js/city-picker.js) ---
   Nutzt denselben .airport-picker-Rahmen wie oben, aber jede Option zeigt
   Stadt (Hauptinformation) und Land (Zusatzinfo) auf zwei Zeilen statt
   einer einzelnen Textzeile. */
.city-picker__option {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.city-picker__option-city {
    font-weight: 600;
}

.city-picker__option-country {
    font-size: 0.8rem;
    color: var(--color-muted);
}

/* --- Ziel-Mehrfachauswahl (Newsletter-Formular, offers.php) --- */
.destination-picker__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-bottom: 0.4rem;
}

.destination-picker__chips:empty {
    margin-bottom: 0;
}

.destination-picker__chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.5rem;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    font-size: 0.85rem;
}

.destination-picker__chip-remove {
    background: none;
    padding: 0;
    margin: 0;
    width: 1.1rem;
    height: 1.1rem;
    line-height: 1.1rem;
    text-align: center;
    font-size: 0.95rem;
    color: var(--color-muted);
    flex-shrink: 0;
}

.destination-picker__chip-remove:hover {
    color: var(--color-text);
}

/* --- Newsletter-Hinweis (offers.php) - bewusst auffällig gestaltet (Akzentfarbe
   + linker Rahmen), da der Hinweis sonst neben den Angebotskarten untergeht. */
.newsletter-cta {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.95rem;
    text-align: left;
    background: rgba(var(--color-primary-rgb), 0.1);
    border: 1px solid rgba(var(--color-primary-rgb), 0.35);
    border-left: 4px solid var(--color-primary);
    border-radius: var(--radius);
    max-width: 720px;
    padding: 0.8rem 1.1rem;
    margin: 0 0 1.5rem;
    color: var(--color-text);
}

.newsletter-cta__icon {
    flex-shrink: 0;
    color: var(--color-primary);
}

.newsletter-cta a {
    font-weight: 700;
    text-decoration: underline;
}

/* Untereinander statt nebeneinander, da der Akkordeon-Abschnitt in der
   ~260px schmalen Filter-Sidebar (siehe offers.php) nicht breit genug für
   zwei Datumsfelder in einer Reihe ist. */
.filter-date-range {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.filter-date-range__field {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-size: 0.85rem;
    font-weight: 600;
}

.filter-date-range input[type="date"] {
    width: 100%;
    padding: 0.55rem 0.6rem;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-size: 0.9rem;
    font-weight: 400;
}

.filter-actions {
    flex: 1 1 100%;
    flex-direction: row;
    align-items: center;
    gap: 0.6rem;
}

.filter-actions .btn {
    margin-top: 0;
}

/* --- Angebote (offers.php) --- */
/* Eine Zeile pro Angebot statt einer Kachel-Grid (frühere .offers-grid/
   .offer-card) - explizite Nutzer-Vorgabe, angelehnt an eine klassische
   Jobbörsen-Listenansicht (Logo links, Inhalt in der Mitte, Aktionen rechts).
   Die Liste steckt in einer .card (wiederverwendet statt einer eigenen
   Container-Optik), die einzelnen Zeilen trennen sich nur durch eine
   Trennlinie, nicht durch je eine eigene Box. */
.offers-list,
.offers-empty {
    max-width: 720px;
}

.offers-list {
    padding-top: 0;
    padding-bottom: 0;
}

/* Unsichtbarer Marker am Ende der Angebotsliste (siehe #offers-load-more-
   sentinel in offers.php) - der IntersectionObserver in
   assets/js/offers-filter.js löst das Nachladen der nächsten Seite aus,
   sobald dieses Element ins Sichtfeld scrollt. Keine eigene Höhe/Optik
   nötig, nur als Scroll-Trigger gebraucht. */
.offers-load-more-sentinel {
    max-width: 720px;
    height: 1px;
}

.offers-load-more-status {
    max-width: 720px;
    margin: 1rem auto 0;
    text-align: center;
    color: var(--color-muted);
}

.offer-row {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    padding: 1.5rem 0;
    border-bottom: 1px solid var(--color-border);
    cursor: pointer;
    border-radius: var(--radius);
}

.offer-row:hover,
.offer-row:focus-visible {
    background: rgba(var(--color-primary-rgb), 0.06);
}

.offer-row:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: -2px;
}

.offers-list > .offer-row:last-child {
    border-bottom: none;
}

/* Diagonales Eck-Banner für "customer_exclusive"-Angebote (siehe offers.php,
   Admin-Checkbox "Nur eingeloggten Kund:innen anzeigen"). Eigene, quadratische
   Clip-Box (...-flare-wrap) statt overflow: hidden direkt auf .offer-row: so
   schneidet nur diese kleine Ecke die überstehenden Bannerspitzen sauber ab,
   ohne z. B. den Fokus-Rahmen oder Schatten der Admin-Aktionsbuttons
   mitabzuschneiden. Bannerbreite (120px) entspricht bewusst ungefähr der
   Diagonale der 90x90px-Box (90 * √2 ≈ 127px) - der Text läuft dadurch von
   Eck-Spitze zu Eck-Spitze durch, statt durch die 45°-Drehung an einem Ende
   (dort, wo die Box sonst zu früh abschneidet) verstümmelt zu werden. */
.offer-row--exclusive {
    position: relative;
}

.offer-row__exclusive-flare-wrap {
    position: absolute;
    top: 0;
    right: 0;
    width: 90px;
    height: 90px;
    overflow: hidden;
    pointer-events: none;
}

.offer-row__exclusive-flare {
    position: absolute;
    top: 18px;
    right: -28px;
    width: 120px;
    padding: 0.2rem 0;
    background: var(--color-primary);
    color: #fff;
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    text-align: center;
    transform: rotate(45deg);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
}

/* Feste Box links (Logo, siehe get_airline_logo_url() in includes/offers.php) -
   feste Breite/Höhe, damit alle Zeilen unabhängig vom jeweiligen Logo-
   Seitenverhältnis exakt fluchten. Wird nur gerendert, wenn ein Logo
   existiert (siehe offers.php) - ohne Logo rutscht der Inhalt einfach nach.
   links, statt eine leere Box vorzuhalten. */
.offer-row__logo {
    flex: 0 0 auto;
    width: 88px;
    height: 64px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.5rem;
}

.offer-row__logo img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/* 3 Kacheln pro Zeile (fester Grid statt Flex, sonst hätten die 200px
   breiten Kacheln bei der Card-Innenbreite von ~624px nur zu zweit
   nebeneinander gepasst, siehe .card-Innenabstand oben) - danach Umbruch in
   die nächste Zeile. Auf schmalen Bildschirmen auf 2 Spalten reduziert
   (siehe @media (max-width: 600px) unten), sonst wären die Kacheln dort zu
   schmal für die Logos. */
.partners-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
}

.partners-section-heading {
    margin-top: 2rem;
}

.partners-grid__item {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 120px;
    padding: 1rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.partners-grid__item:hover {
    border-color: var(--color-primary);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.partners-grid__item img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.offer-row__body {
    flex: 1 1 auto;
    min-width: 0;
}

.offer-row__airline-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.offer-row__airline {
    color: var(--color-muted);
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.offer-row__route {
    font-size: 1.15rem;
    color: var(--color-primary);
    margin: 0.2rem 0 0;
}

.offer-row__airport-detail {
    display: block;
    color: var(--color-muted);
    font-size: 0.75rem;
    margin-top: 0.15rem;
}

.offer-row__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1.25rem;
    margin-top: 0.6rem;
}

.offer-row__meta-item {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--color-muted);
    font-size: 0.85rem;
}

.offer-row__meta-item svg {
    flex: 0 0 auto;
    color: var(--color-primary);
}

/* Datum bleibt als zusammenhängendes Paar auf einer Zeile, statt bei
   schmalen Bildschirmen mitten im Datum umzubrechen. */
.offer-row__date-range {
    white-space: nowrap;
}

.offer-row__actions {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.offer-row__edit-btn,
.offer-row__delete-btn {
    margin-top: 0;
    padding: 0.4rem 0.9rem;
    font-size: 0.8rem;
}

/* --- Newsletter-Anmeldungen (account.php) - eine Zeile pro abonniertem
   Reiseziel, nicht pro newsletter_subscriptions-Zeile, siehe
   get_user_newsletter_destinations() in includes/newsletter.php. */
.newsletter-sub-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.9rem 0;
    border-bottom: 1px solid var(--color-border);
}

.newsletter-sub-list > .newsletter-sub-item:last-child {
    border-bottom: none;
}

.newsletter-sub-item__city {
    font-weight: 600;
}

.newsletter-sub-item__meta {
    display: block;
    color: var(--color-muted);
    font-size: 0.8rem;
    margin-top: 0.15rem;
}

.newsletter-sub-item__actions {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex: 0 0 auto;
}

.newsletter-sub-item__lang-form {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
}

.newsletter-sub-item__lang-select {
    width: auto;
    padding: 0.4rem 0.6rem;
    font-size: 0.8rem;
}

.newsletter-sub-item__lang-btn {
    margin-top: 0;
    padding: 0.4rem 0.9rem;
    font-size: 0.8rem;
}

.newsletter-sub-item__unsubscribe-form {
    flex: 0 0 auto;
    margin: 0;
}

.newsletter-sub-item__unsubscribe-btn {
    margin-top: 0;
    padding: 0.4rem 0.9rem;
    font-size: 0.8rem;
}

/* --- Eigene Buchungsanfragen (travels.php), siehe booking_inquiries in
   includes/db.php - eine Karte pro Anfrage, gleiches Grundmuster wie
   .news-item/.newsletter-sub-item oben. */
.travel-list {
    display: flex;
    flex-direction: column;
}

.travel-item {
    padding: 1.25rem 0;
    border-bottom: 1px solid var(--color-border);
}

.travel-list > .travel-item:last-child {
    border-bottom: none;
}

.travel-item__route {
    margin: 0 0 0.5rem;
    font-size: 1.05rem;
}

.travel-item__meta {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 0.35rem 1rem;
    margin: 0;
}

.travel-item__meta dt {
    color: var(--color-muted);
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.travel-item__meta dd {
    margin: 0;
}

.badge {
    display: inline-block;
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    background: var(--color-badge-bg);
    color: var(--color-primary);
    font-size: 0.8rem;
    font-weight: 600;
}

/* Pille für "neue" Angebote (siehe offer_is_new() in includes/offers.php,
   Angebote der letzten OFFER_NEW_THRESHOLD_DAYS Tage) - sitzt inline direkt
   neben dem Airline-Namen statt als Eck-Banner, damit sie sich mit dem
   diagonalen "customer_exclusive"-Banner (oben rechts, siehe
   .offer-row__exclusive-flare) niemals überlappen kann; Sekundärfarbe statt
   Primärfarbe macht den Unterschied zum normalen .badge auch auf den ersten
   Blick eindeutig. */
.badge--new {
    background: rgba(var(--color-secondary-rgb), 0.12);
    color: var(--color-secondary-dark);
}

/* Pille für abgelaufene Angebote, nur sichtbar für Admins über "Auch
   abgelaufene Angebote anzeigen" (siehe includes/offers.php,
   search_offers()) - neutrales Grau statt Primär-/Sekundärfarbe, damit sie
   klar als "kein normaler Zustand" von .badge/.badge--new abgesetzt ist. */
.badge--expired {
    background: var(--color-border);
    color: var(--color-muted);
}

/* Pille für Blitzangebote (offers.is_lightning_offer, Admin-Checkbox im
   "Neues Angebot"/Bearbeiten-Formular) - eigener Amber-Ton statt Primär-/
   Sekundärfarbe, da beide bereits für .badge/.badge--new belegt sind und
   diese Pille auf denselben Karten gleichzeitig neben "Neu" stehen können
   muss, ohne farblich zu verschmelzen. */
.badge--lightning {
    background: var(--color-lightning-bg);
    color: var(--color-lightning-text);
}

/* --- FAQ (faq.php) --- */
/* Jeder Eintrag ein natives <details>, eigener Rahmen/Innenabstand statt nur
   in der umgebenden .card zu stecken (anders als .admin-collapsible unten,
   das dasselbe +/- Muster ohne eigenen Rahmen wiederverwendet). */
.faq-item {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1rem 1.25rem;
    margin-bottom: 0.75rem;
}

.faq-item:last-child {
    margin-bottom: 0;
}

.faq-item__question {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    font-weight: 600;
}

.faq-item__question::-webkit-details-marker {
    display: none;
}

.faq-item__question::after {
    content: '+';
    flex: 0 0 auto;
    font-size: 1.3rem;
    color: var(--color-primary);
}

.faq-item[open] .faq-item__question::after {
    content: '\2212';
}

.faq-item__answer {
    margin: 1rem 0 0;
}

/* --- Admin-Übersicht (admin.php) --- */
/* Aufklappbare Sektionen mit per JS nachgeladenem Inhalt (siehe
   assets/js/admin-lazy-sections.js) - gleiches +/- Muster wie .faq-item, nur
   ohne dessen eigenen Rahmen/Innenabstand (steckt hier bereits in der
   umgebenden .card). */
.admin-collapsible__toggle {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}

.admin-collapsible__toggle::-webkit-details-marker {
    display: none;
}

.admin-collapsible__toggle h2 {
    margin: 0;
}

.admin-collapsible__toggle::after {
    content: '+';
    flex: 0 0 auto;
    font-size: 1.3rem;
    color: var(--color-primary);
}

.admin-collapsible[open] .admin-collapsible__toggle::after {
    content: '\2212';
}

.admin-collapsible__content {
    margin-top: 1rem;
}

.admin-table-wrap {
    /* Tabellen mit vielen Spalten dürfen auf schmalen Bildschirmen NICHT die
       ganze Seite horizontal aufreißen - nur die Tabelle selbst scrollt. */
    overflow-x: auto;
}

/* Wird per JS gesetzt, solange eines der Spaltenkopf-Filter-Popover offen ist
   (siehe assets/js/admin-lazy-sections.js, updatePopoverOverflowState()) -
   overflow-x: auto oben zwingt den Browser laut CSS-Spec dazu, auch
   overflow-y implizit auf "auto" zu setzen, wodurch ein geöffnetes, meist
   höheres Popover am unteren Rand des Wraps abgeschnitten wurde. Diese
   Klasse hebt die Beschneidung währenddessen gezielt auf; das horizontale
   Scrollen der Tabelle selbst fehlt in diesem kurzen Moment, was unkritisch
   ist, da man dann ohnehin im Popover statt in der Tabelle interagiert. */
.admin-table-wrap--popover-open {
    overflow: visible;
}

.admin-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9rem;
}

.admin-table th,
.admin-table td {
    padding: 0.6rem 0.75rem;
    text-align: left;
    border-bottom: 1px solid var(--color-border);
    white-space: nowrap;
}

/* Freitext-Spalten (z. B. Nachricht der Missbrauchsmeldungen, siehe
   admin-fragment.php) überschreiben das nowrap oben gezielt - anders als
   Datum/E-Mail/IP soll hier langer, mehrzeiliger Nutzertext weder in eine
   einzige, weit scrollende Zeile gequetscht noch die eingegebenen
   Zeilenumbrüche stillschweigend verschlucken (white-space: pre-line wie bei
   .offer-details dd in style.css, dasselbe Muster). */
.admin-table td.admin-table__wrap {
    white-space: pre-line;
    max-width: 320px;
}

.admin-table th {
    color: var(--color-muted);
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.admin-table__actions {
    display: flex;
    gap: 0.5rem;
    white-space: nowrap;
}

.admin-table__actions form {
    margin: 0;
}

/* Pro-Zeile-Eingabe zum Setzen/Ändern der Kundennummer in der "Bestätigte
   Konten"-Sektion (siehe admin-fragment.php) - bewusst ein <div>, KEIN
   verschachteltes <form> (Eingabe/Button referenzieren stattdessen per
   form="cn-edit-<id>" ein eigenständiges <form> außerhalb der Tabelle, siehe
   dort für den Grund). Textfeld PLUS Button nebeneinander, daher eigene
   Flex-Regel statt der geerbten. Feste Eingabefeldbreite verhindert, dass
   das Feld die gesamte verfügbare Zellenbreite ausfüllt und den
   Speichern-Button aus der Zeile drängt. */
.admin-table__inline-edit {
    display: flex;
    gap: 0.4rem;
    align-items: center;
    margin: 0;
}

.admin-table__inline-edit input[type="text"] {
    width: 110px;
}

/* Klickbare Spaltenköpfe mit Filter-/Sortier-Popover ("Destinations",
   "Travel class", "Travel dates", "Account linked" in der Newsletter-
   Übersicht, siehe admin-fragment.php) - dasselbe <details>/<summary>-Muster
   wie .admin-collapsible/.profile-menu oben, hier aber als schwebendes
   Popover unterhalb des jeweiligen Spaltenkopfs statt als Akkordeon-Sektion
   bzw. Navigationsmenü. */
.admin-table__th-filterable {
    position: relative;
}

.admin-table__filter-toggle {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
}

.admin-table__filter-toggle::-webkit-details-marker {
    display: none;
}

/* Der Spaltenkopf selbst ist per .admin-table th oben in Großbuchstaben mit
   Buchstabenabstand formatiert - im Popover-Inhalt (normale Checkbox-/
   Formularbeschriftungen) wird das gezielt wieder zurückgesetzt. */
.admin-table__filter-dropdown {
    position: absolute;
    top: calc(100% + 0.5rem);
    left: 0;
    z-index: 20;
    /* Breit genug, dass die längste vorkommende Übersetzung der beiden
       Sortier-Buttons (z. B. Französisch "Trier par ordre décroissant") auf
       EINER Zeile Platz hat, siehe .admin-table__filter-sort unten - vorher
       waren die Popover mit max-width: 280px zu schmal dafür, wodurch die
       Button-Beschriftungen mitten im Wort umgebrochen sind und alles
       gequetscht wirkte. */
    min-width: 260px;
    max-width: 320px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
    padding: 0.75rem;
    text-transform: none;
    letter-spacing: normal;
    font-weight: 400;
    white-space: normal;
}

/* Die beiden Sortier-Buttons UNTEREINANDER statt nebeneinander - bei
   nebeneinander müssten beide zusammen in die Popover-Breite passen, was bei
   den längeren Übersetzungen (v. a. Französisch/Polnisch) selbst bei einem
   deutlich breiteren Popover eng würde. Volle Breite je Button ist zugleich
   eine größere, leichter treffbare Klickfläche. */
.admin-table__filter-sort {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin-bottom: 0.6rem;
}

.admin-table__filter-sort .btn,
.admin-table__filter-actions .btn {
    padding: 0.35rem 0.6rem;
    font-size: 0.8rem;
    margin-top: 0;
    white-space: nowrap;
}

.admin-table__filter-sort .btn {
    width: 100%;
}

.admin-table__filter-options {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    max-height: 200px;
    overflow-y: auto;
    font-size: 0.85rem;
    margin-bottom: 0.6rem;
}

.admin-table__filter-options label {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-weight: 400;
    cursor: pointer;
}

.admin-table__filter-options--dates label {
    align-items: flex-start;
    flex-direction: column;
    gap: 0.2rem;
}

.admin-table__filter-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.4rem;
}

/* Einfacher horizontaler Balken für die "Beliebteste Wunschziele"-Übersicht
   (admin.php) - Breite relativ zum Ziel mit den meisten Anmeldungen (100%),
   damit die Nachfrage auf einen Blick vergleichbar ist, ohne ein Chart-Skript
   einzubinden. Die tatsächliche Breite kommt NICHT aus einem inline
   style="width: ..."-Attribut - die strikte CSP (style-src 'self', kein
   unsafe-inline, siehe config.php) blockiert JEDES style=""-Attribut
   genauso wie ein <style>-Block, auch wenn nur ein einzelner width-Wert
   drinsteht. Stattdessen steht der Prozentwert als data-fill-percent auf
   .admin-stat-bar__fill (siehe admin.php) und wird erst per JS gesetzt
   (assets/js/admin-stat-bars.js) - das Setzen von .style.width per
   JavaScript-CSSOM-Zugriff ist NICHT von style-src betroffen (nur
   script-src greift dort), anders als ein serverseitig gerenderter
   style=""-Attributwert. width: 0 unten ist der Standardwert, falls JS aus
   irgendeinem Grund nicht läuft - dann bleibt der Balken sichtbar leer statt
   fälschlich voll auszusehen. */
.admin-stat-bar-cell {
    width: 40%;
}

.admin-stat-bar {
    display: block;
    height: 0.6rem;
    border-radius: 999px;
    background: var(--color-border);
    overflow: hidden;
}

.admin-stat-bar__fill {
    display: block;
    width: 0;
    height: 100%;
    background: var(--color-primary);
    border-radius: 999px;
}

.admin-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    margin-top: 1rem;
}

.admin-pagination .btn.is-disabled {
    opacity: 0.5;
    cursor: default;
    pointer-events: none;
}

/* Seiten mit Layouts, die nicht in die sonst übliche schmale, mobil
   orientierte .container-Breite (720px) passen - aktuell admin.php
   (mehrspaltige Tabellen) und offers.php (Filter-Sidebar + Trefferliste
   nebeneinander, siehe .offers-layout). .container--wide wird nur gesetzt,
   wenn $pageWide in der jeweiligen Seite auf true steht (siehe
   includes/header.php); alle anderen Seiten bleiben unverändert
   mobile-first. */
.container--wide {
    max-width: 1400px;
}

/* Zwei kompakte Tabellen-Karten (unbestätigte Konten, Wunschziel-Statistik),
   die auf breiten Bildschirmen nebeneinander passen. Mobile-first wie der
   Rest der Seite: Standard ist eine Spalte (identisch zur vorherigen
   Stapel-Ansicht), erst ab min-width: 900px rücken beide Karten
   nebeneinander - das große Layout ist also eine reine Erweiterung, keine
   Abweichung vom mobilen Grundzustand. */
.admin-grid-2col {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.5rem;
}

.admin-grid-2col > .card {
    margin-bottom: 0;
}

@media (min-width: 900px) {
    .admin-grid-2col {
        grid-template-columns: 1fr 1fr;
        align-items: start;
    }
}

/* --- Angebot-Detail-Modal (offers.php, "Details anzeigen") --- */
.offer-details {
    margin: 0.5rem 0 0;
}

.offer-details dt {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    color: var(--color-muted);
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin-top: 1rem;
}

.offer-details dt:first-child {
    margin-top: 0;
}

/* Hover-/Fokus-Tooltip für erklärungsbedürftige Detail-Labels (z. B.
   "Reisezeitraum" im Angebots-Detail-Popup) - normalgewichtig/nicht
   Großbuchstaben, damit er sich klar vom umgebenden dt-Label abhebt. */
.info-icon {
    position: relative;
    display: inline-flex;
    align-items: center;
    color: var(--color-muted);
    cursor: help;
}

.info-icon__tooltip {
    position: absolute;
    left: 50%;
    top: calc(100% + 0.5rem);
    transform: translateX(-50%);
    width: max-content;
    max-width: 220px;
    background: var(--color-text);
    color: var(--color-surface);
    font-size: 0.75rem;
    font-weight: 400;
    text-transform: none;
    letter-spacing: normal;
    white-space: normal;
    padding: 0.4rem 0.6rem;
    border-radius: 6px;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.15s ease;
    z-index: 5;
}

.info-icon:hover .info-icon__tooltip,
.info-icon:focus .info-icon__tooltip,
.info-icon:focus-visible .info-icon__tooltip {
    opacity: 1;
    visibility: visible;
}

.offer-details dd {
    margin: 0.2rem 0 0;
    white-space: pre-line;
}

.offer-details-fare-wrap {
    margin-top: 1.25rem;
    border-top: 1px solid var(--color-border);
    padding-top: 0.75rem;
}

/* Stornobedingungen und Buchungs-Button auf gleicher Höhe statt der Button
   als eigener Block darunter - eigenes zweites dl statt im dl darüber, damit
   nur diese eine dt/dd-Zeile neben dem Button steht (siehe offers.php).
   flex-wrap, damit lange Stornotexte auf schmalen Bildschirmen den Button
   in die nächste Zeile schieben statt ihn zu quetschen. */
.offer-details-footer {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 0.75rem 1rem;
    margin-top: 1rem;
}

.offer-details-footer__cancellation {
    flex: 1 1 200px;
    min-width: 0;
}

.offer-details__book-btn {
    flex: 0 0 auto;
    margin: 0;
}

.offer-details-fare-wrap summary {
    cursor: pointer;
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--color-primary);
}

.offer-details-fare-wrap[open] summary {
    margin-bottom: 0.25rem;
}

.offer-details-fare dt {
    font-size: 0.75rem;
}

.offer-details-fare dd {
    font-size: 0.9rem;
}

/* --- Kontakt (contact.php) --- */
.contact-info {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin: 1.25rem 0;
}

.contact-info__item {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
}

.contact-info__item svg {
    flex: 0 0 auto;
    color: var(--color-primary);
    margin-top: 0.15rem;
}

.contact-info__label {
    display: block;
    font-weight: 600;
}

.contact-info__value {
    color: var(--color-muted);
}

.contact-info__value .nowrap {
    white-space: nowrap;
}

.entrance-photo {
    margin: 1.25rem 0;
}

.entrance-photo img {
    display: block;
    width: 100%;
    max-width: 480px;
    border-radius: var(--radius);
    border: 1px solid var(--color-border);
}

.doorbell-video {
    margin: 1.25rem 0;
}

.doorbell-video video {
    display: block;
    width: 100%;
    max-width: 480px;
    border-radius: var(--radius);
    border: 1px solid var(--color-border);
}

.map-embed {
    position: relative;
    width: 100%;
    padding-top: 56.25%; /* 16:9 */
    border-radius: var(--radius);
    overflow: hidden;
    border: 1px solid var(--color-border);
    margin: 1.25rem 0;
}

.map-embed iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

/* --- Mobile-Optimierung --- */
@media (max-width: 600px) {
    .container {
        padding: 1.25rem 1rem;
    }

    .card {
        padding: 1.25rem;
    }

    h1 { font-size: 1.35rem; }
    h2 { font-size: 1.1rem; }

    .partners-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .field-row {
        flex-direction: column;
        align-items: stretch;
    }

    /* Popup-Formulare auf offers.php (Newsletter-Anmeldung, Angebot anlegen/
       bearbeiten, Excel-Import - siehe .filter-bar dort): jedes Feld nimmt
       die volle Breite ein, statt als schmale ~200px-Insel mit ungenutztem
       Platz daneben stehen zu bleiben. Nur direkte Kinder von .filter-bar -
       .filter-field-pair (Start-/Enddatum) regelt die eigene Aufteilung
       selbst (siehe dort) und soll hier nicht überschrieben werden. */
    .filter-bar > .filter-field {
        width: 100%;
    }

    /* Apply/Reset (Filter) bzw. der Submit-Button (Angebot anlegen) stehen
       gestapelt statt sich als zwei "width: 100%"-Buttons in einer Reihe
       gegenseitig auf ca. die Hälfte zusammenzudrücken. */
    .filter-actions {
        flex-direction: column;
        align-items: stretch;
    }

    /* Angebotszeile (offers.php): Logo/Inhalt/Aktionen stehen auf schmalen
       Bildschirmen untereinander statt sich in einer Reihe gegenseitig eng
       zusammenzudrücken. Das Logo bleibt oben links statt volle Breite
       einzunehmen (sähe bei einem kleinen Logo auf einer breiten Zeile
       verloren aus). */
    .offer-row {
        flex-wrap: wrap;
    }

    .offer-row__logo {
        width: 64px;
        height: 48px;
    }

    .offer-row__actions {
        width: 100%;
        margin-top: 0.75rem;
    }

    .offer-row__edit-btn,
    .offer-row__delete-btn {
        width: 100%;
    }

    /* Newsletter-Anmeldungen (account.php): gleiches Umbruch-Muster wie
       .offer-row__actions oben - Ziel-Info und Sprache-/Abbestellen-Aktionen
       untereinander statt eng nebeneinander. */
    .newsletter-sub-item {
        flex-wrap: wrap;
    }

    .newsletter-sub-item__actions {
        width: 100%;
        flex-direction: column;
        align-items: stretch;
        margin-top: 0.5rem;
    }

    .newsletter-sub-item__lang-form {
        width: 100%;
    }

    .newsletter-sub-item__lang-select {
        width: 100%;
    }

    .newsletter-sub-item__lang-btn {
        width: 100%;
    }

    .newsletter-sub-item__unsubscribe-form {
        width: 100%;
    }

    .newsletter-sub-item__unsubscribe-btn {
        width: 100%;
    }

    /* News-Einträge (index.php): Bearbeiten/Löschen stehen auf schmalen
       Bildschirmen untereinander statt sich nebeneinander zu quetschen -
       die globale "button, .btn { width: 100% }"-Regel würde beide sonst
       auf 100% der ohnehin schon schmalen Flex-Reihe zwingen. */
    .news-item__actions {
        flex-direction: column;
    }

    nav.topbar {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 0.75rem;
        padding: 0.75rem 1rem;
    }

    nav.topbar a {
        margin-left: 0;
        margin-right: 0;
    }

    .topbar__nav {
        flex-wrap: wrap;
        justify-content: center;
        gap: 0.6rem;
    }

    .topbar__right {
        justify-content: center;
    }

    /* Auf Desktop steht das Profil-Icon am rechten Rand, wodurch "right: 0"
       (siehe Basis-Regel oben) das Dropdown bündig mit dem Container-Rand
       ausrichtet. Auf Mobile steht die Topbar zentriert (siehe .topbar__right
       oben), wodurch dasselbe "right: 0" das Dropdown links über den
       Bildschirmrand hinausschieben würde - hier stattdessen unter dem Icon
       zentrieren und die Breite auf die Fensterbreite begrenzen. */
    .profile-menu__dropdown {
        left: 50%;
        right: auto;
        transform: translateX(-50%);
        min-width: 180px;
        max-width: calc(100vw - 2rem);
    }

    button, .btn {
        width: 100%;
        padding: 0.75rem 1rem;
        font-size: 1rem;
    }

    .btn-primary { margin-top: 1rem; }

    dialog.modal {
        width: calc(100% - 1.5rem);
        padding: 1.25rem;
    }

    .modal__close {
        width: 2rem;
        padding: 0;
    }

    /* Gleiches Muster wie .modal__close oben - ohne dieses Override würde die
       generische "button, .btn { width: 100% }"-Regel den Umschalter auf die
       volle Breite der Topbar-Zeile strecken und Profil-Icon/Sprachauswahl
       jeweils in eine eigene Zeile zwingen, statt nebeneinander zu bleiben. */
    .theme-toggle {
        width: auto;
        padding: 0;
    }

    #cookie-banner {
        flex-direction: column;
        align-items: stretch;
        padding: 1rem;
    }

    #cookie-banner p {
        max-width: none;
    }

    #cookie-banner .cookie-actions {
        flex-direction: column-reverse;
        width: 100%;
    }

    #cookie-banner .cookie-actions button {
        width: 100%;
    }

    /* Angebots-Filter (offers.php): die Sidebar steht auf schmalen
       Bildschirmen nicht mehr nebeneinander mit der Trefferliste (wäre bei
       voller Feldbreite zu eng), sondern wird per "Filter anzeigen"-Button
       als Vollbild-Overlay eingeblendet - analog zum "Filter anzeigen"-Button
       auf otto.de/jobs. Öffnen/Schließen übernimmt assets/js/offers-filter.js
       per .is-open-Klasse auf #offers-filter-sidebar/#offers-filter-backdrop. */
    .offers-layout {
        display: block;
    }

    /* Schwebt fest über der Trefferliste statt oben im normalen Textfluss zu
       stehen, damit die Filter beim Durchscrollen der Angebote jederzeit
       erreichbar bleiben, ohne erst nach oben zurückscrollen zu müssen -
       ähnliches Muster wie der frühere #filter-scroll-btn. Bleibt unter der
       Filter-Sidebar/ihrem Overlay (z-index: 55/60 oben), die beim Öffnen
       ohnehin deckend darüberliegt und den Button so automatisch verdeckt. */
    .offers-filter-toggle {
        display: flex;
        position: fixed;
        right: 1.25rem;
        bottom: 1.25rem;
        z-index: 50;
        width: auto;
        align-items: center;
        justify-content: center;
        gap: 0.5rem;
        padding: 0.75rem 1.25rem;
        background: var(--color-primary);
        color: #fff;
        border-radius: 999px;
        box-shadow: 0 6px 18px rgba(0, 0, 0, 0.25);
    }

    .offers-filter-toggle:hover {
        background: var(--color-primary-dark);
    }

    .offers-filter-sidebar {
        display: none;
        position: fixed;
        /* Startet unterhalb der sticky Topbar (z-index: 100, siehe oben)
           statt sie zu verdecken - sonst wären Titel/Schließen-Button ganz
           oben im Overlay unter der Topbar versteckt. */
        top: var(--topbar-height);
        right: 0;
        bottom: 0;
        left: 0;
        z-index: 60;
        max-height: none;
        background: var(--color-surface);
        padding: 1.25rem;
    }

    .offers-filter-sidebar.is-open {
        display: block;
    }

    .offers-filter-sidebar__header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 1rem;
    }

    .offers-filter-sidebar__title {
        font-size: 1.1rem;
        font-weight: 700;
    }

    .offers-filter-sidebar__close {
        width: auto;
        background: none;
        color: var(--color-secondary);
        padding: 0.25rem;
        font-size: 1.5rem;
        line-height: 1;
    }

    .offers-filter-backdrop.is-open {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 55;
        background: rgba(0, 0, 0, 0.5);
    }

    /* Verhindert Hintergrund-Scroll, solange die Filter-Sidebar als Overlay
       offen ist (siehe assets/js/offers-filter.js). */
    body.offers-filter-open {
        overflow: hidden;
    }

    /* Überschreibt dieselbe "button, .btn { width: 100% }"-Regel oben - die
       Zurück/Weiter-Buttons der Admin-Pagination sollen nebeneinander stehen
       statt sich untereinander über die volle Breite zu stapeln. */
    .admin-pagination .btn {
        width: auto;
    }

    /* Gleiches Muster für die "Bestätigen"/"Erneut senden"-Buttons der
       Admin-Übersicht (siehe .admin-table__actions unten) - bleiben
       nebeneinander statt sich zu stapeln. */
    .admin-table__actions .btn {
        width: auto;
    }
}

/* --- Installierte PWA: minimale 2-Tab-App-Oberfläche (Angebote/Profil) ---
   Siehe includes/header.php für die Markup (.app-tabbar, auf jeder Seite
   vorhanden, aber standardmäßig unsichtbar) und manifest.json/
   service-worker.js. Rein CSS-gesteuert über die display-mode-Media-Query -
   keine serverseitige Verzweigung nötig, greift automatisch bei JEDER
   Navigation innerhalb der installierten App, ohne dass ein Query-Parameter
   o. Ä. durchgereicht werden müsste. Verhält sich für normale
   Desktop-/Mobile-Browser-Besucher:innen unverändert (display-mode ist dort
   nie "standalone"). */
.app-tabbar {
    display: none;
}

/* Push-Benachrichtigungen sind App-only (siehe assets/js/push-subscribe.js)
   - dieselbe display-mode-Erkennung wie .app-tabbar oben, nur umgekehrt:
   standardmäßig unsichtbar, erst innerhalb der Media-Query unten wieder
   sichtbar gemacht. Muss VOR dem @media-Block stehen, nicht danach - bei
   gleicher Spezifität gewinnt in CSS die spätere Regel in der
   Quellreihenfolge, ein unconditional "display: none" nach dem @media-Block
   würde die dortige "display: block"-Ausnahme sonst wieder überschreiben. */
.app-only {
    display: none;
}

/* Gegenstück zu .app-only: Text, der nur in der Web-Version stimmt (z. B.
   eine "und Push"-Erwähnung, die es dort mangels App-Kontext gar nicht gibt) -
   standardmäßig sichtbar, erst innerhalb der Media-Query unten ausgeblendet. */
.web-only {
    display: block;
}

@media (display-mode: standalone) {
    nav.topbar,
    .site-footer,
    #cookie-banner {
        display: none;
    }

    .app-tabbar {
        display: flex;
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 100;
        background: var(--color-surface);
        border-top: 1px solid var(--color-border);
        padding-bottom: env(safe-area-inset-bottom);
    }

    .app-tabbar__link {
        flex: 1;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 0.15rem;
        padding: 0.5rem 0 0.4rem;
        color: var(--color-muted);
        font-size: 0.72rem;
        text-decoration: none;
    }

    .app-tabbar__link--active {
        color: var(--color-primary);
    }

    /* Platz für die jetzt fixe Tab-Leiste am unteren Rand, sonst würde der
       letzte Seiteninhalt dahinter verschwinden - analog zur bestehenden
       Regel für die sticky nav.topbar oben (siehe Kommentar dort), nur am
       jeweils anderen Ende der Seite. */
    body {
        padding-bottom: calc(56px + env(safe-area-inset-bottom));
    }

    /* Schwebender "Filter anzeigen"-Button (offers.php) sonst hinter/unter
       der jetzt fixen Tab-Leiste versteckt - gleicher 56px-Wert wie beim
       body-padding oben, plus etwas Abstand zur Tab-Leiste selbst. */
    .offers-filter-toggle {
        bottom: calc(56px + env(safe-area-inset-bottom) + 1rem);
    }

    /* Macht die Push-Karte (siehe .app-only oben) innerhalb der
       installierten App wieder sichtbar. */
    .app-only {
        display: block;
    }

    /* ...und blendet umgekehrt die reine Web-Formulierung aus (siehe
       .web-only oben) - innerhalb der App gilt stattdessen die .app-only-Variante. */
    .web-only {
        display: none;
    }
}
