/**
 * Portal UI (SSOT): Design-Tokens und semantische Komponenten.
 * Bootstrap bleibt Basis; hier nur wiederkehrende Portal-Muster.
 *
 * Nutzung in PHP ausschließlich über portal_ui_class() / portal_ui_page_open() /
 * portal_ui_content_open() / portal_ui_card_open() in shared.php.
 *
 * - Portal-Dashboard: page_dashboard (comfortable) + --portal-dashboard-gap (größer)
 * - App-Inhalt: .portal-app-content (padding = --portal-content-gap, 0.5rem)
 * - Kachel-Grids: .portal-card-grid setzt Gutter auf --portal-content-gap (auch bei g-3)

 * - Kacheln: card / card_header / card_body (1rem) / card_body_dense (Tabellen)
 * - DataTables in Karten: Abstände in .portal-card .dt-container (SSOT)
 * - Navbar-Innenwrapper: container / app_toolbar_inner
 * - Chart-Kacheln: chart_wrap → .portal-chart-wrap (--portal-chart-height 340px)
 */
:root {
    --portal-space-xs: 0.25rem;
    --portal-space-sm: 0.5rem;
    /* App-Standard: Fensterrand + Abstand zwischen Kacheln (wie bVM gx-2 / dense) */
    --portal-content-gap: 0.5rem;
    /* Alias: früher „nur Tabellen“; jetzt = App-Standard (API-Kompatibilität denseX) */
    --portal-content-gap-x-dense: var(--portal-content-gap);
    /* Toolbar-Innenwrapper = gleicher Seitenrand */
    --portal-content-gutter-x: var(--portal-content-gap);
    --portal-card-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1), 0 0.125rem 0.25rem rgba(0, 0, 0, 0.06);
    --portal-card-shadow-hover: 0 0.5rem 1.25rem rgba(0, 0, 0, 0.14), 0 0.25rem 0.5rem rgba(0, 0, 0, 0.08);
    --portal-card-border: var(--bs-border-color-translucent);
    --portal-card-radius: 0.75rem;
    /* Einzelkarten: Abstand oben/seitlich vom Content-Padding; unten = Gap */
    --portal-card-margin-x: 0;
    --portal-card-margin-top: 0;
    --portal-card-margin-bottom: var(--portal-content-gap);
    /* Innenabstand Tabellen-Karten (dicht, aber Controls lesbar) */
    --portal-card-body-dense-pad: var(--portal-space-sm);
    --portal-page-padding-y: var(--portal-space-xs);
    --portal-page-padding-x: var(--portal-space-xs);
    --portal-page-padding-comfortable-y: 1.25rem;
    --portal-page-padding-comfortable-x: 1.5rem;
    /* Portal-Dashboard bewusst größer als App-Kacheln */
    --portal-dashboard-gap: 1rem;
    /* Scroll-Top-Button: Größe/Offset + Mindest-Abstand Inhalt zum Fensterrand */
    --portal-scroll-top-size: 2.35rem;
    --portal-scroll-top-offset: 0.85rem;
    --portal-scroll-top-clearance: calc(var(--portal-scroll-top-size) + var(--portal-scroll-top-offset) + 0.5rem);
    /* Standard-Chart-Höhe (Balken, Linien, Donuts/Pie); Ausnahme: MEP-Radar */
    --portal-chart-height: 340px;
}

/* Seiten-Layout
 * - .portal-app-content: padding = Gap; unten mind. Scroll-Top-Clearance
 * - .portal-app-content--dense-x: Alias (gleicher Gap; denseX-Aufrufe bleiben gültig)
 * - .portal-card-grid: Margin-Reset + Gutter = --portal-content-gap
 * - .portal-page--comfortable: nur Portal-Dashboard
 */
.portal-app-content {
    --bs-gutter-x: var(--portal-content-gap);
    width: 100%;
    padding: var(--portal-content-gap);
    padding-bottom: max(var(--portal-content-gap), var(--portal-scroll-top-clearance));
    margin-right: auto;
    margin-left: auto;
}

.portal-app-content--dense-x {
    --bs-gutter-x: var(--portal-content-gap-x-dense);
    padding: var(--portal-content-gap-x-dense);
    padding-bottom: max(var(--portal-content-gap-x-dense), var(--portal-scroll-top-clearance));
}

.portal-app-content--bottom-pad {
    padding-bottom: max(3rem, var(--portal-scroll-top-clearance));
}

/* Apps ohne .portal-app-content (z. B. Org): trotzdem Clearance für Scroll-Top.
 * Ausnahme: Vollbild-Apps (Map) – kein unterer Platz, kein Scroll-Top-Button. */
body:has(#portalScrollTop):not(:has(.portal-app-content)):not(:has(.portal-page--bottom-pad)):not(.map-body) {
    padding-bottom: var(--portal-scroll-top-clearance);
}

body.map-body #portalScrollTop {
    display: none !important;
}

/* Sticky Chrome: Blau-Header ± optionale Subnav als eine Einheit */
.portal-app-chrome {
    position: sticky;
    top: 0;
    z-index: 1030;
    width: 100%;
    align-self: flex-start;
    background-color: var(--bs-body-bg);
}

/* Subnav: Aktiv = blauer Unterstrich (bündig am unteren Rand); Punkte durch Trennstreifen getrennt */
.portal-app-subnav {
    border-bottom: none;
}

.portal-app-subnav > .container-fluid {
    padding-top: 0.15rem;
    padding-bottom: 0;
}

.portal-app-subnav .nav {
    gap: 0;
    align-items: stretch;
    padding: 0;
}

.portal-app-subnav .nav-item + .nav-item {
    border-left: 1px solid var(--bs-gray-500);
}

.portal-app-subnav .nav-link {
    box-sizing: border-box;
    font-weight: 400;
    line-height: 1.25;
    color: var(--bs-body-color);
    background: transparent;
    border: 0;
    border-bottom: 3px solid transparent;
    border-radius: 0;
    padding: 0.25rem 0.65rem;
    margin: 0;
}

.portal-app-subnav .nav-link:hover,
.portal-app-subnav .nav-link:focus {
    color: var(--bs-primary);
    background: transparent;
    border-bottom-color: var(--bs-primary-border-subtle, rgba(13, 110, 253, 0.35));
}

.portal-app-subnav .nav-link.active {
    font-weight: 600;
    color: var(--bs-primary);
    background: transparent;
    border-bottom-color: var(--bs-primary);
}

.portal-app-header .container-fluid {
    --bs-gutter-x: var(--portal-content-gap);
    padding-left: var(--portal-content-gap);
    padding-right: var(--portal-content-gap);
}

/* Blau-Header: Brand | Suche | Profil – gleiche Höhe/Ausrichtung */
.portal-app-header-inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: center;
    column-gap: 0.75rem;
    min-height: 2.5em;
    padding-top: 0.35em;
    padding-bottom: 0.35em;
}

.portal-app-header-start,
.portal-app-header-center,
.portal-app-header-end {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

.portal-app-header-start {
    justify-self: start;
}

.portal-app-header-center {
    justify-self: center;
}

.portal-app-header-end {
    justify-self: end;
    justify-content: flex-end;
}

.portal-app-header-brand {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    font-size: 1em;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: 0.01em;
    white-space: nowrap;
}

.portal-app-header-brand .bi {
    font-size: 1.1em;
    line-height: 1;
}

.portal-app-header-search {
    width: min(320px, 42vw);
}

.portal-app-header-search .input-group-text {
    padding-left: 0.55rem;
    padding-right: 0.35rem;
}

.portal-app-header-search .header-search-input {
    min-width: 0;
}

/* Trefferliste unter dem Header: normale Textfarbe (nicht text-white vom Header erben) */
.portal-app-header .header-search-results {
    z-index: 1080;
    color: var(--bs-body-color);
    background-color: var(--bs-body-bg);
    padding: 0.25rem 0;
}

.portal-app-header .header-search-results .list-group-item {
    color: var(--bs-body-color);
    background-color: transparent;
    border-color: var(--bs-border-color-translucent);
    padding: 0.5rem 0.75rem;
    text-align: left;
}

.portal-app-header .header-search-results .list-group-item:hover,
.portal-app-header .header-search-results .list-group-item:focus {
    color: var(--bs-body-color);
    background-color: var(--bs-primary-bg-subtle);
}

.portal-app-header .portal-header-user-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    white-space: nowrap;
}

