/* Auftragserfassung - eigene Styles */

/* ============================================================
   Globaler Chevron-Animations-Stack für Collapse-Toggles.
   Funktioniert mit allen üblichen Klassen-Konventionen:
     .collapse-chevron, .vac-chevron, .month-chevron,
     .completed-chevron, .kdv-chevron, .holiday-chevron,
     .user-block-chevron, ...
   Voraussetzung: das Toggle-Element hat
     - data-bs-toggle="collapse"
     - aria-expanded="true"/"false"
   Der globale JS-Helper in app.js synct aria-expanded zuverlässig
   auch auf <div>/<span>-Toggles. display:inline-block ist Pflicht,
   sonst greift transform: rotate auf einem <i> nicht.
   ============================================================ */
[data-bs-toggle="collapse"] [class*="-chevron"] {
    display: inline-block;
    transform-origin: center;
    transition: transform .2s ease;
}
[data-bs-toggle="collapse"][aria-expanded="false"] [class*="-chevron"],
[data-bs-toggle="collapse"].collapsed [class*="-chevron"] {
    transform: rotate(-90deg);
}

/* Schriftgrößen-Abstufung Mobile-First */
body {
    font-size: 1rem;
    -webkit-tap-highlight-color: transparent;
}

/* ============================================================
   Persönliche Schriftgrößen-Modi (Profil-Einstellung)
   "normal" ist Default und braucht keine Klasse.
   ============================================================ */
body.font-size-large {
    font-size: 1.25rem;
}
body.font-size-large h1 { font-size: 2.4rem; }
body.font-size-large h2 { font-size: 2.0rem; }
body.font-size-large .h3 { font-size: 1.85rem !important; }
body.font-size-large .small,
body.font-size-large small { font-size: 1.0rem !important; }
body.font-size-large .order-list-item .customer-name { font-size: 1.5rem; }
body.font-size-large .order-list-item .description-preview { font-size: 1.15rem !important; }
body.font-size-large .badge { font-size: 0.95rem; }
body.font-size-large .btn { font-size: 1.15rem; }
body.font-size-large .form-control,
body.font-size-large .form-select { font-size: 1.15rem; }

body.font-size-xlarge {
    font-size: 1.5rem;
    font-weight: 500;
}
body.font-size-xlarge h1,
body.font-size-xlarge h2,
body.font-size-xlarge .h3,
body.font-size-xlarge .h4,
body.font-size-xlarge .h5,
body.font-size-xlarge .h6 { font-weight: 800 !important; }
body.font-size-xlarge h1 { font-size: 2.9rem; }
body.font-size-xlarge h2 { font-size: 2.4rem; }
body.font-size-xlarge .h3 { font-size: 2.2rem !important; }
body.font-size-xlarge .small,
body.font-size-xlarge small { font-size: 1.2rem !important; font-weight: 500; }
body.font-size-xlarge .order-list-item .customer-name {
    font-size: 1.85rem;
    font-weight: 800;
}
body.font-size-xlarge .order-list-item .description-preview {
    font-size: 1.4rem !important;
    color: #333 !important;
    font-weight: 500;
}
body.font-size-xlarge .order-list-item .appointment-block {
    font-size: 1.2rem;
    font-weight: 700;
    padding: 6px 14px;
}
body.font-size-xlarge .order-list-item .meta-footer { font-size: 1rem; }
body.font-size-xlarge .badge { font-size: 1.1rem; font-weight: 700; padding: 0.35em 0.7em; }
body.font-size-xlarge .btn {
    font-size: 1.4rem;
    font-weight: 600;
    padding: 0.6rem 1.1rem;
}
body.font-size-xlarge .form-control,
body.font-size-xlarge .form-select {
    font-size: 1.4rem;
    padding: 0.7rem 0.95rem;
    font-weight: 500;
}
body.font-size-xlarge .form-label { font-weight: 700; font-size: 1.2rem; }
body.font-size-xlarge .navbar { font-size: 1.3rem; font-weight: 600; }
body.font-size-xlarge .nav-link { font-weight: 600; }
body.font-size-xlarge .table { font-size: 1.25rem; }
body.font-size-xlarge .table th { font-weight: 800; }
body.font-size-xlarge .alert { font-size: 1.25rem; font-weight: 500; }

/* Druck soll IMMER normale Größe haben, unabhängig vom Bildschirm-Modus */
@media print {
    body.font-size-large,
    body.font-size-xlarge {
        font-size: 1rem !important;
        font-weight: normal !important;
    }
    body.font-size-large *,
    body.font-size-xlarge * {
        font-size: revert !important;
        font-weight: revert !important;
    }
}

/* Karten-Hover-Effekt für die Dashboard-Kacheln */
a.text-decoration-none .card {
    transition: transform .15s ease, box-shadow .15s ease;
}
a.text-decoration-none:hover .card {
    transform: translateY(-2px);
    box-shadow: 0 .5rem 1rem rgba(0,0,0,.1) !important;
}

/* Cards mit border-0 verschwinden auf weissem/hellem Hintergrund.
   Wir setzen ueberall einen dezenten aber sichtbaren Border, damit
   Container voneinander abgegrenzt sind - auch auf "schwachen" Monitoren. */
.card.border-0 {
    border: 1px solid rgba(0, 0, 0, .12) !important;
}
.card.shadow-sm {
    box-shadow: 0 .125rem .35rem rgba(0, 0, 0, .12) !important;
}

/* ============================================================
   Touch / Mobile Quality-of-Life
   ============================================================ */

/* Tap-Highlight (graues Rechteck beim Antippen) global aus — sieht auf
   Tablets schmuddelig aus und :active-Feedback macht das schon. */
* {
    -webkit-tap-highlight-color: transparent;
}

