﻿/* ──────────────────────────────────────────────────────────────────────────
   Styles der eigenen Steuerelemente (Shared/Controls). Nutzt ausschliesslich
   Bootstrap 5 + Font Awesome, die ohnehin schon geladen sind.
   ────────────────────────────────────────────────────────────────────────── */

/* ── Formularfeld: Beschriftung steht ueber dem Eingabefeld ──
   Feste rem-Groessen, damit eine geerbte Schriftgroesse die Formulare
   nicht aufblaeht. */
.hpo-field {
    margin-bottom: .85rem;
}

.hpo-label {
    display: block;
    margin-bottom: .25rem;
    font-size: .85rem;
    font-weight: 600;
    line-height: 1.3;
    color: #5a6472;
}

/* 1rem entspricht dem, was Bootstrap fuer .form-control ohnehin setzt - die
   Eingabefelder bleiben also so gross wie bisher, nur die Beschriftung wandert
   nach oben. */
.hpo-field .form-control {
    font-size: 1rem;
    min-height: 2.6rem;
}

.hpo-field textarea.form-control {
    min-height: 5.5rem;
}

.hpo-field .form-control:disabled,
.hpo-field .hpo-readonly {
    background-color: #f2f2f2;
    color: #55606e;
}

.hpo-field .form-control:focus {
    border-color: var(--hpo-navy, #324E76);
    box-shadow: 0 0 0 .18rem rgba(50, 78, 118, .15);
}

/* ── Fehlende Pflichtangabe ──
   Bootstrap legt bei .is-invalid zusätzlich ein Ausrufezeichen als Hintergrundbild
   rechts ins Feld. Das säße beim Auswahlfeld unter dem Pfeil und beim Zahlenfeld
   neben der mittig stehenden Zahl - der rote Rahmen allein sagt dasselbe. */
.hpo-field .form-control.is-invalid {
    background-image: none;
    padding-right: .75rem;
}

/* Die eingebauten Input*-Komponenten (Anmeldung) kennzeichnen ein fehlerhaftes Feld
   mit "invalid"; Bootstrap kennt nur "is-invalid". Damit sehen beide gleich aus. */
.form-control.invalid {
    border-color: #dc3545;
}

.form-control.invalid:focus {
    border-color: #dc3545;
    box-shadow: 0 0 0 .18rem rgba(220, 53, 69, .2);
}

/* ── Zahlenfeld mit Schritt-Tasten (HpoNumericTextBox) ──
   Die Tasten sitzen bündig links und rechts am Feld (input-group), wie die Pfeile
   der Datumsauswahl. Sie tragen nur ein Symbol und bleiben deshalb schmal - der
   Platz gehört der Zahl, die zwischen ihnen mittig steht. Auf gesperrten Feldern
   (berechnete Stunden) zeichnet die Komponente sie gar nicht erst. */
.hpo-numeric-btn {
    flex: 0 0 auto;
    padding-left: .75rem;
    padding-right: .75rem;
    color: #5a6472;
}

/* Der Rahmen der Tasten liegt sonst optisch vor dem Feld, sobald es den Fokus hat. */
.hpo-numeric .form-control:focus {
    z-index: 3;
}

/* ── Schalter (HpoCheckBox) ── */
.hpo-checkbox {
    font-size: .95rem;
    padding-left: 3rem;
}

.hpo-checkbox.form-switch .form-check-input {
    width: 2.5rem;
    height: 1.25rem;
    margin-left: -3rem;
    margin-top: .1rem;
    flex-shrink: 0;
}

.hpo-checkbox.form-switch .form-check-input:checked {
    background-color: var(--hpo-navy, #324E76);
    border-color: var(--hpo-navy, #324E76);
}

.hpo-checkbox.form-switch .form-check-input:focus {
    border-color: var(--hpo-navy, #324E76);
    box-shadow: 0 0 0 .18rem rgba(50, 78, 118, .15);
}

.hpo-checkbox .form-check-label {
    line-height: 1.45rem;
}

/* ── Kopfzeile einer Liste: links die Ueberschrift, rechts die Aktion ──
   "Neu" steht rechts wie in den Views mit Datumsauswahl - der Knopf soll auf
   jedem Bildschirm an derselben Stelle sitzen. */
.hpo-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: nowrap;
    gap: .5rem;
    flex-shrink: 0;
    margin-bottom: .75rem;
}

.hpo-toolbar > .btn {
    flex: 0 0 auto;
    white-space: nowrap;
}

.hpo-toolbar-title {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
    color: #495057;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.hpo-toolbar-count {
    margin-left: .4rem;
    font-weight: 400;
    color: #8a929c;
}

/* Foto-/Datei-Schaltflaechen in den Erfassungsdialogen. */
.hpo-file-buttons {
    display: flex;
    gap: .5rem;
    margin-top: .25rem;
}

.hpo-file-buttons > label {
    flex: 1 1 0;
    margin: 0;
}

/* ── Statuskennzeichen der Listeneintraege ──
   Der Status steckt einheitlich im Badge, nicht im Rand der Karte. Palette wie
   bei den Toasts (Bootstraps Alert-Toene), damit "gelb heisst offen" ueberall
   dasselbe bedeutet. */
.hpo-badge {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    padding: .1rem .55rem;
    border-radius: 10rem;
    border: 1px solid #ced4da;
    background: #e9ecef;
    color: #495057;
    font-size: .75rem;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
}

.hpo-badge i {
    font-size: .85em;
}

/* offen, Entwurf, gemeldet, beantragt, wartet auf Uebertragung */
.hpo-badge-open {
    background: #fff3cd;
    border-color: #ffecb5;
    color: #664d03;
}

/* in Bearbeitung, bereit zur Uebertragung */
.hpo-badge-progress {
    background: #cff4fc;
    border-color: #b6effb;
    color: #055160;
}

/* erledigt, genehmigt, uebertragen */
.hpo-badge-done {
    background: #d1e7dd;
    border-color: #badbcc;
    color: #0f5132;
}

/* abgelehnt */
.hpo-badge-rejected {
    background: #f8d7da;
    border-color: #f5c2c7;
    color: #842029;
}

/* freigegeben, abgerechnet - abgeschlossen und nicht mehr aenderbar */
.hpo-badge-locked {
    background: #dbe4f0;
    border-color: #c3d1e4;
    color: #263f60;
}

/* ── Aufbau einer Listenkarte ──
   Aktionen immer oben rechts, Statuskennzeichen immer unten rechts - in jeder
   Liste an derselben Stelle. */
.hpo-card-actions {
    display: flex;
    align-items: center;
    gap: .1rem;
    flex: 0 0 auto;
    margin-left: auto;
}

.hpo-card-action {
    border: 0;
    background: transparent;
    color: #8a929c;
    padding: .25rem .45rem;
    border-radius: 4px;
    line-height: 1;
    font-size: .95rem;
}

.hpo-card-action:hover {
    background: #eef1f5;
    color: var(--hpo-navy, #324E76);
}

.hpo-card-action-delete:hover {
    background: #fdf2f3;
    color: #dc3545;
}

.hpo-card-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: .35rem;
    margin-top: .45rem;
}

/* ── Spinner ── */
.hpo-spinner-overlay {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, .6);
}

.hpo-spinner-box {
    text-align: center;
    color: var(--hpo-navy, #324E76);
}

.hpo-spinner-label {
    margin-top: .5rem;
    font-size: .9rem;
}

/* ── Gemeinsamer Hintergrund für Overlay-Elemente ──
   Ebenen (von unten nach oben): Seitenmenü 1400 · Dialog 1500 · verschachtelter
   Dialog 1600 · Auswahlliste 1690 · Toast 1750 · Melde-/Bestätigungsdialog 1800 ·
   Spinner 2000. Eine Auswahlliste muss über jedem Dialog liegen, in dem sie steht. */
.hpo-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .45);
    z-index: 1400;
}

.hpo-modal-overlay {
    z-index: 1500;
}

.hpo-modal-nested.hpo-modal-overlay {
    z-index: 1600;
}

.hpo-select-overlay {
    z-index: 1690;
    background: rgba(0, 0, 0, .3);
}

/* ── Auswahlliste (HpoSelect) ── */
.hpo-select-box {
    position: relative;
}

.hpo-select-trigger {
    display: flex;
    align-items: center;
    background-color: #fff;
    /* Platz fuer den Pfeil am rechten Rand ... */
    padding-right: 2.25rem;
}

/* ... und zusaetzlich fuer die Leeren-Schaltflaeche, wenn sie sichtbar ist. */
.hpo-select-clearable .hpo-select-trigger {
    padding-right: 3.75rem;
}

.hpo-select-trigger > span {
    flex: 1 1 auto;
    min-width: 0;
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
}

.hpo-select-trigger:disabled {
    background-color: #f2f2f2;
    opacity: 1;
}

.hpo-select-empty {
    color: #9aa3ad;
}

.hpo-select-caret {
    position: absolute;
    right: .75rem;
    top: 50%;
    transform: translateY(-50%);
    color: #8a929c;
    font-size: .85rem;
    pointer-events: none;
}

.hpo-select-clear {
    position: absolute;
    right: 2.1rem;
    top: 50%;
    transform: translateY(-50%);
    border: 0;
    background: transparent;
    color: #9aa3ad;
    padding: .2rem .35rem;
    line-height: 1;
    font-size: .85rem;
    z-index: 3;
}

.hpo-select-clear:hover {
    color: #dc3545;
}

/* ── Datumsauswahl mit Blättern (HpoDateNavigator) ──
   Die Pfeile sind buendig ans Datumsfeld gesetzt (input-group), danach folgen
   "Heute" und der Sprung nach vorn als eigener Block (.hpo-datenav-actions).

   width:fit-content ist der Kern der Zeilenaufteilung: der Navigator ist genau so
   breit wie sein Inhalt, hoechstens aber so breit wie der Platz. Solange alles
   nebeneinander passt, gibt es in ihm keinen freien Platz - die Schaltflaechen
   stehen also unmittelbar am Pfeil ">" und der ganze Block linksbuendig; was
   uebrig bleibt, geht an eine nachfolgende Schaltflaeche ("Neu"), die per
   margin-left:auto rechts steht.

   Wird es eng, rutscht der Schaltflaechenblock in die zweite Zeile - Flexbox
   verteilt die Elemente anhand ihrer Wunschbreite auf die Zeilen, das Datumsfeld
   wird also nicht erst zusammengedrueckt. Auf Zeile eins steht dann nur noch die
   input-group und nimmt mit flex-grow die volle Breite ein. Ohne Breakpoint,
   rein aus dem vorhandenen Platz. */
.hpo-datenav {
    display: flex;
    align-items: stretch;
    flex-wrap: wrap;
    gap: .5rem;
    flex: 0 1 auto;
    width: fit-content;
    max-width: 100%;
    min-width: 215px;
}

/* Waechst nur, wenn sie allein auf ihrer Zeile steht - sonst gibt es im
   Navigator gar keinen freien Platz, den sie aufnehmen koennte.
   Bewusst ohne min-width:0: die Gruppe soll nicht unter ihren Inhalt schrumpfen,
   sonst bricht der Schaltflaechenblock nie um. */
.hpo-datenav-group {
    width: auto;
    flex: 1 1 auto;
    flex-wrap: nowrap;
}

/* Ein Block, damit "Heute" und der Sprung nach vorn gemeinsam umbrechen. */
.hpo-datenav-actions {
    display: flex;
    gap: .5rem;
    flex: 0 0 auto;
}

/* Schmaler als eine normale Schaltflaeche - sie tragen nur ein Symbol. Der so
   gewonnene Platz geht ans Datumsfeld, das ihn unter Android braucht. */
.hpo-datenav-btn,
.hpo-datenav-today {
    flex: 0 0 auto;
    white-space: nowrap;
    padding-left: .6rem;
    padding-right: .6rem;
}

/* Das Kalendersymbol zeichnen wir selbst, weil Chrome unter Android
   ::-webkit-calendar-picker-indicator gar nicht darstellt - dort stuende das
   Feld sonst ohne jeden Hinweis da. Es sitzt rechts an derselben Stelle wie
   das native, damit es nur eines bleibt; das native wird unsichtbar geschaltet
   (nicht entfernt) und liegt als Schaltflaeche darunter. Am Rechner oeffnet ein
   Klick darauf weiterhin den Kalender, auf dem Handy tut das ein Tippen ins Feld.

   Der Innenabstand ist beidseitig gleich, sonst stuende das Datum nicht mittig
   zwischen den Pfeilen. Er ist aber knapper als frueher (1.9rem) und das Symbol
   etwas kleiner und naeher am Rand - unter Android braucht das native Datumsfeld
   mehr Breite als am Rechner, sonst fehlt die Jahreszahl. */
.hpo-datenav-input {
    padding-left: 1.35rem;
    padding-right: 1.35rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%236c757d' stroke-width='1.3' stroke-linecap='round'%3E%3Crect x='1.6' y='2.6' width='12.8' height='11.8' rx='1.6'/%3E%3Cpath d='M1.6 6.4h12.8M5 1.2v2.8M11 1.2v2.8'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .3rem center;
    background-size: .9rem .9rem;
}

/* 12rem fassen das ganze Datum samt Jahr. Mehr wird das Feld nur, wenn die
   input-group allein auf ihrer Zeile steht und die volle Breite bekommt - dann
   soll der Platz ins Datum und nicht hinter den Pfeil ">". Nach unten ist bei
   10.5rem Schluss, sonst schneidet Android wieder die Jahreszahl ab; ab da
   bricht stattdessen um, was daneben steht.

   Die Regel braucht drei Klassen: Bootstraps ".input-group > .form-control"
   setzt flex:1 1 auto / width:1% und waere sonst staerker als eine Einzelklasse. */
.hpo-datenav .hpo-datenav-group > .hpo-datenav-input {
    flex: 1 1 auto;
    width: 12rem;
    min-width: 10.5rem;
}

/* Unsichtbar, aber weiterhin anklickbar - und per negativem Aussenabstand unter
   das gezeichnete Symbol geschoben, damit der Klick dort landet, wo man ihn
   erwartet. Der Aussenabstand hebt die Breite genau auf: sonst nimmt das
   Pseudoelement dem Datum Platz weg (deshalb fehlte unter Android die
   Jahreszahl), und es ragt genau ueber den Innenabstand rechts - nicht weiter,
   sonst schluckt es Klicks der Schaltflaeche ">" daneben. Browser ohne dieses
   Pseudoelement ignorieren die Regel. */
.hpo-datenav-input::-webkit-calendar-picker-indicator {
    opacity: 0;
    width: 1.35rem;
    margin-right: -1.35rem;
    cursor: pointer;
}

/* In einer Werkzeugleiste mit weiterer Schaltflaeche ("Neu") loesen wir den
   Kasten des Navigators auf: seine Teile werden dadurch zu Elementen der
   Werkzeugleiste und teilen sich mit "Neu" denselben Zeilenumbruch. Bliebe der
   Kasten stehen, waere er bei Platzmangel schon zweizeilig und "Neu" muesste in
   eine dritte Zeile ausweichen. Der Abstand ist derselbe (.5rem), die Reihenfolge
   ebenso - sichtbar aendert sich nur, wo umgebrochen wird. */
.ts-toolbar > .hpo-datenav,
.absense-toolbar > .hpo-datenav {
    display: contents;
}

/* Ohne eigenen Kasten gibt es freien Platz um die Gruppe herum - solange alles
   in eine Zeile passt, darf sie ihn nicht aufnehmen, sonst zoege sich das
   Datumsfeld auf und schoebe "Heute" und "Neu" an den rechten Rand. */
.ts-toolbar .hpo-datenav-group,
.absense-toolbar .hpo-datenav-group {
    flex: 0 1 auto;
}

/* Der Umbruch haengt hier an der Breite der Werkzeugleiste, nicht an der des
   Fensters - deshalb misst sie sich selbst (container-type). Die 23rem sind der
   Platz, den Datumsfeld, Pfeile, "Heute" und "Neu" nebeneinander brauchen; der
   Wert ist am Geraet nachgemessen, nicht nur gerechnet.

   Darunter wird gestapelt: die Gruppe bekommt die volle Zeile (flex-basis:100%),
   "Heute" und "Neu" ruecken gemeinsam in die zweite - "Neu" per margin-left:auto
   an deren rechten Rand. Ein fester Wert laesst sich hier nicht vermeiden, weil
   Flexbox "wachse nur, wenn du allein auf der Zeile stehst" nicht kennt.
   Browser ohne Container-Abfragen bleiben beim bisherigen Verhalten. */
.ts-toolbar,
.absense-toolbar {
    container-type: inline-size;
}

@container (max-width: 23rem) {
    .ts-toolbar .hpo-datenav-group,
    .absense-toolbar .hpo-datenav-group {
        flex: 1 1 100%;
    }
}

/* Schaltflaechen neben der Datumsauswahl ("Neu") behalten ihre Breite und
   stehen dadurch immer rechts am Rand - auch dann, wenn sie als einzige in die
   zweite Zeile gerutscht sind (das Umbrechen erlauben .ts-toolbar und
   .absense-toolbar in ihrem eigenen CSS). */
.absense-toolbar > .btn,
.ts-toolbar > .btn {
    flex: 0 0 auto;
    white-space: nowrap;
    margin-left: auto;
}

/* Auswahl-Overlay: auf dem Handy als Blatt von unten, ab Tablet zentriert. */
.hpo-sheet {
    position: fixed;
    z-index: 1700;
    left: 0;
    right: 0;
    bottom: 0;
    max-height: 85vh;
    /* Die Hoehe wird beim Oeffnen aus der Zahl der Eintraege eingefroren (--hpo-sheet-rows,
       gesetzt von HpoSelect). Ohne das schrumpft das Blatt beim Filtern mit der Trefferzahl
       und wandert dabei nach unten - die Liste springt einem beim Tippen unter den Fingern weg. */
    height: min(calc(var(--hpo-sheet-rows, 100vh) + var(--hpo-sheet-chrome, 0px)), 85vh);
    display: flex;
    flex-direction: column;
    background: #fff;
    border-top-left-radius: 12px;
    border-top-right-radius: 12px;
    box-shadow: 0 -4px 24px rgba(0, 0, 0, .25);
}

@media (min-width: 768px) {
    .hpo-sheet {
        left: 50%;
        right: auto;
        bottom: auto;
        top: 50%;
        transform: translate(-50%, -50%);
        width: 480px;
        max-width: calc(100vw - 2rem);
        max-height: 70vh;
        height: min(calc(var(--hpo-sheet-rows, 100vh) + var(--hpo-sheet-chrome, 0px)), 70vh);
        border-radius: 8px;
        box-shadow: 0 4px 24px rgba(0, 0, 0, .25);
    }
}

.hpo-sheet-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding: .75rem 1rem;
    background: var(--hpo-navy, #324E76);
    color: #fff;
    border-top-left-radius: inherit;
    border-top-right-radius: inherit;
}

.hpo-sheet-header .btn-close {
    filter: invert(1) grayscale(100%) brightness(200%);
}

.hpo-sheet-title {
    font-weight: 600;
    font-size: 1.05rem;
}

.hpo-sheet-search {
    padding: .5rem .75rem;
    border-bottom: 1px solid #e5e5e5;
}

.hpo-sheet-list {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

.hpo-sheet-item {
    display: block;
    width: 100%;
    text-align: left;
    border: 0;
    border-bottom: 1px solid #f0f0f0;
    background: transparent;
    padding: .75rem 1rem;
    min-height: 46px;
    font-size: .95rem;
}

.hpo-sheet-item:hover {
    background: #E3F2FD;
}

.hpo-sheet-item-selected {
    background: #E3F2FD;
    font-weight: 600;
}

.hpo-sheet-item-empty {
    color: #888;
    font-style: italic;
}

.hpo-sheet-empty {
    padding: 1rem;
    text-align: center;
    color: #888;
}

/* ── Dialog / Modal ── */
.hpo-modal-wrap {
    position: fixed;
    inset: 0;
    z-index: 1550;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}

.hpo-modal-nested.hpo-modal-wrap {
    z-index: 1650;
}

.hpo-dialog.hpo-modal-wrap {
    z-index: 1850;
}

.hpo-dialog.hpo-modal-overlay {
    z-index: 1800;
}

.hpo-modal {
    pointer-events: auto;
    background: #fff;
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 1rem);
    max-width: calc(100vw - 1rem);
    border-radius: 8px;
    box-shadow: 0 4px 24px rgba(0, 0, 0, .3);
}

.hpo-modal-full {
    width: 100vw;
    max-width: 100vw;
    height: 100%;
    max-height: 100%;
    border-radius: 0;
}

.hpo-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding: .75rem 1rem;
    background: var(--hpo-navy, #324E76);
    color: #fff;
    border-top-left-radius: inherit;
    border-top-right-radius: inherit;
    flex: 0 0 auto;
}

.hpo-modal-header .btn-close {
    filter: invert(1) grayscale(100%) brightness(200%);
}

.hpo-modal-title {
    font-weight: 600;
    font-size: 1.05rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.hpo-modal-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: .75rem 1rem 1rem;
}

/* Dialoge mit Reitern: oben kein Polster. Die Reiterleiste klebt per sticky am
   oberen Rand - bliebe darueber Polster stehen, wuerde durchscrollender Inhalt
   in diesem Streifen sichtbar. */
.hpo-modal-tabs .hpo-modal-body {
    padding-top: 0;
}

.hpo-modal-footer {
    flex: 0 0 auto;
    display: flex;
    justify-content: flex-end;
    gap: .5rem;
    padding: .75rem 1rem;
    border-top: 1px solid #e5e5e5;
    background: #fafafa;
}

.hpo-dialog .hpo-modal-body {
    padding: 1.25rem 1rem;
}

.hpo-dialog-text {
    white-space: pre-line;
    font-size: .95rem;
    line-height: 1.5;
}

/* Fehlerlisten der DataAnnotations-Prüfung: ebenfalls feste Groesse, damit
   sie nicht die Schrift der Umgebung erben. */
.hpo-modal-body .validation-errors,
.hpo-modal-body .validation-message {
    font-size: .85rem;
}

/* ── Reiter (HpoTabs) ── */
.hpo-tabs {
    display: flex;
    flex-direction: column;
    min-height: 0;
}

/* Bleibt beim Scrollen des Dialoginhalts oben stehen. sticky ersetzt hier
   relative - als Bezugsrahmen fuer die Pfeile wirkt es genauso. */
.hpo-tab-header-wrap {
    position: sticky;
    top: 0;
    z-index: 3;
    flex: 0 0 auto;
    background: #fff;
}

.hpo-tab-header {
    display: flex;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border-bottom: 3px solid #e5e5e5;
    /* Scrollbalken ausblenden - stattdessen zeigen die Pfeile die Richtung an. */
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.hpo-tab-header::-webkit-scrollbar {
    display: none;
}

/* Pfeile am Rand: liegen ueber der Leiste, der Verlauf laesst den angeschnittenen
   Reiter darunter weich auslaufen. */
.hpo-tab-scroll {
    position: absolute;
    top: 0;
    bottom: 3px;
    width: 2.5rem;
    border: 0;
    padding: 0;
    display: flex;
    align-items: center;
    color: var(--hpo-navy, #324E76);
    font-size: .9rem;
    z-index: 2;
}

.hpo-tab-scroll-left {
    left: 0;
    justify-content: flex-start;
    padding-left: .25rem;
    background: linear-gradient(to right, #fff 55%, rgba(255, 255, 255, 0));
}

.hpo-tab-scroll-right {
    right: 0;
    justify-content: flex-end;
    padding-right: .25rem;
    background: linear-gradient(to left, #fff 55%, rgba(255, 255, 255, 0));
}

.hpo-tab-button {
    flex: 0 0 auto;
    border: 0;
    background: transparent;
    padding: .85rem 1.15rem;
    white-space: nowrap;
    color: var(--hpo-navy, #324E76);
    border-bottom: 3px solid transparent;
    margin-bottom: -3px;
    font-size: 1.05rem;
}

.hpo-tab-button.active {
    font-weight: 600;
    border-bottom-color: var(--hpo-orange, #DD6B2A);
}

.hpo-tab-content {
    flex: 1 1 auto;
    min-height: 0;
    /* Etwas Luft, damit das erste Feld nicht an der Reiterleiste klebt. */
    padding-top: .75rem;
}

.hpo-tab-pane[hidden] {
    display: none;
}

/* ── Kopfzeile (Ersatz für SfAppBar) ── */
.hpo-appbar {
    display: flex;
    align-items: center;
    gap: .5rem;
    min-height: 48px;
    /* Rechts mehr Luft als links: links steht eine Schaltflaeche, die ihren eigenen
       Innenabstand mitbringt, rechts endet die Leiste mit einem blanken Symbol. Mit
       gleichem Wert auf beiden Seiten klebte der Verbindungszustand am Bildschirmrand. */
    padding: 0 .9rem 0 .5rem;
    background-color: var(--hpo-orange, #DD6B2A);
    color: #fff;
}

/* Nimmt den freien Platz selbst ein. Ohne flex-grow schluckt ein separates
   Fuellelement den Platz, und ein langer Titel wird beim Schrumpfen bis auf
   Null gestaucht - dann steht in der Kopfzeile gar nichts mehr. */
.hpo-appbar-title {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 1.05rem;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.hpo-appbar-button {
    border: 0;
    background: transparent;
    color: #fff;
    padding: .4rem .6rem;
    border-radius: 4px;
    font-size: 1rem;
}

/* Feste Groesse fuer die Symbole rechts (Abgleich, Online-Status), damit sie
   die Schrift der Umgebung nicht erben. line-height: 1, weil das Symbol
   sonst auf der Grundlinie der geerbten Zeilenhoehe sitzt und dadurch tiefer
   steht als die Mitte der Leiste. */
.hpo-appbar .fa {
    font-size: 1rem;
    line-height: 1;
}

/* Eigener Flex-Kasten je Statussymbol - zentriert es unabhaengig von der
   Zeilenhoehe, die sein Umfeld vorgibt. */
.hpo-appbar-status {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
}

/* Der Abgleich zeigt nur waehrend eines Laufs ein Symbol. Bliebe die leere Huelle
   stehen, riss der Abstand der Leiste um eine Luecke auf und die Symbole rechts
   ruecken beim Abgleich sichtbar hin und her. */
.hpo-appbar-status:empty {
    display: none;
}

.hpo-appbar-button:hover,
.hpo-appbar-button:focus {
    background-color: var(--hpo-orange-hover, #BB5B24);
    color: #fff;
}

/* ── Seitenmenü (Ersatz für SfSidebar) ── */
.hpo-sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 280px;
    max-width: 85vw;
    background: #fff;
    z-index: 1420;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    box-shadow: 2px 0 12px rgba(0, 0, 0, .2);
    transform: translateX(-100%);
    transition: transform .25s ease;
    /* Feste Basisgroesse, damit eine geerbte Schriftgroesse das Menue nicht
       aufblaeht. */
    font-size: 1rem;
}

.hpo-nav {
    display: flex;
    flex-direction: column;
    min-height: 100%;
}

/* ── Benutzerblock im Menuekopf ── */
.hpo-nav-user {
    display: flex;
    align-items: center;
    gap: .65rem;
    padding: .9rem .85rem;
    border-bottom: 1px solid #e6e9ed;
    background: #f7f8fa;
}

.hpo-nav-avatar {
    flex: 0 0 auto;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    background: var(--hpo-navy, #324E76);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: .8rem;
    font-weight: 600;
    letter-spacing: .02em;
}

.hpo-nav-user-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: 1.25;
}

.hpo-nav-user-name {
    font-size: .9rem;
    font-weight: 600;
    color: #212529;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.hpo-nav-user-link {
    font-size: .75rem;
    color: #6c757d;
    text-decoration: none;
}

.hpo-nav-user-link:hover {
    color: var(--hpo-navy, #324E76);
    text-decoration: underline;
}

/* ── Fuss des Menues ── */
.hpo-nav-footer {
    margin-top: auto;
    border-top: 1px solid #e6e9ed;
}

/* Sprachwahl im Menuefuss: ueber der Versionsnummer, mittig wie diese. */
.hpo-nav-language {
    display: flex;
    justify-content: center;
    padding: .6rem .85rem .35rem;
}

.hpo-nav-version {
    padding: 0 .85rem .85rem;
    text-align: center;
    font-size: .7rem;
    color: #9aa3ad;
}

.hpo-sidebar.open {
    transform: translateX(0);
}

/* Schmaler Streifen am linken Rand, über den sich das Menü aufziehen lässt
   (Ersatz für SfSidebar EnableGestures). */
.hpo-sidebar-edge {
    position: fixed;
    top: 48px;
    left: 0;
    bottom: 0;
    width: 18px;
    z-index: 1100;
}

/* ── Navigationsbaum (Ersatz für SfTreeView) ── */
.hpo-navtree,
.hpo-navtree ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

.hpo-navtree {
    padding: .35rem 0;
}

.hpo-navtree ul {
    padding-left: 1.1rem;
}

.hpo-navtree-item {
    display: flex;
    align-items: center;
    gap: .6rem;
    width: 100%;
    border: 0;
    background: transparent;
    text-align: left;
    padding: 0 .85rem;
    height: 42px;
    line-height: 42px;
    color: #212529;
    font-size: .95rem;
}

.hpo-navtree-item:hover {
    background: #f2f4f7;
}

.hpo-navtree-item.active {
    background: var(--hpo-navy, #324E76);
    color: #fff;
}

.hpo-navtree-item .hpo-navtree-icon {
    width: 1.2rem;
    text-align: center;
}

.hpo-navtree-item .hpo-navtree-caret {
    margin-left: auto;
    font-size: .8rem;
    opacity: .6;
}

.hpo-sidebar .nav-actions {
    display: flex;
    flex-direction: column;
    gap: .4rem;
    padding: .75rem .85rem .5rem;
}


/* ── Toasts (Ersatz für SfToast) ── */
.hpo-toast-container {
    position: fixed;
    z-index: 1750;
    display: flex;
    flex-direction: column;
    gap: .5rem;
    pointer-events: none;
}

.hpo-toast-container.bottom-right {
    right: 1rem;
    bottom: 1rem;
    align-items: flex-end;
}

.hpo-toast-container.top-center {
    top: 1rem;
    left: 50%;
    transform: translateX(-50%);
    align-items: center;
}

/* Flaechige Farben nach Bootstrap-Palette. Feste rem-Groessen fuer den Text,
   damit er die Schrift der Umgebung nicht erbt. */
.hpo-toast {
    pointer-events: auto;
    min-width: 320px;
    max-width: calc(100vw - 2rem);
    border-radius: 6px;
    box-shadow: 0 2px 12px rgba(0, 0, 0, .15);
    background: #e9ecef;
    color: #212529;
    border: 1px solid #ced4da;
    overflow: hidden;
}

.hpo-toast-body {
    display: flex;
    align-items: center;
    gap: .7rem;
    padding: .9rem 1rem;
}

.hpo-toast-icon {
    flex: 0 0 auto;
    font-size: 1.25rem;
    line-height: 1.4;
    color: inherit;
}

.hpo-toast-text {
    flex: 1 1 auto;
    min-width: 0;
    text-align: center;
}

.hpo-toast-title {
    font-weight: 600;
    font-size: 1rem;
    line-height: 1.4;
    word-break: break-word;
}

.hpo-toast-content {
    font-size: .9rem;
    line-height: 1.4;
    color: inherit;
    opacity: .9;
    word-break: break-word;
}

.hpo-toast .btn-close {
    flex: 0 0 auto;
    font-size: .7rem;
    opacity: .6;
}

/* Farbpalette von Bootstraps Alerts: getoenter Hintergrund, dunkler Text in
   derselben Farbfamilie. Deutlich ruhiger als die vollen Signalfarben und
   trotzdem auf den ersten Blick unterscheidbar. */
.hpo-toast-success {
    background: #d1e7dd;
    border-color: #badbcc;
    color: #0f5132;
}

.hpo-toast-warning {
    background: #fff3cd;
    border-color: #ffecb5;
    color: #664d03;
}

.hpo-toast-danger {
    background: #f8d7da;
    border-color: #f5c2c7;
    color: #842029;
}

.hpo-toast-info {
    background: #cff4fc;
    border-color: #b6effb;
    color: #055160;
}

.hpo-toast-progress {
    height: 2px;
    background: rgba(0, 0, 0, .18);
    width: 100%;
    animation-name: hpo-toast-progress;
    animation-timing-function: linear;
    animation-fill-mode: forwards;
}

@keyframes hpo-toast-progress {
    from { width: 100%; }
    to   { width: 0; }
}

/* ── Statusanzeigen in der Kopfzeile ──
   Keine eigene Farbe: die Kopfzeile ist über AdvancedSettings.ThemeColor
   einstellbar, deshalb erben die Symbole ihre Farbe von ihr.
   Unterschieden wird über das Symbol selbst (Haken bzw. Kreuz). */
.hpo-status-ok,
.hpo-status-off {
    color: inherit;
}

/* ── Positionslisten in den Arbeitsnachweis-Reitern (bisher SfGrid) ── */
.ts-poslist {
    padding: .25rem 0;
}


.ts-posrow {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    border: 1px solid #dee2e6;
    border-radius: 6px;
    padding: .6rem .75rem;
    margin-bottom: .5rem;
    background: #fff;
}

.ts-posrow-main {
    flex: 1 1 auto;
    min-width: 0;
    cursor: pointer;
}

.ts-posrow-title {
    font-weight: 600;
    font-size: .95rem;
}

.ts-posrow-detail {
    font-size: .85rem;
    color: #555;
    word-break: break-word;
}

.ts-posrow-actions {
    flex: 0 0 auto;
    display: flex;
    gap: .15rem;
}

.btn-pos-action {
    border: 0;
    background: transparent;
    color: #666;
    padding: .3rem .45rem;
    border-radius: 4px;
}

.btn-pos-action:hover {
    background: #f0f0f0;
}

/* Bewusst ohne feste Hoehe: die Reiterleiste klebt per position:sticky oben und
   kann das nur innerhalb der Box ihres Elternelements. Waere .hpo-tabs auf die
   sichtbare Hoehe begrenzt, wuerde die Leiste beim Weiterscrollen doch
   verschwinden. */
.ts-tabs {
    min-height: 100%;
}

/* Karte, die sich zum Ansehen/Bearbeiten oeffnen laesst. */
.hpo-card-clickable {
    cursor: pointer;
}

/* Uebertragene Datensaetze bekommen eine gruene Kante links - auf einen Blick
   erkennbar, was schon beim Server ist, ohne das Badge lesen zu muessen.
   !important, weil die Karten ihren Rahmen in ihrem eigenen scoped CSS setzen. */
.hpo-card-synced {
    border-left: 4px solid #198754 !important;
}

/* Aktionen im Kopf einer Karte, deren Kopf kein Flex-Container ist. */
.attachment-title {
    display: flex;
    align-items: center;
    gap: .4rem;
}

/* ── "Update verfuegbar"-Leiste (Toolbelt.Blazor.PWA.Updater) ──
   Das Paket steuert seine Groesse ueber CSS-Variablen. Seine eigene Regel traegt
   das Scope-Attribut [b-pwa-updater] und damit hoehere Spezifitaet - deshalb
   !important. */
.pwa-updater {
    --pwa-updater-font-size: 15px !important;
    --pwa-updater-bar-height: 46px !important;
}

/* ── Unterschrift (HpoSignaturePad) ──
   touch-action: none ist Pflicht - ohne das scrollt das Handy die Seite, statt
   den Strich zu zeichnen. Die feste Hoehe gibt der Flaeche eine Groesse, bevor
   das Canvas vermessen wird. */
.hpo-signature {
    width: 100%;
}

.hpo-signature-canvas {
    display: block;
    width: 100%;
    height: 180px;
    background-color: #fff;
    border: 1px solid #ced4da;
    border-radius: .375rem;
    touch-action: none;
}