.portal-app-header .portal-header-user-btn .bi {
    font-size: 1.1em;
    line-height: 1;
}

/* Vertretung-Checkbox im blauen Header: weißes Kästchen + weißer Text */
.portal-app-header .portal-vertretung-mischen {
    color: #fff;
    cursor: pointer;
}
.portal-app-header .portal-vertretung-mischen .form-check-input {
    margin-top: 0;
    cursor: pointer;
    width: 1.1em;
    height: 1.1em;
    background-color: #fff;
    border: 1px solid #fff;
}
.portal-app-header .portal-vertretung-mischen .form-check-input:checked {
    background-color: #fff;
    border-color: #fff;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%230d6efd' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
}
.portal-app-header .portal-vertretung-mischen .form-check-input:focus {
    border-color: #fff;
    box-shadow: 0 0 0 0.2rem rgba(255, 255, 255, 0.35);
}
.portal-app-header .portal-vertretung-hinweis {
    opacity: 0.9;
}

.portal-app-header .portal-session-badge {
    font-size: 0.7rem;
    padding: 0.2em 0.5em;
}

.portal-app-header .portal-version,
.portal-app-header .portal-online,
.portal-app-header .portal-online-sep {
    font-size: 0.8rem;
    letter-spacing: 0.02em;
    white-space: nowrap;
    color: rgba(255, 255, 255, 0.92) !important;
}

@media (max-width: 575.98px) {
    .portal-app-header-inner {
        grid-template-columns: auto minmax(0, 1fr) auto;
        column-gap: 0.5rem;
    }

    .portal-app-header-search {
        width: 100%;
    }

    .portal-app-header-brand span {
        max-width: 7rem;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* Dashboard/Portal-Nav: Version auf schmalen Screens weglassen (Platz für Online) */
    .portal-app-header .portal-version,
    .portal-app-header .portal-version + .portal-online-sep {
        display: none;
    }
}

/* Toolbar-Innenwrapper: gleicher Seitenrand wie Content */
.portal-app-toolbar > .container-fluid,
.portal-app-toolbar .container-fluid,
.bvm-toolbar .container-fluid {
    --bs-gutter-x: var(--portal-content-gap);
    padding-left: var(--portal-content-gap);
    padding-right: var(--portal-content-gap);
}

.portal-page {
    padding: var(--portal-page-padding-y) var(--portal-page-padding-x) 0;
}

.portal-page--bottom-pad {
    padding-bottom: max(3rem, var(--portal-scroll-top-clearance));
}

/* Nur top/left/right — padding-bottom bleibt bei 0 bzw. --bottom-pad */
.portal-page--comfortable {
    padding-top: var(--portal-page-padding-comfortable-y);
    padding-left: var(--portal-page-padding-comfortable-x);
    padding-right: var(--portal-page-padding-comfortable-x);
}

@media (min-width: 768px) {
    .portal-page--comfortable {
        --portal-page-padding-comfortable-y: 1.5rem;
        --portal-page-padding-comfortable-x: 2.5rem;
    }
}

.portal-page-intro {
    margin-bottom: 1.5rem;
}

.portal-page--dashboard {
    padding-top: 0;
}

.portal-page--dashboard.portal-page--comfortable {
    padding-top: 0;
}

@media (min-width: 768px) {
    .portal-page--dashboard.portal-page--comfortable {
        --portal-page-padding-comfortable-x: 2rem;
        padding-left: var(--portal-page-padding-comfortable-x);
        padding-right: var(--portal-page-padding-comfortable-x);
    }
}

.portal-dashboard-hero {
    --portal-hero-pad-top: 0.25rem;
    --portal-nav-gap: 1rem;
    display: flex;
    align-items: center;
    padding-top: var(--portal-hero-pad-top);
    /* Navbar margin-bottom + gleicher Abstand wie oben → vertikal zentriert */
    padding-bottom: calc(var(--portal-nav-gap) + var(--portal-hero-pad-top));
}

@media (min-width: 768px) {
    .portal-dashboard-hero {
        --portal-hero-pad-top: 0.375rem;
    }
}

.portal-page--dashboard .portal-page-intro {
    margin-bottom: 0;
}

.portal-page--dashboard .portal-page-intro .h3 {
    font-size: 1.35rem;
}

.portal-dashboard-intro--suche {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(12rem, 22rem) minmax(0, 1fr);
    align-items: center;
    gap: 0.75rem 1rem;
}

.portal-dashboard-intro--suche .portal-dashboard-intro-title {
    justify-self: start;
}

.portal-dashboard-intro--suche .portal-dashboard-suche {
    justify-self: center;
    width: 100%;
    max-width: 22rem;
}

.portal-dashboard-intro--suche .portal-dashboard-intro-favoriten {
    justify-self: end;
}

.portal-dashboard-suche-results {
    z-index: 1080;
    top: calc(100% + 0.25rem);
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    min-width: 100%;
    width: max-content;
    max-width: min(42rem, calc(100vw - 1.5rem));
    max-height: min(24rem, 70vh);
    overflow-x: hidden;
    overflow-y: auto;
    color: var(--bs-body-color);
}

.portal-dashboard-suche-results .list-group-item {
    color: var(--bs-body-color);
    background-color: transparent;
    border-color: var(--bs-border-color-translucent);
    padding: 0.5rem 0.75rem;
    text-align: left;
    white-space: normal;
}

.portal-dashboard-suche-results .list-group-item:hover,
.portal-dashboard-suche-results .list-group-item:focus,
.portal-dashboard-suche-results .list-group-item.active {
    color: var(--bs-body-color);
    background-color: var(--bs-primary-bg-subtle);
}

.portal-dashboard-suche-app {
    font-size: 0.7rem;
    letter-spacing: 0.01em;
    flex-shrink: 0;
}

@media (max-width: 767.98px) {
    .portal-dashboard-intro--suche {
        grid-template-columns: 1fr;
    }

    .portal-dashboard-intro--suche .portal-dashboard-suche,
    .portal-dashboard-intro--suche .portal-dashboard-intro-favoriten {
        justify-self: stretch;
        max-width: none;
    }

    .portal-dashboard-suche-results {
        left: 0;
        transform: none;
        width: 100%;
        max-width: none;
    }
}

.portal-page--dashboard .portal-row {
    --bs-gutter-x: 0;
    --bs-gutter-y: 0;
}

.portal-page--dashboard .portal-card {
    margin: 0;
}

.portal-dashboard-stack {
    display: flex;
    flex-direction: column;
    gap: var(--portal-dashboard-gap);
}

.portal-dashboard-aktuelles-list .portal-dashboard-aktuelles-zeile {
    line-height: 1.45;
    overflow: hidden;
}

/* Geburtstage: 3 Spalten nur allein; mit Nachbarkachel(n) 1 Spalte */
.portal-dashboard-aktuelles-list--drei {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    column-gap: 0.75rem;
}

.portal-mitteilungen-kacheln {
    display: flex;
    flex-direction: column;
    gap: var(--portal-space-sm, 0.75rem);
}

.portal-dashboard-aktuelles-box {
    background-color: #cff4fc;
}

.portal-dashboard-apps {
    position: relative;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
    gap: var(--portal-dashboard-gap);
}

/* Käfer + Spinne: über Kacheln/Header, unter Dropdowns/Modals (Whitelist-Easter-Egg) */
.portal-dashboard-bugs {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1035;
    overflow: hidden;
    pointer-events: none;
    max-width: 100%;
}

.portal-dashboard-bugs[hidden] {
    display: none !important;
}

.portal-dashboard-bug {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
    display: block;
    line-height: 0;
    opacity: 0.94;
    overflow: visible;
    will-change: transform;
}

.portal-dashboard-bug-sprite {
    display: block;
    width: 100%;
    height: 100%;
    line-height: 0;
    transform-origin: 50% 50%;
    will-change: transform;
}

.portal-dashboard-bug svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
    transform-origin: 50% 55%;
    animation: portal-bug-bob calc(var(--portal-bug-stride, 0.28s) * 2.2) ease-in-out infinite;
}