/* Größere Touch-Ziele auf Mobilgeräten */
@media (max-width: 576px) {
    .btn, .form-control, .form-select {
        min-height: 44px;
    }

    /* iOS zoomed beim Fokussieren in ein Input rein, wenn dessen
       computed font-size < 16px ist. Bootstrap-Defaults sind 1rem,
       aber kleinere Form-Controls (.form-control-sm, Inline-Edit-
       Tabellen) liegen darunter. Pauschale 16px hier verhindert das
       ungewollte Zoom-In auf iPad/iPhone. */
    input[type="text"],
    input[type="email"],
    input[type="search"],
    input[type="password"],
    input[type="number"],
    input[type="tel"],
    input[type="url"],
    input[type="date"],
    input[type="datetime-local"],
    input[type="month"],
    input[type="time"],
    input[type="week"],
    select,
    textarea {
        font-size: 16px !important;
    }

    /* ============================================================
       Auftragslisten-Karten auf Smartphones (~380-430 CSS-Pixel breit):
       
       Default-Layout reserviert per padding-right: 175px die rechte Spalte
       für den absolute-positionierten Action-Stack (Termin/Drucken/Erledigt).
       Das ist auf Desktop schick, aber auf Mobile zwingt es auch die
       Beschreibungs-Box - die UNTER dem Stack steht und daher dort gar
       keinen Platz reservieren müsste - in nur ~60% der Karten-Breite.
       
       Lösung: padding-right der Karte auf normal zurück, dafür die obere
       Zeile (Kundenname + Stack) und die Badge-Zeile selbst mit dem
       padding-right ausstatten - so weichen NUR die oberen Inhalte dem
       absoluten Stack aus, die description-preview unten nutzt die volle
       Karten-Breite.
       
       Wirkt auf:
         - app/Views/orders/index.php (Aufträge-Listen-Ansicht)
         - app/Views/dashboard/_order_row.php (Dashboard-Auftragszeilen,
           5x eingebunden für Heute/Woche/Backlog/Erledigt/Dringend)
       
       Hinweis: Specificity-Trick mit doppeltem Klassen-Selektor
       (.order-list-item.order-list-item) ist nötig, weil der Default-Block
       später in der Datei steht und bei gleicher Spezifität gewinnen würde.
       ============================================================ */
    .order-list-item.order-list-item {
        padding-right: 16px !important;
    }
    /* Obere Zeile (Kundenname links, Action-Stack rechts via absolute):
       padding-right damit der Kundenname-Text nicht UNTER dem Stack landet. */
    .order-list-item.order-list-item > .d-flex.justify-content-between.mb-1 {
        padding-right: 159px;
    }
    /* Badge-Zeile (Auftragsnummer, Status, Priorität, Kategorie, Ort, Monteur):
       ebenfalls am Stack vorbei, weil sie im selben vertikalen Bereich liegt. */
    .order-list-item.order-list-item > .d-flex.align-items-center.flex-wrap.small {
        padding-right: 159px;
    }
    /* description-preview braucht keine spezielle Regel - sie bekommt
       automatisch die volle Karten-Breite (padding-right wurde auf 16px reduziert). */
}