.portal-dashboard-bug--ladybug {
    opacity: 0.98;
}

.portal-dashboard-bug--ladybug svg {
    animation-duration: calc(var(--portal-bug-stride, 0.24s) * 2);
}

.portal-dashboard-bug--ant {
    opacity: 0.96;
}

.portal-dashboard-bug--ant svg {
    animation-duration: calc(var(--portal-bug-stride, 0.13s) * 2);
}

.portal-dashboard-bug--spider {
    opacity: 0.98;
    z-index: 2;
}

.portal-dashboard-bug--spider svg {
    animation-duration: calc(var(--portal-bug-stride, 0.26s) * 2.6);
}

.portal-dashboard-bug--spider .portal-bug-leg {
    animation-name: portal-spider-leg-swing;
    animation-duration: var(--portal-bug-stride, 0.26s);
}

/* Vordere / mittlere / hintere Beine leicht phasenversetzt */
.portal-dashboard-bug--spider .portal-bug-leg--a,
.portal-dashboard-bug--spider .portal-bug-leg--b {
    animation-delay: 0s;
}

.portal-dashboard-bug--spider .portal-bug-leg--b,
.portal-dashboard-bug--spider .portal-bug-leg--d,
.portal-dashboard-bug--spider .portal-bug-leg--f {
    animation-name: portal-spider-leg-swing-alt;
}

.portal-dashboard-bug--spider .portal-bug-leg--c,
.portal-dashboard-bug--spider .portal-bug-leg--d {
    animation-duration: calc(var(--portal-bug-stride, 0.26s) * 1.05);
    animation-delay: -0.09s;
}

.portal-dashboard-bug--spider .portal-bug-leg--e,
.portal-dashboard-bug--spider .portal-bug-leg--f {
    animation-duration: calc(var(--portal-bug-stride, 0.26s) * 1.12);
    animation-delay: -0.18s;
}

.portal-dashboard-bug--spider.is-feeding svg {
    animation-name: portal-spider-feed-bob;
    animation-duration: 0.28s;
}

.portal-dashboard-bug--spider.is-digesting svg {
    animation-name: portal-spider-digest-bob;
    animation-duration: 0.55s;
}

.portal-dashboard-bug--spider.is-still .portal-bug-leg {
    animation: none;
}

.portal-dashboard-bug.is-caught {
    z-index: 1;
    pointer-events: none;
}

.portal-dashboard-bug-name {
    position: absolute;
    left: 50%;
    bottom: calc(100% + 6px);
    z-index: 4;
    transform: translateX(-50%);
    white-space: nowrap;
    max-width: 7rem;
    overflow: hidden;
    text-overflow: ellipsis;
    padding: 0.12rem 0.35rem;
    border-radius: 0.35rem;
    font-size: 0.62rem;
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: 0.01em;
    color: #334155;
    background: rgba(255, 255, 255, 0.94);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.22);
    pointer-events: none;
}

.portal-dashboard-bug-name.is-user {
    color: #92400e;
    background: #fef3c7;
    box-shadow: 0 1px 2px rgba(146, 64, 14, 0.28);
}

.portal-dashboard-bug-name.is-spider {
    color: #4c1d95;
    background: #ede9fe;
    box-shadow: 0 1px 2px rgba(76, 29, 149, 0.25);
}

.portal-dashboard-bug.is-caught .portal-dashboard-bug-name {
    opacity: 0;
}

/* Beinchen schwingen im Wechsel */
.portal-bug-leg {
    transform-origin: 0px 0px;
    animation: portal-bug-leg-swing var(--portal-bug-stride, 0.28s) ease-in-out infinite;
}

.portal-bug-leg--b,
.portal-bug-leg--d,
.portal-bug-leg--f {
    animation-name: portal-bug-leg-swing-alt;
}

.portal-bug-leg--c,
.portal-bug-leg--d {
    animation-duration: var(--portal-bug-stride, 0.26s);
}

.portal-bug-leg--e,
.portal-bug-leg--f {
    animation-duration: calc(var(--portal-bug-stride, 0.28s) * 1.08);
}

@keyframes portal-bug-leg-swing {
    0%, 100% { transform: rotate(-11deg); }
    50% { transform: rotate(10deg); }
}

@keyframes portal-bug-leg-swing-alt {
    0%, 100% { transform: rotate(10deg); }
    50% { transform: rotate(-11deg); }
}

@keyframes portal-spider-leg-swing {
    0%, 100% { transform: rotate(-10deg); }
    50% { transform: rotate(9deg); }
}

@keyframes portal-spider-leg-swing-alt {
    0%, 100% { transform: rotate(9deg); }
    50% { transform: rotate(-10deg); }
}

@keyframes portal-spider-feed-bob {
    0%, 100% { transform: translateY(0) scale(1); }
    50% { transform: translateY(0.8px) scale(1.04); }
}

@keyframes portal-spider-digest-bob {
    0%, 100% { transform: translateY(0) scale(1); }
    50% { transform: translateY(0.4px) scale(1.02); }
}

@keyframes portal-bug-bob {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(0.45px); }
}

@media (prefers-reduced-motion: reduce) {
    .portal-bug-leg,
    .portal-dashboard-bug svg {
        animation: none;
    }
}

.portal-dashboard-apps-sep {
    grid-column: 1 / -1;
    height: 2px;
    margin: 0.55rem 0 0.35rem;
    border: 0;
    background-color: var(--bs-secondary);
    opacity: 0.45;
}

@media (min-width: 768px) {
    .portal-dashboard-apps {
        grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
    }
}

@media (min-width: 1200px) {
    .portal-dashboard-apps {
        grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    }
}

.portal-page--comfortable .portal-row {
    --bs-gutter-x: 1rem;
    --bs-gutter-y: 1rem;
}

.portal-page--narrow {
    max-width: 640px;
    margin-left: auto;
    margin-right: auto;
    padding-top: 1.5rem;
    padding-bottom: 1.5rem;
}

.portal-row {
    --bs-gutter-x: var(--portal-space-xs);
    --bs-gutter-y: var(--portal-space-xs);
}

/* Karte (einheitliche Oberfläche für Mitteilungen und Kacheln).
   Kein overflow:hidden — sonst werden Dropdowns in der Kachel abgeschnitten. */
.portal-card {
    border: 1px solid var(--portal-card-border);
    border-radius: var(--portal-card-radius);
    box-shadow: var(--portal-card-shadow);
    margin: var(--portal-card-margin-top) var(--portal-card-margin-x) var(--portal-card-margin-bottom);
    background-color: var(--bs-body-bg);
}

/* Letzte Karte: Abstand zum Fensterrand kommt von .portal-app-content padding-bottom */
.portal-app-content > .portal-card:last-child {
    margin-bottom: 0;
}

.portal-card > :first-child {
    border-top-left-radius: calc(var(--portal-card-radius) - 1px);
    border-top-right-radius: calc(var(--portal-card-radius) - 1px);
}

.portal-card > :last-child {
    border-bottom-left-radius: calc(var(--portal-card-radius) - 1px);
    border-bottom-right-radius: calc(var(--portal-card-radius) - 1px);
}

.portal-card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--portal-space-sm);
    padding: var(--portal-space-sm) var(--portal-space-sm);
    background-color: var(--bs-primary);
    color: #fff;
}

/* Kachel-Titel = gleiche Metrik wie .portal-app-header-brand */
.portal-card-title {
    font-size: 1em;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: 0.01em;
    margin: 0;
    color: inherit;
}

.portal-card-header .portal-card-title {
    color: inherit;
}

/* Titel/Utilities erben Header-Weiß (kein text-primary auf Primary-Hintergrund) */
.portal-card-header .text-primary,
.portal-card-header .text-muted {
    color: inherit !important;
}

.portal-card-header .breadcrumb {
    --bs-breadcrumb-divider-color: rgba(255, 255, 255, 0.55);
    margin-bottom: 0;
}

.portal-card-header .breadcrumb-item,
.portal-card-header .breadcrumb-item a,
.portal-card-header .breadcrumb-item.active {
    color: #fff;
}

.portal-card-header .breadcrumb-item a:hover,
.portal-card-header .breadcrumb-item a:focus {
    color: #fff;
    opacity: 0.85;
}

/* card_body: Bootstrap-Default (1rem); Varianten unten */

.portal-card-body--dense {
    padding: var(--portal-card-body-dense-pad);
}

.portal-card-body--flush {
    padding: 0;
}

/* DataTables in App-Karten: einheitliche Innenränder, kein doppelter Bootstrap-Gutter */
.portal-card .dt-container > div.row,
.portal-card div.dataTables_wrapper > div.row {
    margin-left: 0;
    margin-right: 0;
}

.portal-card .dt-container > div.row > [class*="col-"]:first-child,
.portal-card div.dataTables_wrapper > div.row > [class*="col-"]:first-child {
    padding-left: 0;
}

.portal-card .dt-container > div.row > [class*="col-"]:last-child,
.portal-card div.dataTables_wrapper > div.row > [class*="col-"]:last-child {
    padding-right: 0;
}

.portal-card .dt-container table.dataTable,
.portal-card div.dataTables_wrapper table.dataTable {
    margin-top: var(--portal-space-sm);
    margin-bottom: var(--portal-space-sm);
    width: 100% !important;
}

.portal-card-body--dense > .table-responsive,
.portal-card-body--dense > .dt-container,
.portal-card-body--dense > .dataTables_wrapper {
    margin: 0;
}

.portal-card-body--kachel {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: var(--portal-space-sm);
    padding: 1.5rem var(--portal-space-sm);
}

.portal-page--dashboard .portal-card-body--kachel {
    padding: 0.75rem 0.5rem 0.625rem;
    gap: 0.375rem;
}

.portal-page--dashboard .portal-app-icon {
    width: 3.75rem;
    height: 3.75rem;
    font-size: 1.85rem;
}

.portal-dashboard-apps .portal-card {
    margin: 0;
}

/* Musik-Kachel: volle Rasterbreite, horizontale Leiste */
.portal-app-tile--musik {
    grid-column: 1 / -1;
    min-width: 0;
}

.portal-musik-kachel-body {
    --portal-musik-gap: 0.65rem;
    --portal-musik-panel-radius: var(--portal-card-radius);
    --portal-musik-panel-pad: 0.65rem;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--portal-musik-gap);
    padding: var(--portal-musik-gap) !important;
    text-align: left;
}

/* Zeile 1: 2/5/5 · Zeile 2: 2/10 · Zeile 3: 5/7 */
.portal-musik-bar {
    display: flex;
    flex-direction: column;
    gap: var(--portal-musik-gap);
    width: 100%;
}

.portal-musik-row {
    display: grid;
    gap: var(--portal-musik-gap);
    width: 100%;
    align-items: stretch;
    min-width: 0;
}

.portal-musik-row-top {
    grid-template-columns: minmax(0, 2fr) minmax(0, 5fr) minmax(0, 5fr);
}

.portal-musik-row-mid {
    grid-template-columns: minmax(0, 2fr) minmax(0, 10fr);
}

.portal-musik-lists {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
}

.portal-musik-panel {
    min-width: 0;
    border: 1px solid var(--portal-card-border);
    border-radius: var(--portal-musik-panel-radius);
    box-shadow: var(--portal-card-shadow);
    padding: var(--portal-musik-panel-pad);
    background: var(--bs-body-bg);
}

.portal-musik-mid-main {
    display: flex;
    flex-direction: column;
    gap: var(--portal-musik-gap);
    min-width: 0;
    height: 0;
    min-height: 100%;
    /* visible: sonst fehlen Schatten/runde Ecken an Now + Lyrics */
    overflow: visible;
}

.portal-musik-col {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

/* Pastell-Kacheln: einheitlich hellblau wie „Musik (N)“ */
.portal-musik-panel.portal-musik-brand-panel,
.portal-musik-panel.portal-musik-col-ctrl,
.portal-musik-panel.portal-musik-col-volume,
.portal-musik-panel.portal-musik-cover-wrap,
.portal-musik-panel.portal-musik-now-panel,
.portal-musik-panel.portal-musik-lyrics,
.portal-musik-panel.portal-musik-col-artist,
.portal-musik-panel.portal-musik-col-title {
    background: #dbeafe;
    border-color: #93c5fd;
}

.portal-musik-panel.portal-musik-brand-panel {
    display: flex;
    align-items: center;
    width: 100%;
    margin: 0;
    appearance: none;
    -webkit-appearance: none;
    font: inherit;
    text-align: left;
    cursor: pointer;
    color: inherit;
}

.portal-musik-panel.portal-musik-brand-panel:hover,
.portal-musik-panel.portal-musik-brand-panel:focus-visible {
    border-color: var(--bs-primary);
    outline: none;
    box-shadow: 0 0 0 0.2rem rgba(var(--bs-primary-rgb), 0.2);
}

.portal-musik-panel.portal-musik-col-ctrl {
    display: flex;
    align-items: center;
}

.portal-musik-panel.portal-musik-col-volume {
    display: flex;
    align-items: center;
}

.portal-musik-panel.portal-musik-cover-wrap {
    position: relative;
    min-width: 0;
    width: 100%;
    aspect-ratio: 1;
    height: auto;
    padding: 0;
    overflow: hidden;
}

.portal-musik-panel.portal-musik-now-panel {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.portal-musik-panel.portal-musik-lyrics {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    border-radius: var(--portal-musik-panel-radius);
    box-shadow: var(--portal-card-shadow);
}

.portal-musik-panel.portal-musik-col-artist,
.portal-musik-panel.portal-musik-col-title {
    gap: 0.125rem;
    min-height: 0;
    overflow: hidden;
}

.portal-musik-col-artist > .form-label,
.portal-musik-col-title > .form-label,
.portal-musik-col-title > .portal-musik-title-label-row {
    flex: 0 0 auto;
    line-height: 1.2;
}

.portal-musik-brand {
    min-width: 0;
    width: 100%;
}

.portal-musik-icon {
    width: 2rem;
    height: 2rem;
    font-size: 1rem;
    flex: 0 0 auto;
}

.portal-musik-controls {
    display: flex;
    flex-wrap: nowrap;
    min-width: 0;
    width: 100%;
}

.portal-musik-controls .btn {
    padding: 0.35rem 0.45rem;
    font-size: 1rem;
    line-height: 1.2;
}

/* Hinweis: Musik wählen – Aufmerksamkeit auf Brand-Kachel */
.portal-musik-ordner-hint {
    border-color: var(--bs-primary) !important;
    z-index: 1;
    animation: portal-musik-ordner-pulse 1.35s ease-in-out infinite;
}

@keyframes portal-musik-ordner-pulse {
    0%,
    100% {
        opacity: 1;
        box-shadow: 0 0 0 0 rgba(var(--bs-primary-rgb), 0.45);
    }
    50% {
        opacity: 0.72;
        box-shadow: 0 0 0 0.4rem rgba(var(--bs-primary-rgb), 0);
    }
}

@media (prefers-reduced-motion: reduce) {
    .portal-musik-ordner-hint {
        animation: none;
        box-shadow: 0 0 0 2px rgba(var(--bs-primary-rgb), 0.45);
    }
}

.portal-musik-volume {
    min-width: 0;
    width: 100%;
}

.portal-musik-mute-btn {
    flex: 0 0 auto;
    padding: 0.35rem 0.45rem;
    font-size: 1rem;
    line-height: 1.2;
}

.portal-musik-volume-range {
    flex: 1 1 auto;
    min-width: 0;
    height: 1.35rem;
    padding: 0;
    accent-color: var(--bs-primary);
    background: transparent;
    -webkit-appearance: none;
    appearance: none;
}

.portal-musik-volume-range::-webkit-slider-runnable-track {
    height: 0.5rem;
    border-radius: 999px;
    background: rgba(var(--bs-primary-rgb), 0.4);
    border: 1px solid rgba(var(--bs-primary-rgb), 0.55);
}

.portal-musik-volume-range::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 1rem;
    height: 1rem;
    margin-top: -0.28rem;
    border-radius: 50%;
    background: var(--bs-primary);
    border: 0;
    box-shadow: 0 0 0 2px #fff;
}

.portal-musik-volume-range::-moz-range-track {
    height: 0.5rem;
    border-radius: 999px;
    background: rgba(var(--bs-primary-rgb), 0.4);
    border: 1px solid rgba(var(--bs-primary-rgb), 0.55);
}

.portal-musik-volume-range::-moz-range-thumb {
    width: 1rem;
    height: 1rem;
    border-radius: 50%;
    background: var(--bs-primary);
    border: 0;
    box-shadow: 0 0 0 2px #fff;
}

.portal-musik-seek-range {
    flex: 1 1 auto;
    min-width: 0;
    height: 1.25rem;
    padding: 0;
    accent-color: var(--bs-primary);
    background: transparent;
    -webkit-appearance: none;
    appearance: none;
}

.portal-musik-seek-range::-webkit-slider-runnable-track {
    height: 0.4rem;
    border-radius: 999px;
    background: rgba(var(--bs-primary-rgb), 0.35);
    border: 1px solid rgba(var(--bs-primary-rgb), 0.5);
}

.portal-musik-seek-range::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 0.9rem;
    height: 0.9rem;
    margin-top: -0.28rem;
    border-radius: 50%;
    background: var(--bs-primary);
    border: 0;
    box-shadow: 0 0 0 2px #fff;
}