/* Prioritäts-Farbkennzeichnung als linker Balken */
.priority-bar {
    border-left: 5px solid var(--priority-color, #6c757d);
    padding-left: 16px;
}

/* Listenansicht: Kundenname groß als Überschrift */
.order-list-item .customer-name {
    font-size: 1.15rem;
    font-weight: 600;
    line-height: 1.3;
}

/* Order-Liste: Karten mit kleinem Abstand */
.order-list {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

/* Dashboard-Gruppen-Header (Heute, Diese Woche, etc.) */
.dashboard-group-header {
    padding: 8px 14px;
    border-radius: 6px;
    margin-bottom: 5px;
    border: 1px solid rgba(0,0,0,0.08);
}

/* Einzelne Karten: weißer Hintergrund, Schatten, abgerundete Ecken */
.order-list-item {
    display: block;
    background: #ffffff;
    color: #212529;
    border: 1px solid rgba(0,0,0,0.08);
    border-radius: 6px;
    padding: 14px 16px !important;
    box-shadow: 0 1px 2px rgba(0,0,0,0.04);
    transition: box-shadow 0.15s ease, transform 0.05s ease;
}
.order-list-item:hover {
    box-shadow: 0 2px 6px rgba(0,0,0,0.10);
    text-decoration: none;
    color: #212529;
}
.order-list-item:active {
    transform: translateY(1px);
}

/* Prioritäts-Balken bei List-Items: nur Border, kein eigenes Padding */
.order-list-item.priority-bar {
    border-left: 5px solid var(--priority-color, #6c757d);
    padding-left: 16px !important;
}

/* Termin-Block oben - groß und farblich hervorgehoben */
.order-list-item .appointment-block {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 12px;
    border-radius: 4px;
    font-size: .95rem;
    font-weight: 600;
    background: var(--priority-color, #6c757d);
    color: var(--priority-text-color, #fff);
}

/* Action-Stack rechts in der Karte: Termin + Drucken + Erledigt.
   Absolut positioniert, damit der Stack die Höhe der Karte nicht beeinflusst -
   die linke Inhalts-Spalte bleibt kompakt, egal wie viele Buttons rechts gestackt sind.
   Die Karte selbst bekommt rechts genug padding, damit kein Inhalt unter dem Stack landet,
   und eine Mindesthöhe, damit der unterste Button bei kurzen Aufträgen nicht überhängt. */
.order-list-item {
    position: relative;
    padding-right: 175px !important;
    min-height: 140px;
}
.order-list-item .order-action-stack {
    position: absolute;
    top: 12px;
    right: 12px;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    width: 150px;
    z-index: 2;
}
.order-list-item .order-action-stack .appointment-block {
    justify-content: center;
}
.order-list-item .order-action-stack .btn {
    text-align: center;
}

/* Beschreibung als clean-typografischer Textblock mit dezentem Border (Card-in-Card),
   ohne eigenen Hintergrund (transparent zur Order-Item-Farbe). Leicht fettere Schrift
   und mehr Abstand zur Badge-Zeile, ergaenzt durch feinen grauen Rahmen + minimalen
   Schatten - sieht aus wie ein in sich geschlossener Notiz-Block. */
.order-list-item .description-preview {
    display: -webkit-box;
    -webkit-line-clamp: var(--description-max-lines, 3);
    line-clamp: var(--description-max-lines, 3);
    -webkit-box-orient: vertical;
    overflow: hidden;
    white-space: pre-wrap;
    color: #1c1c1c;
    font-size: 1rem;
    font-weight: 500;
    line-height: 1.5;
    margin: 16px 0 0 0 !important;
    padding: 8px 10px !important;
    text-indent: 0 !important;
    border: 1px solid #dee2e6;
    border-radius: 4px;
    box-shadow: 0 1px 2px rgba(0,0,0,0.04);
}

/* Footer-Zeile mit Erstellt-Datum/Benutzer */
.order-list-item .meta-footer {
    margin-top: 8px;
    color: #6c757d;
    font-size: .8rem;
}

/* Druck-Layout */
@media print {
    .navbar, footer, .no-print { display: none !important; }
    body { background: white !important; }
    main { padding: 0 !important; }
}

/* =====================================================
   Leaflet-Popups: Bootstrap-Buttons korrekt darstellen
   =====================================================
   Leaflet definiert .leaflet-container a { color: #0078A8 } mit höherer
   Spezifität als Bootstraps .btn-primary - daher würden Buttons in
   Karten-Popups blau-grau statt weiß angezeigt.
   Die folgenden Overrides stellen die Bootstrap-Standard-Farben wieder
   her und entfernen die Leaflet-Unterstreichung.
   ===================================================== */
.leaflet-container a.btn {
    text-decoration: none;
}
.leaflet-container a.btn-primary,
.leaflet-container a.btn-primary:hover,
.leaflet-container a.btn-primary:focus {
    color: #fff;
}
.leaflet-container a.btn-outline-primary {
    color: var(--bs-primary, #0d6efd);
}
.leaflet-container a.btn-outline-primary:hover,
.leaflet-container a.btn-outline-primary:focus {
    color: #fff;
}
.leaflet-container a.btn-outline-secondary {
    color: #6c757d;
}
.leaflet-container a.btn-outline-secondary:hover,
.leaflet-container a.btn-outline-secondary:focus {
    color: #fff;
}
.leaflet-container a.btn-success,
.leaflet-container a.btn-success:hover,
.leaflet-container a.btn-success:focus,
.leaflet-container a.btn-danger,
.leaflet-container a.btn-danger:hover,
.leaflet-container a.btn-danger:focus,
.leaflet-container a.btn-warning,
.leaflet-container a.btn-warning:hover,
.leaflet-container a.btn-warning:focus {
    color: #fff;
}

/* =====================================================
   Password-Strength-Meter (siehe assets/js/password-strength.js)
   ===================================================== */
.pw-strength-meter .pw-bar {
    transition: width 0.25s ease, background-color 0.25s ease;
}
.pw-strength-meter .pw-checks li {
    transition: color 0.15s ease;
}
.pw-strength-meter .pw-icon {
    display: inline-block;
    width: 1.1em;
    text-align: center;
    font-weight: bold;
}

/* =====================================================
   Hoher Kontrast-Modus
   =====================================================
   Aktiv durch body.high-contrast. Verstärkt Hintergrundfarben,
   verdunkelt Texte und macht Rahmen deutlicher sichtbar -
   bewusst etwas zurückhaltend, damit die Anwendung nicht "hart"
   wirkt, aber dennoch deutlich lesbarer als im Normal-Modus.
   ===================================================== */
body.high-contrast {
    background: #fff !important;
    color: #1a1a1a;
}
body.high-contrast .card,
body.high-contrast .modal-content {
    border: 1px solid #444 !important;
    box-shadow: none !important;
}
body.high-contrast .card-header {
    background: #f0f0f0 !important;
    border-bottom: 1px solid #444 !important;
}
body.high-contrast .table-light,
body.high-contrast thead.table-light tr {
    background-color: #e0e0e0 !important;
    color: #1a1a1a !important;
}
body.high-contrast .table {
    border-color: #555 !important;
}
body.high-contrast .table > :not(caption) > * > * {
    border-bottom-color: #b0b0b0 !important;
}
body.high-contrast .text-muted,
body.high-contrast .small.text-muted {
    color: #555 !important;
}
body.high-contrast .form-control,
body.high-contrast .form-select {
    border: 1.5px solid #444 !important;
    background: #fff !important;
    color: #1a1a1a !important;
}
body.high-contrast .form-control:focus,
body.high-contrast .form-select:focus {
    border-color: #0a44d6 !important;
    box-shadow: 0 0 0 2px rgba(10,68,214,0.25) !important;
}
body.high-contrast .form-label {
    color: #1a1a1a !important;
    font-weight: 600;
}

/* Buttons: kräftigere Border und mehr Kontrast */
body.high-contrast .btn-outline-primary {
    border: 1.5px solid #0a44d6 !important;
    color: #0a44d6 !important;
    background: #fff !important;
}
body.high-contrast .btn-outline-secondary {
    border: 1.5px solid #555 !important;
    color: #1a1a1a !important;
    background: #fff !important;
}
body.high-contrast .btn-outline-success {
    border: 1.5px solid #1a7a36 !important;
    color: #1a7a36 !important;
    background: #fff !important;
}
body.high-contrast .btn-outline-danger {
    border: 1.5px solid #b80000 !important;
    color: #b80000 !important;
    background: #fff !important;
}
/* Ausgewählte btn-check-Toggles (z.B. Monteur-Auswahl beim Kundendienst) müssen
   auch im Kontrast-Modus als GEFÜLLT erkennbar sein. Ohne diese Regeln überschreibt
   die Outline-Regel oben (background:#fff !important) den Auswahl-Zustand, sodass
   ein angehakter Button optisch wie ein nicht angehakter aussieht. */
body.high-contrast .btn-check:checked + .btn-outline-primary {
    background: #0a44d6 !important;
    color: #fff !important;
    border-color: #0a44d6 !important;
}
body.high-contrast .btn-check:checked + .btn-outline-secondary {
    background: #555 !important;
    color: #fff !important;
    border-color: #555 !important;
}
body.high-contrast .btn-check:checked + .btn-outline-success {
    background: #1a7a36 !important;
    color: #fff !important;
    border-color: #1a7a36 !important;
}
body.high-contrast .btn-check:checked + .btn-outline-danger {
    background: #b80000 !important;
    color: #fff !important;
    border-color: #b80000 !important;
}
body.high-contrast .btn-primary,
body.high-contrast .btn-primary:not(:disabled):not(.disabled) {
    background: #0a44d6 !important;
    border-color: #0a44d6 !important;
    color: #fff !important;
}
body.high-contrast .btn-success,
body.high-contrast .btn-success:not(:disabled):not(.disabled) {
    background: #1a7a36 !important;
    border-color: #1a7a36 !important;
    color: #fff !important;
}
body.high-contrast .btn-danger,
body.high-contrast .btn-danger:not(:disabled):not(.disabled) {
    background: #b80000 !important;
    border-color: #b80000 !important;
    color: #fff !important;
}

/* Badges kräftiger */
body.high-contrast .badge {
    border: 1px solid rgba(0,0,0,0.25);
    font-weight: 600;
}
body.high-contrast .badge.bg-light {
    background: #e0e0e0 !important;
    color: #1a1a1a !important;
}
body.high-contrast .badge.bg-secondary {
    background: #444 !important;
    color: #fff !important;
}

/* Auftragslisten-Karten: deutlicher Rahmen + verstärkte Highlight-Farben */
body.high-contrast .order-list-item {
    border: 1px solid #444 !important;
    box-shadow: none !important;
}
body.high-contrast .order-list-item:hover {
    box-shadow: 0 0 0 2px rgba(10,68,214,0.25) !important;
}
body.high-contrast .order-list-item.priority-bar {
    border-left-width: 6px !important;
}

/* Navbar/Modul-Wechsler kräftiger */
body.high-contrast .navbar.bg-primary {
    background-color: #0a2b80 !important;
    border-bottom: 2px solid #1a1a1a !important;
}
body.high-contrast .navbar .nav-link,
body.high-contrast .navbar .navbar-brand,
body.high-contrast .navbar .navbar-text {
    color: #fff !important;
    font-weight: 500;
}

/* Alerts etwas kräftiger umranden */
body.high-contrast .alert {
    border-width: 1.5px !important;
    font-weight: 500;
}
body.high-contrast .alert-success { background: #d3f5dd !important; color: #0e3d1d !important; border-color: #1a7a36 !important; }
body.high-contrast .alert-danger  { background: #fde0e0 !important; color: #6b0000 !important; border-color: #b80000 !important; }
body.high-contrast .alert-warning { background: #fff5b8 !important; color: #503600 !important; border-color: #806600 !important; }
body.high-contrast .alert-info    { background: #d3e0ff !important; color: #0a2b80 !important; border-color: #0a44d6 !important; }

/* Links kräftiger */
body.high-contrast a {
    color: #0a44d6;
}
body.high-contrast a:hover {
    color: #082880;
    text-decoration: underline;
}

/* Tabellen-Highlights (überfällig/heute/zugewiesen/gedruckt) leicht intensivieren */
body.high-contrast .order-list-item[style*="background-color"] {
    border: 1px solid #444 !important;
    box-shadow: 1px 1px 0 rgba(0,0,0,0.08) !important;
}

/* =====================================================
   Article-Search Dropdown - Mobile-Anpassung
   =====================================================
   Auf Mobile-Bildschirmen ist das Eingabefeld oft schmal
   (z.B. in einer Tabelle mit wenig Spaltenbreite). Das
   Dropdown würde dann unleserlich klein werden. Daher
   strecken wir es auf Mobile bis fast zum Viewport-Rand
   und größere Items für Touch-Bedienung.
   ===================================================== */
@media (max-width: 768px) {
    .article-search-dropdown {
        /* left: 0 = relativ zum article-search-wrapper, also zur linken Kante des Inputs.
           min/max-width gewinnt gegen das Bootstrap w-100, der Dropdown wird breiter
           als das Input und ragt nach rechts in den Viewport. */
        left: 0 !important;
        width: auto !important;
        min-width: calc(100vw - 24px) !important;
        max-width: calc(100vw - 24px) !important;
    }
    /* Treffer-Items größer/luftiger für Touch-Bedienung */
    .article-search-dropdown .list-group-item {
        padding: 12px 14px;
        font-size: 0.95rem;
        line-height: 1.35;
    }
}

/* Treffer-Items immer auf Weiß — das Apple-Theme setzt --bs-body-bg auf
   Grau, das Bootstrap-Listen als Item-Hintergrund erben; die Liste sähe
   dann deaktiviert aus. Variante (.active, -warning) definieren die
   Variable am Item selbst neu und bleiben unberührt. */
.article-search-dropdown,
.customer-search-dropdown {
    --bs-list-group-bg: #fff;
}

/* Aktiver Treffer (Hover/Pfeiltasten): Bootstraps .active färbt den
   Hintergrund primärblau — text-muted bliebe grau und wäre darauf
   kaum lesbar. Muted-Zeilen daher auf Weiß aufhellen. */
.article-search-dropdown .list-group-item.active .text-muted,
.customer-search-dropdown .list-group-item.active .text-muted {
    color: rgba(255, 255, 255, 0.85) !important;
}

/* =====================================================
   Geteilte Kachel (z.B. "Alle / Meine Aufträge" auf Dashboard)
   =====================================================
   Die ganze Karte hebt sich beim Hover wie die anderen Kacheln,
   und die einzelne Hälfte zeigt zusätzlich einen leichten
   Hintergrund-Highlight, damit klar ist welche Seite geklickt wird.
   ===================================================== */
.split-tile {
    transition: transform .15s ease, box-shadow .15s ease;
}
.split-tile:hover {
    transform: translateY(-2px);
    box-shadow: 0 .5rem 1rem rgba(0,0,0,.1) !important;
}
.split-tile .tile-half {
    transition: background-color .15s ease;
}
.split-tile .tile-half:hover {
    background-color: rgba(13, 110, 253, 0.05);
}


/* ============================================================
   Admin-Kennzeichnung
   Elemente, die NUR Admins sehen (Navbar-Punkte, Buttons, Cards),
   tragen .admin-marked und sind einheitlich gelb umrandet -
   gleiche Optik wie die Admin-Card im Auftrags-Detail.
   Nur fuer admin-EXKLUSIVE Funktionen verwenden, nicht fuer
   Permission-basierte, die auch Nicht-Admins haben koennen.
   ============================================================ */
.admin-marked {
    border: 1px solid #ffc107 !important;
    border-radius: var(--bs-border-radius, .375rem);
}

/* ============================================================
   Diktat-Komponente (Spracheingabe, assets/js/dictation.js)
   Ohne Browser-Unterstuetzung blendet .no-dictation am <html>
   die Bars komplett aus.
   ============================================================ */
.no-dictation .dictation-bar {
    display: none !important;
}
.dictation-btn.recording {
    animation: dictation-pulse 1.2s ease-in-out infinite;
}
@keyframes dictation-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(220, 53, 69, 0.45); }
    70%  { box-shadow: 0 0 0 8px rgba(220, 53, 69, 0); }
    100% { box-shadow: 0 0 0 0 rgba(220, 53, 69, 0); }
}


/* ============================================================
   Auftrags-Timer (Arbeitszeit-Bereich im Auftrag)
   Gruener Puls-Punkt zeigt eine laufende Zeit an.
   ============================================================ */
.wt-timer-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #198754;
    animation: wt-timer-pulse 1.6s ease-in-out infinite;
}
@keyframes wt-timer-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: .25; }
}

/* --- Artikel-Thumbnails (article_thumb-Helper) --- */
.article-thumb {
    object-fit: cover;
    border-radius: 0.375rem;
    border: 1px solid #dee2e6;
    background: #fff;
    flex-shrink: 0;
}

/* Platz fuer die vertikale Scrollleiste IMMER reservieren: Seiten mit und
   ohne Scrollleiste haben sonst unterschiedlich breite Viewports, und der
   zentrierte Inhalt springt um ~8px (User-Befund 2026-09-03, Rechnungen). */
html { scrollbar-gutter: stable; }
/* Bootstrap-Modals gleichen die beim Oeffnen ausgeblendete Scrollleiste per
   inline padding-right (body, .sticky-top/.fixed-*) aus. Mit reserviertem
   Gutter wuerde das den Inhalt DOPPELT verschieben (Befund: Auftrags-Modal
   ueber der Liste) - Ausgleich daher neutralisieren (!important schlaegt
   Bootstraps Inline-Style). */
body.modal-open,
.modal-open .sticky-top,
.modal-open .fixed-top,
.modal-open .fixed-bottom,
.modal-open .is-fixed { padding-right: 0 !important; }
.modal-open .sticky-top { margin-right: 0 !important; }

/* Navbar: Modulname als Orientierung hinter dem Brand "Startseite" */
.navbar .navbar-module-label {
    /* Navbar-Textfarbe des jeweiligen Themes (dunkel: hell, Apple: dunkel) */
    color: var(--bs-navbar-color, rgba(255, 255, 255, .7));
    font-weight: 500;
    padding: 0;
    white-space: nowrap;
}
/* Navbar (aufgeklappt): wenn Menuepunkte bei Platznot zweizeilig werden
   (Icon ueber Text), stehen Dropdowns wie "Neu"/"Admin" sonst oben am Rand -
   alle Punkte vertikal auf die Mitte ausrichten. */
@media (min-width: 992px) {
    .navbar-expand-lg .navbar-nav { align-items: center; }

    /* Icon-Breite (1em) schon VOR dem Laden der Icon-Schrift reservieren:
       layout-nav.js misst den Umbruch inline beim ersten Parsen - so stimmt
       die Messung bereits ohne geladene Glyphen (kein Umspringen danach). */
    .navbar-nav > .nav-item > .nav-link > .bi:first-child {
        display: inline-block;
        min-width: 1em;
        text-align: center;
    }

    /* Platznot (layout-nav.js setzt .nav-stacked, sobald ein Punkt umbricht):
       ALLE Punkte einheitlich Icon zentriert ueber zentriertem Text -
       gilt fuer jede Modul-Navbar, weil alle dieselbe Liste nutzen. */
    .navbar-nav.nav-stacked > .nav-item > .nav-link {
        text-align: center;
        line-height: 1.2;
        padding-top: .3rem;
        padding-bottom: .3rem;
    }
    .navbar-nav.nav-stacked > .nav-item > .nav-link > .bi:first-child {
        display: block;
        margin: 0 auto .15rem;
        font-size: 1.2rem;
        line-height: 1;
    }
}

/* ============================================================
   Dashboard (/dashboard): Modul-Kacheln je User (s/m/l)
   4 Spalten Desktop, 2 Tablet, 1 Handy. s = 1x1, m = 2x1, l = 2x2.
   Bearbeiten-Modus (.is-editing): Griff + Groessen-Button sichtbar,
   Inhalte nicht klickbar. Kein pointer-events:none auf .sortable-drag
   (SortableJS-Merker aus dem Monteur-Board).
   ============================================================ */
/* Raster: 9 Spalten x 88px-Zeilen (StartPageService::COLS/MAX_H). --cols
   setzt start-page.js aus der Breite (Spalten >= 128px, max. 9; Tablet
   max. 4; Handy 1). Jede Kachel spannt --w Spalten x --h Zeilen
   (data-w/data-h), frei ziehbar im Anpassen-Modus (Ecke unten rechts).
   Der INHALT richtet sich per Container-Query nach der Kachelgroesse:
     1 Zeile (< 150px)   .start-tile-compact  Icon + Name (+ Badge)
     ab 2 Zeilen         .start-tile-full     Kopfleiste + Kennzahlen/Aktionen
     ab 3 Zeilen         .start-list          Liste, so viele Zeilen wie passen
     ab 560px breit      .start-row-x         Zusatzspalten in Listen
     < 400px breit       Aktionen als Reihe unter den Kennzahlen
     < 300px breit       "Oeffnen" nur als Pfeil, Name darf 2-zeilig werden */
.start-grid {
    --cols: 9;
    display: grid;
    grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
    grid-auto-rows: 88px;
    gap: 1rem;
}
.start-tile {
    --x: 1;
    --y: 1;
    --w: 1;
    --h: 1;
    /* feste Position im Raster (data-x/data-y); Fliesslayout s.u. */
    grid-column: var(--x) / span var(--w);
    grid-row: var(--y) / span var(--h);
    border: 0;
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    overflow: hidden;
    container-type: size;
    container-name: tile;
    transition: transform .15s ease, box-shadow .15s ease;
}
/* Fliesslayout (weniger als 9 Spalten, Tablet/Handy): DOM-Reihenfolge
   (= nach y/x sortiert), Breite geklemmt; kein Verschieben/Resize */
.start-grid-flow .start-tile { grid-column: span var(--w); grid-row: span var(--h); }
.start-grid-flow .start-tile-tools, .start-grid-flow .start-tile-resize { display: none !important; }
/* Verschieben: die gezogene Kachel folgt dem Zeiger (fixed), ein Platzhalter
   zeigt das Ziel im Raster (blau = frei, rot = belegt) */
.start-tile.is-dragging {
    position: fixed;
    z-index: 1000;
    pointer-events: none;
    opacity: .92;
    transition: none;
    box-shadow: 0 .75rem 1.5rem rgba(0,0,0,.22) !important;
}
.start-tile-placeholder {
    border: 2px dashed var(--bs-primary, #0d6efd);
    border-radius: var(--bs-card-border-radius, .375rem);
    background: rgba(13, 110, 253, .07);
}
.start-tile-placeholder.is-invalid {
    border-color: var(--bs-danger, #dc3545);
    background: rgba(220, 53, 69, .08);
}
/* Schnellsuche: das Ergebnis-Dropdown muss UEBER die Kachel hinausragen
   duerfen (overflow:hidden schnitt es ab); z-index hebt es ueber die
   Nachbar-Kacheln. */
.start-tile[data-key="suche"] { overflow: visible; z-index: 10; }
/* ... und auch der Body darf hier nicht clippen (overflow:hidden fuer die
   "safe center"-Kacheln schnitt das Ergebnis-Dropdown am Kachelende ab). */
.start-tile[data-key="suche"] .start-tile-body { overflow: visible; }
/* Ohne overflow:hidden clippt die Kachel die Kopfleiste nicht mehr an den
   runden Ecken - die Kopfleiste bekommt die oberen Radien daher selbst. */
.start-tile-head { border-top-left-radius: var(--bs-card-border-radius, .375rem); border-top-right-radius: var(--bs-card-border-radius, .375rem); }
/* Ganze Kachel klickbar (JS, data-home) - innere Controls bleiben eigenstaendig */
.start-tile[data-home] { cursor: pointer; }
.start-tile[data-home]:hover, .start-tile-solo:hover { box-shadow: 0 .5rem 1rem rgba(0,0,0,.1) !important; }
.start-tile-content {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    min-width: 0;
}
.start-tile-desktop, .start-tile-mobile { min-height: 0; }

/* ---- Stufe 1 Zeile: Icon + Name in einer Reihe, ganze Kachel ist der Link ---- */
.start-tile-compact {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .6rem;
    padding: .5rem 1rem;
    text-decoration: none;
    color: inherit;
    font-weight: 600;
    font-size: 1rem;
    min-width: 0;
}
.start-tile-compact > .bi:first-child { font-size: 2.1rem; color: var(--bs-primary, #0d6efd); line-height: 1; flex: none; }
.start-tile-compact .start-tile-label { min-width: 0; line-height: 1.2; hyphens: auto; overflow-wrap: anywhere; }
.start-tile-compact .badge { flex: none; }
a.start-tile-compact:hover { color: var(--bs-primary, #0d6efd); }
/* Zeiterfassung 1-zeilig: Symbol + Name (Link) links, Art/Ticker, Start/Stop rechts */
.start-tile-compact-stempel { justify-content: flex-start; gap: .5rem; }
.start-tile-compact-link { display: flex; align-items: center; gap: .5rem; text-decoration: none; color: inherit; min-width: 0; }
.start-tile-compact-link .bi { font-size: 2.1rem; line-height: 1; }
.start-tile-compact-link:hover { color: var(--bs-primary, #0d6efd); }
.start-stempel-badge { font-weight: 600; white-space: nowrap; }
select.start-stempel-type { width: auto; max-width: 9rem; }

/* ---- Stufe ab 2 Zeilen: Kopfleiste (sichtbarer Modul-Link) + Body ---- */
.start-tile-full { display: none; flex: 1 1 auto; flex-direction: column; min-height: 0; min-width: 0; }
.start-tile-head {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .55rem .75rem .55rem 1rem;
    font-weight: 600;
    text-decoration: none;
    min-width: 0;
    color: var(--bs-primary, #0d6efd);
    background: rgba(13, 110, 253, .08);
    border-bottom: 1px solid rgba(13, 110, 253, .12);
    transition: background .12s, color .12s;
}
.start-tile-head > .bi:first-child { font-size: 1.25rem; line-height: 1; flex: none; }
.start-tile-head .start-tile-label {
    min-width: 0;
    line-height: 1.2;
    hyphens: auto;
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.start-tile-open {
    margin-left: auto;
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: .2rem;
    font-size: .78rem;
    padding: .15rem .5rem .15rem .65rem;
    border-radius: 999px;
    background: #fff;
    border: 1px solid var(--bs-primary, #0d6efd);
    white-space: nowrap;
}
a.start-tile-head:hover { background: var(--bs-primary, #0d6efd); color: #fff; }
a.start-tile-head:hover .start-tile-open { background: transparent; border-color: rgba(255,255,255,.7); color: #fff; }
.start-tile-head-static { cursor: default; }
.start-tile-body {
    padding: .75rem 1rem 1rem;
    flex: 1 1 auto;
    min-height: 0;
    min-width: 0;
    /* Fuellt der Inhalt die Kachel nicht, verteilt sich der Rest oben+unten;
       "safe": laeuft er ueber, beginnt er oben und wird unten abgeschnitten
       (statt in die Kopfleiste zu ragen) */
    display: flex;
    flex-direction: column;
    justify-content: center;
    justify-content: safe center;
    overflow: hidden;
}
.start-kpi { text-decoration: none; color: inherit; min-width: 0; }
/* Grosse Kennzahlen in ALLEN Kacheln ab 2 Zeilen (User-Feedback: Platz nutzen) */
.start-kpi-num { font-size: 2.5rem; font-weight: 700; line-height: 1.1; white-space: nowrap; }
/* Aktions-Spalte rechts neben den Kennzahlen (schmal: Reihe darunter) */
.start-tile-actions { margin-left: auto; display: flex; flex-direction: column; gap: .5rem; align-items: stretch; }
/* Liste: ab 3 Zeilen; zeigt so viele Zeilen wie passen (Rest ausgeblendet) */
.start-list {
    display: none;
    font-size: .9rem;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
    -webkit-mask-image: linear-gradient(#000 calc(100% - 16px), transparent);
            mask-image: linear-gradient(#000 calc(100% - 16px), transparent);
}
/* Listen, die der Hauptinhalt der Kachel sind (Schaltplaene): schon ab 2 Zeilen */
.start-list-main { display: block; }
.start-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: .5rem;
    padding: .3rem 0;
    border-top: 1px solid rgba(0,0,0,.075);
    text-decoration: none;
    color: inherit;
    min-width: 0;
}
a.start-row:hover { color: var(--bs-primary, #0d6efd); }
.start-row > :first-child { min-width: 0; }
.start-row-x { display: none; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #6c757d; }

/* Schnellsuche: nur EINE Stufe (Suchfeld existiert nur einmal); bei 1 Zeile
   bleiben Suchfeld + Suchen, Kopfleiste und Schnellzugriffe verschwinden */
.start-tile-always { display: flex; }
@container tile (max-height: 149px) {
    .start-tile-always .start-tile-head, .start-tile-always .start-suche-more { display: none !important; }
    .start-tile-always .start-tile-body { padding: .5rem 1rem; justify-content: center; }
}

/* Auftragszeit-Banner: so breit wie die belegten Raster-Spalten (--used-cols
   aus index.php), schliesst rechts mit den Kacheln ab; im Fliesslayout
   (Tablet/Handy) volle Breite */
@media (min-width: 992px) {
    .start-banner { width: calc((100% - 8rem) / 9 * var(--used-cols, 9) + (var(--used-cols, 9) - 1) * 1rem); }
}

/* Kompakte Kennzahlen in EINER Zeile (Urlaub: Zahl + Text, Button rechts) -
   fuer Kacheln, deren Hauptinhalt die Liste ist */
.start-tile-body-top { justify-content: flex-start; }
.start-kpi-row { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem 1.1rem; }
.start-kpi-inline { display: inline-flex; align-items: baseline; gap: .35rem; text-decoration: none; color: inherit; white-space: nowrap; }
.start-kpi-inline b { font-size: 1.5rem; font-weight: 700; line-height: 1; }
.start-kpi-inline span { color: #6c757d; font-size: .85rem; }
.start-kpi-inline.admin-marked { padding: .15rem .5rem; }
.start-kpi-inline:hover span { color: var(--bs-primary, #0d6efd); }

/* ---- Container-Queries: Inhalt folgt der Kachelgroesse ---- */
@container tile (min-height: 150px) {
    .start-tile-compact { display: none; }
    .start-tile-full { display: flex; }
    /* Kacheln ohne Partial (Lager/Archiv/Kasse): Icon gross ueber dem Namen */
    .start-tile-solo .start-tile-compact { display: flex; flex-direction: column; gap: .6rem; font-size: 1.1rem; padding: 1rem .5rem; text-align: center; }
    .start-tile-solo .start-tile-compact > .bi:first-child { font-size: 3.4rem; }
}
@container tile (min-height: 270px) {
    .start-list { display: block; }
    .start-tile-body { justify-content: flex-start; }
}
@container tile (min-width: 560px) {
    /* Jede Zeile ist ein eigenes Grid: Namensspalte fest (nicht fr), sonst
       verschiebt die unterschiedlich breite Datumsspalte die Spalten je Zeile */
    .start-row:has(.start-row-x) { grid-template-columns: 42% auto minmax(0, 1fr); }
    .start-row-x { display: block; }
}
@container tile (max-width: 400px) {
    .start-tile-actions { margin-left: 0; width: 100%; flex-direction: row; flex-wrap: wrap; }
    .start-tile-actions > * { flex: 1 1 auto; }
    .start-kpi-num { font-size: 2rem; }
}
@container tile (max-width: 300px) {
    .start-tile-head { padding-left: .75rem; gap: .4rem; }
    .start-tile-open { font-size: 0; padding: .2rem .35rem; gap: 0; }
    .start-tile-open .bi { font-size: .9rem; }
    .start-stempel-type { display: none; }
    .start-tile-compact-stempel .start-tile-label { display: none; }
}
@container tile (max-width: 260px) {
    .start-tile-compact { flex-direction: column; gap: .15rem; padding: .35rem .6rem; font-size: .9rem; text-align: center; }
    .start-tile-compact > .bi:first-child { font-size: 1.7rem; }
    .start-tile-compact .badge { font-size: .68rem; }
}

/* Sehr schmale Kachel (1 Spalte): keine Aktionsknoepfe, kleinere Kennzahlen,
   engere Abstaende - nur das Wichtigste passt */
@container tile (max-width: 200px) {
    .start-tile-actions { display: none !important; }
    .start-kpi-num { font-size: 1.6rem; }
    .start-kpi .text-muted { font-size: .8rem; white-space: normal; line-height: 1.15; }
    .start-tile-body { padding: .5rem .75rem .75rem; }
    .start-tile-body > .d-flex.gap-4 { gap: .5rem .9rem !important; }
}

/* Knopf-Reihe unter den Kennzahlen (Anlege-Knoepfe der Auftrags-/Beleg-
   Kacheln, Suche: Schnellzugriffe). Die M-Hoehe laesst genau EINE Zeile zu
   (Umbruch wuerde abgeschnitten), darum werden die Knoepfe erst dann zu
   Icon-Knoepfen (title = Tooltip), wenn die Beschriftungen wirklich nicht
   mehr in die Zeile passen - Icon-only ist Notloesung, nicht Regelfall
   (User-Vorgabe 2026-09-04). Schwelle nach Knopfzahl: start-actions-3
   (drei kurze Anlege-Knoepfe, ~385px) / start-actions-2 (~280px); Reihen
   ohne Zaehl-Klasse (Suche) wie bisher 480px. Ein Zusatz-Knopf mit
   start-actions-opt (Auftrag: "Meine Aufträge", auch ueber die Liste
   erreichbar) faellt VOR den Beschriftungen weg. Sehr schmal ganz weg.
   Schwellen in em (Basis 16px: 30em=480px, 27.5em=440px, 25em=400px,
   18.125em=290px, 12.5em=200px): em in @container bezieht sich auf die
   Schrift der Kachel, damit wachsen die Schwellen mit der Einstellung
   "Schrift gross" (body 1.25rem) mit - bei festen px brachen die breiteren
   Knoepfe in eine zweite Zeile um, die die Kachelhoehe abschneidet. */
@container tile (max-width: 30em) {
    .start-tile-actions-row:not(.start-actions-2):not(.start-actions-3) .btn { font-size: 0; padding: .4rem .55rem; }
    .start-tile-actions-row:not(.start-actions-2):not(.start-actions-3) .btn .bi { font-size: 1rem; margin: 0 !important; }
}
@container tile (max-width: 27.5em) {
    .start-tile-actions-row .start-actions-opt { display: none !important; }
}
@container tile (max-width: 25em) {
    .start-actions-3 .btn { font-size: 0; padding: .4rem .55rem; }
    .start-actions-3 .btn .bi { font-size: 1rem; margin: 0 !important; }
}
@container tile (max-width: 18.125em) {
    .start-actions-2 .btn { font-size: 0; padding: .4rem .55rem; }
    .start-actions-2 .btn .bi { font-size: 1rem; margin: 0 !important; }
}
@container tile (max-width: 12.5em) {
    .start-tile-actions-row { display: none !important; }
}

/* Kennzahlen-Zeile (Urlaub): der kleine Icon-Button bleibt auch schmal in
   der Zeile - keine eigene Zeile, die der Liste den Platz nimmt */
@container tile (max-width: 400px) {
    .start-kpi-row .start-tile-actions { margin-left: auto; width: auto; flex-direction: row; }
}

/* ---- Handy (< 576px): eine Spalte, Hoehe nach Inhalt ---- */
@media (max-width: 575.98px) {
    .start-grid { grid-template-columns: minmax(0, 1fr); grid-auto-rows: auto; }
    .start-tile { grid-column: span 1; grid-row: span 1; container-type: inline-size; min-height: 88px; }
    .start-tile-resize { display: none !important; }
    /* Keine feste Hoehe -> Hoehen-Queries greifen nicht: Stufe nach der
       GESPEICHERTEN Zeilenzahl (data-h), sonst faellt alles auf kompakt zurueck */
    .start-tile:not([data-h="1"]) .start-tile-compact { display: none; }
    .start-tile:not([data-h="1"]) .start-tile-full { display: flex; }
    .start-tile[data-h="1"] .start-tile-always .start-tile-head, .start-tile[data-h="1"] .start-tile-always .start-suche-more { display: none !important; }
    /* Kacheln ohne Partial (Lager/Archiv/Kasse): am Handy IMMER Icon gross
       ueber dem Namen - unabhaengig von der Desktop-Hoehe, sonst sind sie
       kleiner als die Modul-Kacheln mit Handy-Block (User-Meldung 2026-09-04) */
    .start-tile.start-tile-solo .start-tile-compact { display: flex; flex-direction: column; gap: .6rem; font-size: 1.1rem; padding: 1rem .5rem; }
    .start-tile.start-tile-solo .start-tile-compact > .bi:first-child { font-size: 3.4rem; }
    .start-tile.start-tile-solo .start-tile-compact .start-tile-label { line-height: 1.5; }   /* = Handy-Block, gleiche Kachelhoehe */
    .start-tile[data-h="3"] .start-list, .start-tile[data-h="4"] .start-list,
    .start-tile[data-h="5"] .start-list, .start-tile[data-h="6"] .start-list { display: block; max-height: 240px; }
}
/* Handy-Block (start-tile-mobile): Icon gross ueber dem Namen, ganze Kachel Link */
.start-tile-link {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .6rem;
    padding: 1rem .5rem;
    text-align: center;
    text-decoration: none;
    color: inherit;
    font-weight: 600;
    font-size: 1.1rem;
}
.start-tile-link i { font-size: 3.4rem; color: var(--bs-primary, #0d6efd); line-height: 1; }
.start-tile-link:hover { color: var(--bs-primary, #0d6efd); }

/* ---- Bearbeiten-Modus: Verschieben-Griff + Resize-Ecke ---- */
.start-tile-tools {
    display: none;
    position: absolute;
    top: .4rem;
    right: .4rem;
    gap: .25rem;
    z-index: 4;
}
.start-tile-tools .btn { background: #fff; }
.start-tile-hide { line-height: 1; }
.start-tile-handle { cursor: grab; touch-action: none; }   /* sonst scrollt das Tablet statt zu ziehen */
.start-tile-resize {
    display: none;
    position: absolute;
    right: 0;
    bottom: 0;
    width: 28px;
    height: 28px;
    z-index: 4;
    cursor: nwse-resize;
    color: var(--bs-primary, #0d6efd);
    touch-action: none;
}
.start-tile-resize::before {
    content: "";
    position: absolute;
    right: 5px;
    bottom: 5px;
    width: 14px;
    height: 14px;
    background: linear-gradient(135deg, transparent 0 50%, currentColor 50% 60%, transparent 60% 70%, currentColor 70% 80%, transparent 80% 90%, currentColor 90%);
}
.start-tile-size-badge {
    display: none;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    z-index: 5;
    padding: .3rem .7rem;
    border-radius: .4rem;
    background: #212529;
    color: #fff;
    font-weight: 600;
    font-size: 1.05rem;
    pointer-events: none;
    font-variant-numeric: tabular-nums;
}
.start-tile.is-resizing { z-index: 6; transition: none; box-shadow: 0 .5rem 1.25rem rgba(0,0,0,.18) !important; }
.start-tile.is-resizing .start-tile-size-badge { display: block; }
.start-grid.is-editing .start-tile-tools { display: flex; }
.start-grid.is-editing .start-tile-resize { display: block; }
.start-grid.is-editing .start-tile-content { pointer-events: none; opacity: .75; }
.start-grid.is-editing .start-tile {
    outline: 2px dashed rgba(13, 110, 253, .45);
    outline-offset: -2px;
}
.start-tile-ghost { opacity: .35; }

/* =====================================================================
   Statistik (/statistik): Chart-Container + klickbare KPI-Karten
   ===================================================================== */
.statistik-chart { position: relative; width: 100%; }
.statistik-kpi { transition: box-shadow .15s ease, transform .15s ease; }
.statistik-kpi:hover { box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .12) !important; transform: translateY(-1px); }
.statistik-filter .form-control,
.statistik-filter .form-select { min-width: 9rem; }
@media (max-width: 575.98px) {
    .statistik-chart { height: 200px !important; }
}

/* ---------- Datenimport: PDF-Erkennung (assets/js/import-pdf.js) ---------- */
.pdf-recognize-stage { overflow: auto; max-height: 70vh; }
.pdf-ruler {
    height: 18px; background: #e9ecef; border-bottom: 1px solid #ced4da;
    cursor: crosshair; position: sticky; top: 0; z-index: 3;
}
.pdf-canvas-wrap { position: relative; }
.pdf-canvas-wrap canvas { display: block; max-width: 100%; }
.pdf-overlay { position: absolute; inset: 0; touch-action: none; }
.pdf-bound {
    position: absolute; top: 0; bottom: 0; width: 9px; margin-left: -4px;
    cursor: col-resize; z-index: 2;
}
.pdf-bound::before {
    content: ""; position: absolute; top: 0; bottom: 0; left: 4px;
    border-left: 2px dashed #dc3545;
}
.pdf-bound.dragging::before { border-left-style: solid; }
.pdf-bound-handle {
    position: absolute; top: 2px; left: -4px; min-width: 17px; padding: 0 3px;
    font-size: 10px; line-height: 15px; text-align: center; border-radius: 3px;
    background: #dc3545; color: #fff; user-select: none;
}