.portal-musik-seek-range::-moz-range-track {
    height: 0.4rem;
    border-radius: 999px;
    background: rgba(var(--bs-primary-rgb), 0.35);
    border: 1px solid rgba(var(--bs-primary-rgb), 0.5);
}

.portal-musik-seek-range::-moz-range-thumb {
    width: 0.9rem;
    height: 0.9rem;
    border-radius: 50%;
    background: var(--bs-primary);
    border: 0;
    box-shadow: 0 0 0 2px #fff;
}

.portal-musik-cover,
.portal-musik-cover-placeholder {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}

.portal-musik-cover {
    display: block;
    object-fit: cover;
    border-radius: 0;
    background: var(--bs-secondary-bg);
}

.portal-musik-cover-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--bs-secondary-color);
    font-size: 3rem;
    background: var(--bs-secondary-bg);
}

.portal-musik-cover-wrap.is-cover .portal-musik-cover-placeholder {
    display: none;
}

.portal-musik-now-row {
    flex: 0 0 auto;
    width: 100%;
    min-width: 0;
}

.portal-musik-now {
    flex: 1 1 auto;
    min-width: 0;
    width: auto;
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.35;
    min-height: 1.35em;
}

.portal-musik-delete-btn {
    flex: 0 0 auto;
    padding: 0.2rem 0.45rem;
    line-height: 1;
}

.portal-musik-rating {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0;
}

.portal-musik-rating-star {
    padding: 0.1rem 0.15rem;
    line-height: 1;
    color: var(--bs-secondary-color);
    text-decoration: none !important;
}

.portal-musik-rating-star:hover,
.portal-musik-rating-star:focus-visible {
    color: var(--bs-warning);
}

.portal-musik-rating-star.is-on {
    color: var(--bs-warning);
}

.portal-musik-rating-star:disabled {
    opacity: 0.45;
}

.portal-musik-title-label-row {
    flex: 0 0 auto;
    line-height: 1.2;
}

.portal-musik-rating-filter {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0;
}

.portal-musik-rating-filter-label {
    margin-right: 0.25rem;
    line-height: 1;
    white-space: nowrap;
}

.portal-musik-rating-filter-star {
    padding: 0;
    line-height: 1;
    color: var(--bs-secondary-color);
    text-decoration: none !important;
    font-size: 0.85rem;
}

.portal-musik-rating-filter-star:hover,
.portal-musik-rating-filter-star:focus-visible {
    color: var(--bs-warning);
}

.portal-musik-rating-filter-star.is-on {
    color: var(--bs-warning);
}

.portal-musik-seek {
    flex: 0 0 auto;
    width: 100%;
}

.portal-musik-seek-time {
    flex: 0 0 auto;
    min-width: 2.5rem;
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
    color: var(--bs-secondary-color);
    line-height: 1;
}

.portal-musik-seek-time:last-child {
    text-align: right;
}

.portal-musik-search {
    width: 100%;
    flex: 0 0 auto;
}

.portal-musik-select-artist,
.portal-musik-select-title {
    width: 100%;
    flex: 0 0 auto;
    /* Sichtbare Zeilen steuert size="6" – keine CSS-Höhe, sonst werden mehr Zeilen sichtbar */
    height: auto;
    min-height: 0;
    overflow: auto;
}

.portal-musik-duplikate {
    flex: 0 0 auto;
    background: var(--bs-danger-bg-subtle);
    border-color: var(--bs-danger-border-subtle);
}

.portal-musik-duplikate-toggle {
    color: var(--bs-body-color) !important;
    line-height: 1.3;
}

.portal-musik-duplikate-list {
    max-height: 10rem;
    overflow: auto;
    margin-top: 0.4rem;
    padding-top: 0.35rem;
    border-top: 1px solid var(--bs-danger-border-subtle);
    font-size: 0.875rem;
}

.portal-musik-duplikate-group + .portal-musik-duplikate-group {
    margin-top: 0.45rem;
}

.portal-musik-duplikate-group-title {
    font-weight: 600;
    margin-bottom: 0.15rem;
}

.portal-musik-duplikate-path {
    display: block;
    width: 100%;
    text-align: left;
    border: 0;
    background: transparent;
    color: var(--bs-secondary-color);
    padding: 0.1rem 0;
    font-size: inherit;
    line-height: 1.35;
    word-break: break-all;
}

.portal-musik-duplikate-path:hover,
.portal-musik-duplikate-path:focus-visible {
    color: var(--bs-body-color);
    text-decoration: underline;
}

.portal-musik-lyrics-inner {
    font-size: 1rem;
    line-height: 1.5;
    white-space: pre-wrap;
    color: var(--bs-body-color);
    flex: 1 1 auto;
    min-height: 0;
}

.portal-musik-lyrics-inner.is-window {
    white-space: normal;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    min-height: calc(3 * 1.5em + 3 * 0.4rem);
}

.portal-musik-lyrics-inner.is-timed {
    white-space: normal;
}

.portal-musik-lyrics-line {
    padding: 0.2rem 0.5rem;
    border-radius: 0.25rem;
    color: var(--bs-secondary-color);
    min-height: 1.5em;
    line-height: 1.5;
}

.portal-musik-lyrics-line.is-empty {
    visibility: hidden;
}

.portal-musik-lyrics-line.is-active {
    color: var(--bs-body-color);
    background: rgba(var(--bs-primary-rgb), 0.18);
    font-weight: 600;
}

@media (max-width: 991.98px) {
    .portal-musik-row-top {
        grid-template-columns: minmax(0, 1fr);
    }

    .portal-musik-row-mid {
        grid-template-columns: minmax(0, 1fr);
    }

    .portal-musik-cover-wrap {
        max-width: 14rem;
        justify-self: start;
    }

    .portal-musik-mid-main {
        height: auto;
        min-height: 0;
        overflow: visible;
    }

    .portal-musik-lyrics {
        flex: 0 0 auto;
        min-height: calc(var(--portal-musik-panel-pad) * 2 + 3 * 1.5em + 3 * 0.4rem);
    }
}

@media (max-width: 767.98px) {
    .portal-musik-lists {
        grid-template-columns: 1fr;
    }
}

/* Dashboard-Favorit: Stern auf der Kachel (bewegt sich mit Tile-Hover) */
.portal-app-tile {
    position: relative;
    transition: transform 0.15s ease-in-out;
}

.portal-app-favorit-btn {
    position: absolute;
    z-index: 3;
    top: 0.15rem;
    right: 0.15rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    color: var(--bs-secondary);
    line-height: 1;
    cursor: pointer;
    box-shadow: none;
}

.portal-app-favorit-btn:hover,
.portal-app-favorit-btn:focus-visible {
    color: var(--bs-warning);
    outline: none;
}

.portal-app-favorit-btn.is-favorit {
    color: var(--bs-warning);
}

.portal-app-favorit-btn .bi {
    font-size: 0.95rem;
}

/* Karten in Grids: Eigen-Margin aus; Abstand = App-Gap (überstimmt Bootstrap g-3 o. ä.) */
.portal-card-grid {
    --bs-gutter-x: var(--portal-content-gap);
    --bs-gutter-y: var(--portal-content-gap);
}

.portal-card-grid .portal-card {
    margin: 0;
}

/*
 * Gestapelte Kachel-Zeilen: Abstand wie Mitteilungen→Kacheln.
 * Nicht margin-top am Folge-Grid (Row hat schon −gutter-y, Spalten +gutter-y) —
 * sonst doppelter oder fehlender Gap. Stattdessen margin-bottom am oberen Grid.
 */
.portal-card-grid:has(+ .portal-card-grid) {
    margin-bottom: var(--portal-content-gap);
}

/* Gestapelte Kacheln in einer Grid-Spalte (z. B. CRM Geburtstage → Fällige Notizen) */
.portal-card-grid > [class*="col"] > .portal-card + .portal-card {
    margin-top: var(--portal-content-gap);
}

/* App-Kacheln (Dashboard) */
.portal-card--app {
    transition: transform 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

.portal-card--app-wartung {
    position: relative;
    opacity: 0.72;
}

.portal-app-wartung-stempel {
    position: absolute;
    z-index: 2;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) rotate(-22deg);
    padding: 0.28rem 0.75rem;
    border: 2.5px solid var(--bs-danger);
    border-radius: 0.25rem;
    color: var(--bs-danger);
    background-color: color-mix(in srgb, var(--bs-body-bg) 85%, transparent);
    font-size: 0.95rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    line-height: 1.2;
    pointer-events: none;
    white-space: nowrap;
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--bs-danger) 25%, transparent);
}

.portal-app-wartung-stempel--in-kuerze {
    border-color: var(--bs-secondary);
    color: var(--bs-secondary);
    font-size: 0.82rem;
    letter-spacing: 0.05em;
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--bs-secondary) 25%, transparent);
}

.portal-app-link--wartung {
    cursor: not-allowed;
}

/* Dashboard-Tile: ganze Kachel inkl. Stern anheben.
   focus-within nur mit focus-visible: sonst bleibt die Kachel nach Klick
   (target=_blank) hochgefahren, weil der Link den Fokus behält. */
.portal-app-tile:hover,
.portal-app-tile:focus-within:has(:focus-visible) {
    transform: translateY(-4px);
}

.portal-app-tile:hover .portal-card--app,
.portal-app-tile:focus-within:has(:focus-visible) .portal-card--app {
    box-shadow: var(--portal-card-shadow-hover) !important;
    transform: none;
}

.portal-app-tile:hover .portal-app-icon,
.portal-app-tile:focus-within:has(:focus-visible) .portal-app-icon {
    transform: scale(1.15);
}

/* Musik-Kachel: kein Anheben/Schatten-Hover (Bedienelemente, kein App-Link) */
.portal-app-tile--musik,
.portal-app-tile--musik:hover,
.portal-app-tile--musik:focus-within,
.portal-app-tile--musik:focus-within:has(:focus-visible) {
    transform: none;
    transition: none;
}

.portal-app-tile--musik .portal-card--app,
.portal-app-tile--musik:hover .portal-card--app,
.portal-app-tile--musik:focus-within .portal-card--app,
.portal-app-tile--musik:focus-within:has(:focus-visible) .portal-card--app {
    box-shadow: var(--portal-card-shadow, 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075)) !important;
    transform: none;
}

.portal-app-tile:has(> .portal-app-link--wartung):hover,
.portal-app-tile:has(> .portal-app-link--wartung):focus-within:has(:focus-visible) {
    transform: none;
}

.portal-app-tile:has(> .portal-app-link--wartung):hover .portal-card--app,
.portal-app-tile:has(> .portal-app-link--wartung):focus-within:has(:focus-visible) .portal-card--app {
    box-shadow: var(--portal-card-shadow) !important;
    transform: none;
}

.portal-app-tile:has(> .portal-app-link--wartung):hover .portal-app-icon,
.portal-app-tile:has(> .portal-app-link--wartung):focus-within:has(:focus-visible) .portal-app-icon {
    transform: none;
}

/* Apps ohne Tile-Wrapper (z. B. MED/RNG): Hover weiter am Link */
.portal-app-link:hover .portal-card--app,
.portal-app-link:focus-visible .portal-card--app {
    transform: translateY(-4px);
    box-shadow: var(--portal-card-shadow-hover) !important;
}

.portal-app-link:hover .portal-app-icon {
    transform: scale(1.15);
}

.portal-app-link--wartung:hover .portal-card--app,
.portal-app-link--wartung:focus-visible .portal-card--app {
    transform: none;
    box-shadow: var(--portal-card-shadow) !important;
}

.portal-app-link--wartung:hover .portal-app-icon {
    transform: none;
}

/* Tile überschreibt Link-Hover (kein Doppel-Anheben der Karte ohne Stern) */
.portal-app-tile .portal-app-link:hover .portal-card--app,
.portal-app-tile .portal-app-link:focus-visible .portal-card--app {
    transform: none;
}

.portal-app-tile .portal-app-link--wartung:hover .portal-card--app,
.portal-app-tile .portal-app-link--wartung:focus-visible .portal-card--app {
    box-shadow: var(--portal-card-shadow) !important;
    transform: none;
}

.portal-app-icon {
    width: 3.5rem;
    height: 3.5rem;
    transition: transform 0.15s ease-in-out;
}

/* Badge auf App-Kachel (bVM ungelesen, System-Ampel) */
.portal-app-unread-badge {
    position: absolute;
    top: -0.15rem;
    right: -0.35rem;
    min-width: 1.35rem;
    font-size: 0.7rem;
    line-height: 1.2;
    z-index: 1;
}

/* Dashboard-Hinweis-Modal (Umstellung) */
.portal-dashboard-hinweis .portal-dashboard-hinweis-list i {
    font-size: 1.15rem;
    flex-shrink: 0;
}

/* Mitteilungen */
.portal-mitteilung-carousel {
    padding: 0;
}

.portal-mitteilung-box {
    line-height: 1.35;
    border: 1px solid var(--portal-card-border);
    border-radius: calc(var(--portal-card-radius) - 2px);
    padding: var(--portal-space-xs) var(--portal-space-sm);
    margin-bottom: 0;
}

.portal-mitteilung-header {
    display: flex;
    align-items: center;
    margin-bottom: var(--portal-space-xs);
}

.portal-mitteilung-text {
    margin-bottom: 0;
    color: var(--bs-body-color);
    font-size: inherit;
    font-weight: 500;
}

.portal-icon-inline {
    margin-right: var(--portal-space-sm);
}

/* Login */
body.portal-login-body {
    background:
        radial-gradient(ellipse 80% 50% at 50% -10%, rgba(var(--bs-primary-rgb), 0.22), transparent 60%),
        linear-gradient(165deg, var(--bs-body-bg) 0%, var(--bs-secondary-bg) 100%);
}

.portal-login .portal-login-card {
    margin: 0;
    border: 1px solid rgba(var(--bs-primary-rgb), 0.12);
    box-shadow:
        0 0.75rem 2rem rgba(0, 0, 0, 0.08),
        0 0.25rem 0.5rem rgba(0, 0, 0, 0.04);
}

.portal-login .portal-login-card-body {
    padding: 1.75rem 1.5rem;
}

@media (min-width: 768px) {
    .portal-login .portal-login-card-body {
        padding: 2rem 1.75rem;
    }
}

.portal-login-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.25rem;
    height: 3.25rem;
    border-radius: 1rem;
    background: rgba(var(--bs-primary-rgb), 0.12);
    color: var(--bs-primary);
    font-size: 1.5rem;
    margin-bottom: 0.75rem;
}

.portal-login-title {
    font-size: 1.35rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    margin: 0 0 0.25rem;
    color: var(--bs-body-color);
}

.portal-login-subtitle {
    font-size: 0.95rem;
}

.portal-login-code {
    letter-spacing: 0.35em;
    font-weight: 600;
}

.portal-login-passkey-intro {
    line-height: 1.45;
}

.portal-login .form-label {
    width: 100%;
}

.portal-login .alert {
    text-align: center;
}

/* Willkommen (Erstlogin) */
.portal-willkommen .portal-willkommen-body {
    padding: 1.75rem 1.5rem;
    text-align: left;
}

@media (min-width: 768px) {
    .portal-willkommen .portal-willkommen-body {
        padding: 2.25rem 2rem;
    }
}

.portal-willkommen-title {
    font-size: 1.5rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    margin: 0 0 0.5rem;
    color: var(--bs-body-color);
}

.portal-willkommen-lead {
    font-size: 1rem;
    line-height: 1.5;
    max-width: 36rem;
    margin-left: auto;
    margin-right: auto;
}

.portal-willkommen-section {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    padding: 1.1rem 0;
    border-top: 1px solid rgba(var(--bs-primary-rgb), 0.1);
}

.portal-willkommen-section:first-of-type {
    border-top: 0;
    padding-top: 0.25rem;
}

.portal-willkommen-icon {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 0.75rem;
    background: rgba(var(--bs-primary-rgb), 0.12);
    color: var(--bs-primary);
    font-size: 1.15rem;
}

.portal-willkommen-h {
    font-size: 1.05rem;
    font-weight: 600;
    margin: 0.15rem 0 0.4rem;
    color: var(--bs-body-color);
}

.portal-willkommen-section p {
    font-size: 0.95rem;
    line-height: 1.5;
    color: var(--bs-body-color);
}

.portal-willkommen-steps {
    padding-left: 1.15rem;
    font-size: 0.95rem;
    line-height: 1.55;
    color: var(--bs-body-color);
}

.portal-willkommen-steps li + li {
    margin-top: 0.35rem;
}

.portal-willkommen-cta .btn-primary {
    min-width: min(100%, 22rem);
}

/* Anmeldegeräte-Modal: Passkey | Authenticator */
.portal-anmelde-kachel {
    border: 1px solid var(--bs-border-color);
    border-radius: var(--bs-border-radius-lg, 0.5rem);
    padding: 0.85rem 1rem;
    background: var(--bs-body-bg);
}

.portal-login .portal-anmelde-kachel {
    padding: 0.75rem 0.9rem;
}

.portal-anmelde-kachel--empfohlen {
    border-color: rgba(var(--bs-primary-rgb), 0.4);
    background: rgba(var(--bs-primary-rgb), 0.05);
    box-shadow: 0 0 0 1px rgba(var(--bs-primary-rgb), 0.08);
}

/* Umleitung (Webgo → Portal) */
.portal-umleitung .portal-umleitung-body {
    padding: 2rem 1.5rem;
}

@media (min-width: 768px) {
    .portal-umleitung .portal-umleitung-body {
        padding: 2.5rem 2rem;
    }
}

.portal-umleitung-headline {
    font-size: 1.45rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    line-height: 1.35;
    margin: 0 0 0.75rem;
    color: var(--bs-body-color);
}

.portal-umleitung-lead {
    font-size: 1rem;
    line-height: 1.55;
    max-width: 28rem;
    margin-left: auto;
    margin-right: auto;
}

.portal-umleitung-cta {
    max-width: 22rem;
}

.portal-umleitung-points {
    max-width: 26rem;
    margin-left: auto;
    margin-right: auto;
}

.portal-umleitung-points li {
    display: flex;
    align-items: flex-start;
    line-height: 1.45;
}

.portal-umleitung-points li + li {
    margin-top: 0.55rem;
}

.portal-umleitung-points .bi {
    flex-shrink: 0;
    margin-top: 0.1rem;
}

/* Filterleisten-SSOT (Listen/Auswertungen; nicht Modal-Formulare)
 * Tokens: portal_ui_class filter_container | filter_panel | filter_row | filter_field | filter_label
 * filter_container / filter_panel = einheitliches helles Grau (bg-body-secondary)
 */
.portal-filter-label {
    font-size: 0.9em;
    line-height: 1.2;
}

.portal-filter-field {
    gap: 0.125rem;
    min-width: 0;
}

.portal-filter-field .form-select {
    /* Bootstrap width:100% sonst schrumpft in Flex-Zeilen unter den Optionstext */
    width: auto;
    max-width: 100%;
}

.portal-filter-field .form-label {
    line-height: 1.2;
}

.portal-filter-row {
    column-gap: 0.75rem;
    row-gap: 0.5rem;
    width: 100%;
}

/* CRM-Tabellen: 8 gleiche Filterbreiten pro Zeile (Desktop) */
.portal-filter-row-tabelle {
    display: grid;
    grid-template-columns: repeat(8, minmax(0, 1fr));
    align-items: end;
}

/* Module mit wenigen Filtern (bVM): 6 gleiche Spalten (12er-Raster 2+2+2+2+2+2) */
.portal-filter-row-modul {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    align-items: end;
    column-gap: 1rem;
}

/* Auswertungen: Flex mit Wrap, Labels oben */
.portal-filter-row-auswertung {
    column-gap: 1rem;
    row-gap: 0.5rem;
}

@media (max-width: 991.98px) {
    .portal-filter-row-tabelle {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
    .portal-filter-row-modul {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 575.98px) {
    .portal-filter-row-tabelle,
    .portal-filter-row-modul {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.portal-filter-row-tabelle > .portal-filter-field,
.portal-filter-row-tabelle > .portal-filter-check,
.portal-filter-row-modul > .portal-filter-field,
.portal-filter-row-modul > .portal-filter-check {
    width: 100%;
    min-width: 0;
}

.portal-filter-row-tabelle .form-select,
.portal-filter-row-tabelle .form-control,
.portal-filter-row-tabelle .portal-ms-compact,
.portal-filter-row-tabelle .portal-ms-compact-trigger,
.portal-filter-row-modul .form-select,
.portal-filter-row-modul .form-control {
    width: 100%;
    max-width: 100%;
}

/* Geschlossenes Select: Luft vor dem Caret (Bootstrap form-select) */
.portal-filter-field > .form-select {
    padding-right: 2.25rem;
}

.portal-filter-check {
    display: flex;
    align-items: flex-end;
    min-height: 100%;
    padding-bottom: 0.15rem;
}

/* Kompakte Mehrfachauswahl (Tabellenfilter) – eine Zeile Höhe */
.portal-ms-compact {
    position: relative;
    display: block;
    width: 100%;
    max-width: 100%;
}

.portal-ms-compact-trigger {
    display: block;
    width: 100%;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.portal-ms-compact-trigger.portal-ms-compact-empty {
    color: var(--inactive-color, silver);
}

.portal-ms-compact-label {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Aufgeklappt: Inhalt bestimmt die Breite; mindestens so breit wie der Trigger (JS) */
.portal-ms-compact-menu {
    max-height: 16rem;
    overflow-y: auto;
    width: max-content;
    max-width: min(28rem, calc(100vw - 2rem));
}

.portal-ms-compact-item.active,
.portal-ms-compact-item:active {
    background-color: var(--bs-primary);
    color: #fff;
}

.portal-ms-compact-select {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

/* Aktive Filter (vom Standard abweichend) – SSOT für CRM, bVM, KPI, … */
:root {
    --filter-highlight-bg: #fff3cd;
    --filter-highlight-border: #ffc107;
    --filter-highlight-border-width: 1px;
}

.portal-filter-active {
    background-color: var(--filter-highlight-bg) !important;
    border-color: var(--filter-highlight-border) !important;
    border-width: var(--filter-highlight-border-width) !important;
}

/* Raumige Mehrfachauswahl: nur Rahmen, kein Gelb hinter den Optionen */
select[multiple].portal-filter-active {
    background-color: var(--bs-body-bg, #fff) !important;
}

.form-check-input.portal-filter-checkbox-active {
    border-color: var(--filter-highlight-border) !important;
    border-width: var(--filter-highlight-border-width) !important;
    border-style: solid !important;
}

.form-check-input.portal-filter-checkbox-active:checked {
    background-color: var(--filter-highlight-border);
    border-color: var(--filter-highlight-border);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23212529' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
}

/* Sticky App-Toolbars (standalone ohne Chrome-Hülle) */
body.org-body .org-toolbar,
body.mav-body .mav-toolbar,
body.ael-body .ael-toolbar,
body.bck-body .bck-toolbar,
body.kal-body .kal-toolbar,
body.lp-body .lp-subnav,
.portal-app-toolbar {
    position: sticky;
    top: 0;
    z-index: 1020;
}

/* Chrome-Hülle übernimmt Sticky – innere Leisten nicht nochmal */
.portal-app-chrome .portal-app-toolbar,
.portal-app-chrome .mav-toolbar,
.portal-app-chrome .bck-toolbar,
.portal-app-chrome .lp-subnav,
.portal-app-chrome .org-toolbar,
.portal-app-chrome .ael-toolbar,
.portal-app-chrome nav.navbar {
    position: static;
}

/* Nach oben mit Scroll-Fortschritt (Ring) */
.portal-scroll-top {
    position: fixed;
    right: var(--portal-scroll-top-offset);
    bottom: var(--portal-scroll-top-offset);
    z-index: 1040;
    width: var(--portal-scroll-top-size);
    height: var(--portal-scroll-top-size);
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--bs-primary);
    color: #fff;
    box-shadow: var(--portal-card-shadow);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.2s ease, visibility 0.2s ease, transform 0.15s ease;
    cursor: pointer;
}

.portal-scroll-top:hover {
    transform: translateY(-2px);
    color: #fff;
}

.portal-scroll-top:focus-visible {
    outline: 2px solid var(--bs-primary);
    outline-offset: 3px;
}

.portal-scroll-top.is-visible {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
}

.portal-scroll-top-ring {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    transform: rotate(-90deg);
}

.portal-scroll-top-track {
    stroke: rgba(255, 255, 255, 0.28);
    stroke-width: 2.5;
}

.portal-scroll-top-progress {
    stroke: #fff;
    stroke-width: 2.5;
    stroke-linecap: round;
    stroke-dasharray: 106.814;
    stroke-dashoffset: 106.814;
    transition: stroke-dashoffset 0.08s linear;
}

.portal-scroll-top-icon {
    position: relative;
    z-index: 1;
    font-size: 1.15rem;
    line-height: 1;
    color: rgba(255, 255, 255, 0.92);
    /* Pfeil optisch gleich groß trotz kleinerem Kreis */
    transform: scale(1.05);
}

/* Schwebende Meldungen (portalShowToast): deckend, schwach eingefärbt
 * Bootstrap setzt --bs-toast-bg sonst auf ~85 % Transparenz → Hintergrund scheint durch. */
.toast.portal-toast-success,
.toast.portal-toast-danger,
.toast.portal-toast-warning,
.toast.portal-toast-info {
    --bs-bg-opacity: 1;
}
.toast.portal-toast-success {
    --bs-toast-bg: var(--bs-success-bg-subtle);
    color: var(--bs-success-text-emphasis);
    border-color: var(--bs-success-border-subtle);
}
.toast.portal-toast-danger {
    --bs-toast-bg: var(--bs-danger-bg-subtle);
    color: var(--bs-danger-text-emphasis);
    border-color: var(--bs-danger-border-subtle);
}
.toast.portal-toast-warning {
    --bs-toast-bg: var(--bs-warning-bg-subtle);
    color: var(--bs-warning-text-emphasis);
    border-color: var(--bs-warning-border-subtle);
}
.toast.portal-toast-info {
    --bs-toast-bg: var(--bs-info-bg-subtle);
    color: var(--bs-info-text-emphasis);
    border-color: var(--bs-info-border-subtle);
}
.toast.portal-toast-success .toast-header,
.toast.portal-toast-danger .toast-header,
.toast.portal-toast-warning .toast-header,
.toast.portal-toast-info .toast-header {
    color: inherit;
}

/* Länger dauernde UI-Aktion (z. B. PDF-Export) – über Modals/Toasts */
.portal-busy-overlay {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.72);
}
.portal-busy-overlay[hidden] {
    display: none !important;
}
.portal-busy-panel {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    padding: 1.25rem 1.5rem;
    border-radius: var(--bs-border-radius-lg);
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    box-shadow: var(--bs-box-shadow);
    max-width: min(22rem, 90vw);
    text-align: center;
}
.portal-busy-panel .portal-busy-text {
    margin: 0;
    font-size: 0.95rem;
    color: var(--bs-body-color);
}

/* Soft-ungültig (Wiki-Toggle in AP / FNet / LNK) */
tr.portal-row-ungueltig > td:not(.text-end),
tr.portal-row-ungueltig > td:not(.text-end) a {
    text-decoration: line-through;
    color: var(--bs-secondary-color);
}
tr.portal-row-ungueltig > td.text-end,
tr.portal-row-ungueltig > td .btn,
tr.portal-row-ungueltig > td .badge {
    text-decoration: none;
}

/* Chart-Kachel: feste Höhe für Chart.js (maintainAspectRatio: false) */
.portal-chart-wrap {
    position: relative;
    height: var(--portal-chart-height);
    width: 100%;
}

